aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c_headers/stdarg.h4
-rw-r--r--src-self-hosted/main.zig1
-rw-r--r--src/all_types.hpp8
-rw-r--r--src/analyze.cpp50
-rw-r--r--src/codegen.cpp107
-rw-r--r--src/codegen.hpp1
-rw-r--r--src/config.h.in1
-rw-r--r--src/errmsg.cpp1
-rw-r--r--src/ir.cpp11
-rw-r--r--src/link.cpp22
-rw-r--r--src/main.cpp142
-rw-r--r--src/parsec.cpp2
-rw-r--r--src/tokenizer.cpp56
-rw-r--r--src/zig_llvm.cpp11
-rw-r--r--std/build.zig39
-rw-r--r--std/fmt/errol/index.zig22
-rw-r--r--std/fmt/index.zig71
-rw-r--r--std/special/build_runner.zig39
-rw-r--r--std/special/compiler_rt/comparetf2.zig2
-rw-r--r--std/special/compiler_rt/fixunsdfdi.zig2
-rw-r--r--std/special/compiler_rt/fixunsdfsi.zig2
-rw-r--r--std/special/compiler_rt/fixunsdfti.zig2
-rw-r--r--std/special/compiler_rt/fixunssfdi.zig2
-rw-r--r--std/special/compiler_rt/fixunssfsi.zig2
-rw-r--r--std/special/compiler_rt/fixunssfti.zig2
-rw-r--r--std/special/compiler_rt/fixunstfdi.zig2
-rw-r--r--std/special/compiler_rt/fixunstfsi.zig2
-rw-r--r--std/special/compiler_rt/fixunstfti.zig2
-rw-r--r--std/special/compiler_rt/index.zig6
-rw-r--r--std/special/compiler_rt/udivmoddi4.zig2
-rw-r--r--std/special/compiler_rt/udivmodti4.zig2
-rw-r--r--std/special/compiler_rt/udivti3.zig2
-rw-r--r--std/special/compiler_rt/umodti3.zig2
-rw-r--r--test/behavior.zig1
-rw-r--r--test/cases/align.zig2
-rw-r--r--test/cases/union.zig33
-rw-r--r--test/compile_errors.zig44
37 files changed, 498 insertions, 204 deletions
diff --git a/c_headers/stdarg.h b/c_headers/stdarg.h
index f6635105e0..d603d353f5 100644
--- a/c_headers/stdarg.h
+++ b/c_headers/stdarg.h
@@ -26,10 +26,14 @@
#ifndef __STDARG_H
#define __STDARG_H
+/* zig: added because macos _va_list.h was duplicately defining va_list
+ */
#ifndef _VA_LIST
+#ifndef _VA_LIST_T
typedef __builtin_va_list va_list;
#define _VA_LIST
#endif
+#endif
#define va_start(ap, param) __builtin_va_start(ap, param)
#define va_end(ap) __builtin_va_end(ap)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig
index af3c785c21..a4337faef3 100644
--- a/src-self-hosted/main.zig
+++ b/src-self-hosted/main.zig
@@ -5,6 +5,7 @@ const heap = @import("std").mem;
// TODO: OutSteam and InStream interface
// TODO: move allocator to heap namespace
+// TODO: sync up CLI with c++ code
error InvalidArgument;
error MissingArg0;
diff --git a/src/all_types.hpp b/src/all_types.hpp
index e4d174c414..318e6b2c11 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1008,6 +1008,9 @@ struct TypeTableEntryEnum {
size_t gen_union_index;
size_t gen_tag_index;
+
+ uint32_t union_size_bytes;
+ TypeTableEntry *most_aligned_union_member;
};
struct TypeTableEntryEnumTag {
@@ -1514,9 +1517,12 @@ struct CodeGen {
size_t version_major;
size_t version_minor;
size_t version_patch;
- bool verbose;
+ bool verbose_tokenize;
+ bool verbose_ast;
bool verbose_link;
bool verbose_ir;
+ bool verbose_llvm_ir;
+ bool verbose_cimport;
ErrColor err_color;
ImportTableEntry *root_import;
ImportTableEntry *bootstrap_import;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 292943a6e6..89ce5df6b4 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -27,9 +27,17 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type);
static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type);
ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
- // if this assert fails, then parsec generated code that
- // failed semantic analysis, which isn't supposed to happen
- assert(!node->owner->c_import_node);
+ if (node->owner->c_import_node != nullptr) {
+ // if this happens, then parsec generated code that
+ // failed semantic analysis, which isn't supposed to happen
+ ErrorMsg *err = add_node_error(g, node->owner->c_import_node,
+ buf_sprintf("compiler bug: @cImport generated invalid zig code"));
+
+ add_error_note(g, err, node, msg);
+
+ g->errors.append(err);
+ return err;
+ }
ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,
node->owner->source_code, node->owner->line_offsets, msg);
@@ -39,9 +47,20 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
}
ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg) {
- // if this assert fails, then parsec generated code that
- // failed semantic analysis, which isn't supposed to happen
- assert(!node->owner->c_import_node);
+ if (node->owner->c_import_node != nullptr) {
+ // if this happens, then parsec generated code that
+ // failed semantic analysis, which isn't supposed to happen
+
+ Buf *note_path = buf_create_from_str("?.c");
+ Buf *note_source = buf_create_from_str("TODO: remember C source location to display here ");
+ ZigList<size_t> note_line_offsets = {0};
+ note_line_offsets.append(0);
+ ErrorMsg *note = err_msg_create_with_line(note_path, 0, 0,
+ note_source, &note_line_offsets, msg);
+
+ err_msg_add_note(parent_msg, note);
+ return note;
+ }
ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,
node->owner->source_code, node->owner->line_offsets, msg);
@@ -1344,6 +1363,8 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
// unset temporary flag
enum_type->data.enumeration.embedded_in_current = false;
enum_type->data.enumeration.complete = true;
+ enum_type->data.enumeration.union_size_bytes = biggest_size_in_bits / 8;
+ enum_type->data.enumeration.most_aligned_union_member = most_aligned_union_member;
if (!enum_type->data.enumeration.is_invalid) {
TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count);
@@ -1365,10 +1386,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
};
union_type_ref = LLVMStructType(union_element_types, 2, false);
} else {
- LLVMTypeRef union_element_types[] = {
- most_aligned_union_member->type_ref,
- };
- union_type_ref = LLVMStructType(union_element_types, 1, false);
+ union_type_ref = most_aligned_union_member->type_ref;
}
enum_type->data.enumeration.union_type_ref = union_type_ref;
@@ -2804,7 +2822,6 @@ static bool is_container(TypeTableEntry *type_entry) {
switch (type_entry->id) {
case TypeTableEntryIdInvalid:
case TypeTableEntryIdVar:
- case TypeTableEntryIdOpaque:
zig_unreachable();
case TypeTableEntryIdStruct:
case TypeTableEntryIdEnum:
@@ -2831,6 +2848,7 @@ static bool is_container(TypeTableEntry *type_entry) {
case TypeTableEntryIdBoundFn:
case TypeTableEntryIdEnumTag:
case TypeTableEntryIdArgTuple:
+ case TypeTableEntryIdOpaque:
return false;
}
zig_unreachable();
@@ -2982,7 +3000,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ
return;
}
- if (g->verbose) {
+ if (g->verbose_ir) {
fprintf(stderr, "{ // (analyzed)\n");
ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);
fprintf(stderr, "}\n");
@@ -3015,7 +3033,7 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
fn_table_entry->anal_state = FnAnalStateInvalid;
return;
}
- if (g->verbose) {
+ if (g->verbose_ir) {
fprintf(stderr, "\n");
ast_render(g, stderr, fn_table_entry->body_node, 4);
fprintf(stderr, "\n{ // (IR)\n");
@@ -3115,7 +3133,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) {
}
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code) {
- if (g->verbose) {
+ if (g->verbose_tokenize) {
fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(abs_full_path));
fprintf(stderr, "----------------\n");
fprintf(stderr, "%s\n", buf_ptr(source_code));
@@ -3135,7 +3153,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
exit(1);
}
- if (g->verbose) {
+ if (g->verbose_tokenize) {
print_tokens(source_code, tokenization.tokens);
fprintf(stderr, "\nAST:\n");
@@ -3150,7 +3168,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color);
assert(import_entry->root);
- if (g->verbose) {
+ if (g->verbose_ast) {
ast_print(stderr, import_entry->root, 0);
}
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 61640b062b..1dc8205c8e 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -196,10 +196,6 @@ void codegen_set_is_static(CodeGen *g, bool is_static) {
g->is_static = is_static;
}
-void codegen_set_verbose(CodeGen *g, bool verbose) {
- g->verbose = verbose;
-}
-
void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {
g->each_lib_rpath = each_lib_rpath;
}
@@ -452,10 +448,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
LLVMSetLinkage(fn_table_entry->llvm_value, LLVMExternalLinkage);
break;
case GlobalLinkageIdWeak:
- LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakAnyLinkage);
+ LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakODRLinkage);
break;
case GlobalLinkageIdLinkOnce:
- LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceAnyLinkage);
+ LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceODRLinkage);
break;
}
@@ -3665,6 +3661,12 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
zig_unreachable();
}
+// We have this because union constants can't be represented by the official union type,
+// and this property bubbles up in whatever aggregate type contains a union constant
+static bool is_llvm_value_unnamed_type(TypeTableEntry *type_entry, LLVMValueRef val) {
+ return LLVMTypeOf(val) != type_entry->type_ref;
+}
+
static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
TypeTableEntry *type_entry = const_val->type;
assert(!type_entry->zero_bits);
@@ -3726,24 +3728,34 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
} else {
LLVMValueRef child_val;
LLVMValueRef maybe_val;
+ bool make_unnamed_struct;
if (const_val->data.x_maybe) {
child_val = gen_const_val(g, const_val->data.x_maybe);
maybe_val = LLVMConstAllOnes(LLVMInt1Type());
+
+ make_unnamed_struct = is_llvm_value_unnamed_type(const_val->type, child_val);
} else {
- child_val = LLVMConstNull(child_type->type_ref);
+ child_val = LLVMGetUndef(child_type->type_ref);
maybe_val = LLVMConstNull(LLVMInt1Type());
+
+ make_unnamed_struct = false;
}
LLVMValueRef fields[] = {
child_val,
maybe_val,
};
- return LLVMConstStruct(fields, 2, false);
+ if (make_unnamed_struct) {
+ return LLVMConstStruct(fields, 2, false);
+ } else {
+ return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
+ }
}
}
case TypeTableEntryIdStruct:
{
LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count);
size_t src_field_count = type_entry->data.structure.src_field_count;
+ bool make_unnamed_struct = false;
if (type_entry->data.structure.layout == ContainerLayoutPacked) {
size_t src_field_index = 0;
while (src_field_index < src_field_count) {
@@ -3761,8 +3773,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
}
if (src_field_index + 1 == src_field_index_end) {
- fields[type_struct_field->gen_index] =
- gen_const_val(g, &const_val->data.x_struct.fields[src_field_index]);
+ ConstExprValue *field_val = &const_val->data.x_struct.fields[src_field_index];
+ LLVMValueRef val = gen_const_val(g, field_val);
+ fields[type_struct_field->gen_index] = val;
+ make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(field_val->type, val);
} else {
LLVMTypeRef big_int_type_ref = LLVMStructGetTypeAtIndex(type_entry->type_ref,
(unsigned)type_struct_field->gen_index);
@@ -3790,11 +3804,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
if (type_struct_field->gen_index == SIZE_MAX) {
continue;
}
- fields[type_struct_field->gen_index] = gen_const_val(g, &const_val->data.x_struct.fields[i]);
+ ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
+ LLVMValueRef val = gen_const_val(g, field_val);
+ fields[type_struct_field->gen_index] = val;
+ make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(field_val->type, val);
}
}
- return LLVMConstStruct(fields, type_entry->data.structure.gen_field_count,
- type_entry->data.structure.layout == ContainerLayoutPacked);
+ if (make_unnamed_struct) {
+ return LLVMConstStruct(fields, type_entry->data.structure.gen_field_count,
+ type_entry->data.structure.layout == ContainerLayoutPacked);
+ } else {
+ return LLVMConstNamedStruct(type_entry->type_ref, fields, type_entry->data.structure.gen_field_count);
+ }
}
case TypeTableEntryIdUnion:
{
@@ -3808,11 +3829,19 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
}
LLVMValueRef *values = allocate<LLVMValueRef>(len);
+ LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref;
+ bool make_unnamed_struct = false;
for (uint64_t i = 0; i < len; i += 1) {
ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i];
- values[i] = gen_const_val(g, elem_value);
+ LLVMValueRef val = gen_const_val(g, elem_value);
+ values[i] = val;
+ make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val);
+ }
+ if (make_unnamed_struct) {
+ return LLVMConstStruct(values, len, true);
+ } else {
+ return LLVMConstArray(element_type_ref, values, (unsigned)len);
}
- return LLVMConstArray(LLVMTypeOf(values[0]), values, (unsigned)len);
}
case TypeTableEntryIdEnum:
{
@@ -3825,14 +3854,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag];
assert(enum_field->value == const_val->data.x_enum.tag);
LLVMValueRef union_value;
+
+ bool make_unnamed_struct;
+
if (type_has_bits(enum_field->type_entry)) {
- uint64_t union_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,
- union_type_ref);
uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,
enum_field->type_entry->type_ref);
- uint64_t pad_bytes = union_type_bytes - field_type_bytes;
+ uint64_t pad_bytes = type_entry->data.enumeration.union_size_bytes - field_type_bytes;
+
+ ConstExprValue *payload_value = const_val->data.x_enum.payload;
+ LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value);
+
+ make_unnamed_struct = is_llvm_value_unnamed_type(payload_value->type, correctly_typed_value) ||
+ payload_value->type != type_entry->data.enumeration.most_aligned_union_member;
- LLVMValueRef correctly_typed_value = gen_const_val(g, const_val->data.x_enum.payload);
if (pad_bytes == 0) {
union_value = correctly_typed_value;
} else {
@@ -3843,12 +3878,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
union_value = LLVMConstStruct(fields, 2, false);
}
} else {
+ make_unnamed_struct = false;
union_value = LLVMGetUndef(union_type_ref);
}
LLVMValueRef fields[2];
fields[type_entry->data.enumeration.gen_tag_index] = tag_value;
fields[type_entry->data.enumeration.gen_union_index] = union_value;
- return LLVMConstStruct(fields, 2, false);
+
+ if (make_unnamed_struct) {
+ return LLVMConstStruct(fields, 2, false);
+ } else {
+ return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
+ }
}
}
case TypeTableEntryIdFn:
@@ -3932,18 +3973,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
} else {
LLVMValueRef err_tag_value;
LLVMValueRef err_payload_value;
+ bool make_unnamed_struct;
if (const_val->data.x_err_union.err) {
err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err_union.err->value, false);
err_payload_value = LLVMConstNull(child_type->type_ref);
+ make_unnamed_struct = false;
} else {
err_tag_value = LLVMConstNull(g->err_tag_type->type_ref);
- err_payload_value = gen_const_val(g, const_val->data.x_err_union.payload);
+ ConstExprValue *payload_val = const_val->data.x_err_union.payload;
+ err_payload_value = gen_const_val(g, payload_val);
+ make_unnamed_struct = is_llvm_value_unnamed_type(payload_val->type, err_payload_value);
}
LLVMValueRef fields[] = {
err_tag_value,
err_payload_value,
};
- return LLVMConstStruct(fields, 2, false);
+ if (make_unnamed_struct) {
+ return LLVMConstStruct(fields, 2, false);
+ } else {
+ return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
+ }
}
}
case TypeTableEntryIdVoid:
@@ -4159,10 +4208,6 @@ static void validate_inline_fns(CodeGen *g) {
}
static void do_code_gen(CodeGen *g) {
- if (g->verbose) {
- fprintf(stderr, "\nCode Generation:\n");
- fprintf(stderr, "------------------\n");
- }
assert(!g->errors.length);
codegen_add_time_event(g, "Code Generation");
@@ -4439,7 +4484,8 @@ static void do_code_gen(CodeGen *g) {
ZigLLVMDIBuilderFinalize(g->dbuilder);
- if (g->verbose || g->verbose_ir) {
+ if (g->verbose_llvm_ir) {
+ fflush(stderr);
LLVMDumpModule(g->module);
}
@@ -5269,10 +5315,6 @@ static void gen_root_source(CodeGen *g) {
resolve_top_level_decl(g, panic_tld, false, nullptr);
}
- if (g->verbose) {
- fprintf(stderr, "\nIR Generation and Semantic Analysis:\n");
- fprintf(stderr, "--------------------------------------\n");
- }
if (!g->error_during_imports) {
semantic_analyze(g);
}
@@ -5286,9 +5328,6 @@ static void gen_root_source(CodeGen *g) {
}
report_errors_and_maybe_exit(g);
- if (g->verbose) {
- fprintf(stderr, "OK\n");
- }
}
diff --git a/src/codegen.hpp b/src/codegen.hpp
index 35ae31d8b9..5c54e9bce8 100644
--- a/src/codegen.hpp
+++ b/src/codegen.hpp
@@ -25,7 +25,6 @@ void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);
void codegen_set_is_static(CodeGen *codegen, bool is_static);
void codegen_set_strip(CodeGen *codegen, bool strip);
-void codegen_set_verbose(CodeGen *codegen, bool verbose);
void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir);
diff --git a/src/config.h.in b/src/config.h.in
index 36bd66098b..a596213a3d 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -20,7 +20,6 @@
#define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@"
#cmakedefine ZIG_EACH_LIB_RPATH
-#cmakedefine ZIG_LLVM_OLD_CXX_ABI
// Only used for running tests before installing.
#define ZIG_TEST_DIR "@CMAKE_SOURCE_DIR@/test"
diff --git a/src/errmsg.cpp b/src/errmsg.cpp
index bef4d7548d..01c3ee8429 100644
--- a/src/errmsg.cpp
+++ b/src/errmsg.cpp
@@ -123,6 +123,7 @@ ErrorMsg *err_msg_create_with_line(Buf *path, size_t line, size_t column,
size_t end_line = line + 1;
size_t line_end_offset = (end_line >= line_offsets->length) ? buf_len(source) : line_offsets->at(line + 1);
size_t len = (line_end_offset + 1 > line_start_offset) ? (line_end_offset - line_start_offset - 1) : 0;
+ if (len == SIZE_MAX) len = 0;
buf_init_from_mem(&err_msg->line_buf, buf_ptr(source) + line_start_offset, len);
diff --git a/src/ir.cpp b/src/ir.cpp
index 0879942b3e..6c6ce676f6 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -7849,7 +7849,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
if (ir_executable.invalid)
return codegen->invalid_instruction;
- if (codegen->verbose) {
+ if (codegen->verbose_ir) {
fprintf(stderr, "\nSource: ");
ast_render(codegen, stderr, node, 4);
fprintf(stderr, "\n{ // (IR)\n");
@@ -7870,7 +7870,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
if (type_is_invalid(result_type))
return codegen->invalid_instruction;
- if (codegen->verbose) {
+ if (codegen->verbose_ir) {
fprintf(stderr, "{ // (analyzed)\n");
ir_print(codegen, stderr, &analyzed_executable, 4);
fprintf(stderr, "}\n");
@@ -13514,7 +13514,7 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc
return ira->codegen->builtin_types.entry_invalid;
}
- if (ira->codegen->verbose) {
+ if (ira->codegen->verbose_cimport) {
fprintf(stderr, "\nC imports:\n");
fprintf(stderr, "-----------\n");
ast_render(ira->codegen, stderr, child_import->root, 4);
@@ -15312,6 +15312,11 @@ static TypeTableEntry *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, Ir
if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes))
return ira->codegen->builtin_types.entry_invalid;
+ if (align_bytes > 256) {
+ ir_add_error(ira, &instruction->base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes));
+ return ira->codegen->builtin_types.entry_invalid;
+ }
+
FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
if (fn_entry == nullptr) {
ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack outside function"));
diff --git a/src/link.cpp b/src/link.cpp
index f2f21fd746..a4e5b2dd25 100644
--- a/src/link.cpp
+++ b/src/link.cpp
@@ -37,7 +37,12 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path)
parent_gen->zig_lib_dir);
child_gen->want_h_file = false;
+ child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
+ child_gen->verbose_ast = parent_gen->verbose_ast;
child_gen->verbose_link = parent_gen->verbose_link;
+ child_gen->verbose_ir = parent_gen->verbose_ir;
+ child_gen->verbose_llvm_ir = parent_gen->verbose_llvm_ir;
+ child_gen->verbose_cimport = parent_gen->verbose_cimport;
codegen_set_cache_dir(child_gen, parent_gen->cache_dir);
@@ -46,7 +51,6 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path)
codegen_set_out_name(child_gen, buf_create_from_str(oname));
- codegen_set_verbose(child_gen, parent_gen->verbose);
codegen_set_errmsg_color(child_gen, parent_gen->err_color);
codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min);
@@ -858,15 +862,12 @@ void codegen_link(CodeGen *g, const char *out_file) {
buf_resize(&lj.out_file, 0);
}
- if (g->verbose || g->verbose_ir) {
+ if (g->verbose_llvm_ir) {
fprintf(stderr, "\nOptimization:\n");
fprintf(stderr, "---------------\n");
+ fflush(stderr);
LLVMDumpModule(g->module);
}
- if (g->verbose || g->verbose_link) {
- fprintf(stderr, "\nLink:\n");
- fprintf(stderr, "-------\n");
- }
bool override_out_file = (buf_len(&lj.out_file) != 0);
if (!override_out_file) {
@@ -887,9 +888,6 @@ void codegen_link(CodeGen *g, const char *out_file) {
zig_panic("unable to rename object file into final output: %s", err_str(err));
}
}
- if (g->verbose || g->verbose_link) {
- fprintf(stderr, "OK\n");
- }
return;
}
@@ -907,7 +905,7 @@ void codegen_link(CodeGen *g, const char *out_file) {
construct_linker_job(&lj);
- if (g->verbose || g->verbose_link) {
+ if (g->verbose_link) {
for (size_t i = 0; i < lj.args.length; i += 1) {
const char *space = (i != 0) ? " " : "";
fprintf(stderr, "%s%s", space, lj.args.at(i));
@@ -924,8 +922,4 @@ void codegen_link(CodeGen *g, const char *out_file) {
}
codegen_add_time_event(g, "Done");
-
- if (g->verbose || g->verbose_link) {
- fprintf(stderr, "OK\n");
- }
}
diff --git a/src/main.cpp b/src/main.cpp
index a4aa00aeca..358f1cf255 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -20,66 +20,69 @@ static int usage(const char *arg0) {
fprintf(stderr, "Usage: %s [command] [options]\n"
"Commands:\n"
" build build project from build.zig\n"
- " build-exe [source] create executable from source or object files\n"
- " build-lib [source] create library from source or object files\n"
- " build-obj [source] create object from source or assembly\n"
- " parsec [source] convert c code to zig code\n"
+ " build-exe $source create executable from source or object files\n"
+ " build-lib $source create library from source or object files\n"
+ " build-obj $source create object from source or assembly\n"
+ " parsec $source convert c code to zig code\n"
" targets list available compilation targets\n"
- " test [source] create and run a test build\n"
+ " test $source create and run a test build\n"
" version print version number and exit\n"
" zen print zen of zig and exit\n"
"Compile Options:\n"
- " --assembly [source] add assembly file to build\n"
- " --cache-dir [path] override the cache directory\n"
- " --color [auto|off|on] enable or disable colored error messages\n"
+ " --assembly $source add assembly file to build\n"
+ " --cache-dir $path override the cache directory\n"
+ " --color $auto|off|on enable or disable colored error messages\n"
" --enable-timing-info print timing diagnostics\n"
- " --libc-include-dir [path] directory where libc stdlib.h resides\n"
- " --name [name] override output name\n"
- " --output [file] override destination path\n"
- " --output-h [file] override generated header file path\n"
- " --pkg-begin [name] [path] make package available to import and push current pkg\n"
+ " --libc-include-dir $path directory where libc stdlib.h resides\n"
+ " --name $name override output name\n"
+ " --output $file override destination path\n"
+ " --output-h $file override generated header file path\n"
+ " --pkg-begin $name $path make package available to import and push current pkg\n"
" --pkg-end pop current pkg\n"
" --release-fast build with optimizations on and safety off\n"
" --release-safe build with optimizations on and safety on\n"
" --static output will be statically linked\n"
" --strip exclude debug symbols\n"
- " --target-arch [name] specify target architecture\n"
- " --target-environ [name] specify target environment\n"
- " --target-os [name] specify target operating system\n"
- " --verbose turn on compiler debug output\n"
- " --verbose-link turn on compiler debug output for linking only\n"
- " --verbose-ir turn on compiler debug output for IR only\n"
- " --zig-install-prefix [path] override directory where zig thinks it is installed\n"
- " -dirafter [dir] same as -isystem but do it last\n"
- " -isystem [dir] add additional search path for other .h files\n"
- " -mllvm [arg] additional arguments to forward to LLVM's option processing\n"
+ " --target-arch $name specify target architecture\n"
+ " --target-environ $name specify target environment\n"
+ " --target-os $name specify target operating system\n"
+ " --verbose-tokenize turn on compiler debug output for tokenization\n"
+ " --verbose-ast turn on compiler debug output for parsing into an AST\n"
+ " --verbose-link turn on compiler debug output for linking\n"
+ " --verbose-ir turn on compiler debug output for Zig IR\n"
+ " --verbose-llvm-ir turn on compiler debug output for LLVM IR\n"
+ " --verbose-cimport turn on compiler debug output for C imports\n"
+ " --zig-install-prefix $path override directory where zig thinks it is installed\n"
+ " -dirafter $dir same as -isystem but do it last\n"
+ " -isystem $dir add additional search path for other .h files\n"
+ " -mllvm $arg additional arguments to forward to LLVM's option processing\n"
"Link Options:\n"
- " --ar-path [path] set the path to ar\n"
- " --dynamic-linker [path] set the path to ld.so\n"
+ " --ar-path $path set the path to ar\n"
+ " --dynamic-linker $path set the path to ld.so\n"
" --each-lib-rpath add rpath for each used dynamic library\n"
- " --libc-lib-dir [path] directory where libc crt1.o resides\n"
- " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n"
- " --msvc-lib-dir [path] (windows) directory where vcruntime.lib resides\n"
- " --kernel32-lib-dir [path] (windows) directory where kernel32.lib resides\n"
- " --library [lib] link against lib\n"
- " --library-path [dir] add a directory to the library search path\n"
- " --linker-script [path] use a custom linker script\n"
- " --object [obj] add object file to build\n"
- " -L[dir] alias for --library-path\n"
+ " --libc-lib-dir $path directory where libc crt1.o resides\n"
+ " --libc-static-lib-dir $path directory where libc crtbegin.o resides\n"
+ " --msvc-lib-dir $path (windows) directory where vcruntime.lib resides\n"
+ " --kernel32-lib-dir $path (windows) directory where kernel32.lib resides\n"
+ " --library $lib link against lib\n"
+ " --library-path $dir add a directory to the library search path\n"
+ " --linker-script $path use a custom linker script\n"
+ " --object $obj add object file to build\n"
+ " -L$dir alias for --library-path\n"
" -rdynamic add all symbols to the dynamic symbol table\n"
- " -rpath [path] add directory to the runtime library search path\n"
+ " -rpath $path add directory to the runtime library search path\n"
" -mconsole (windows) --subsystem console to the linker\n"
" -mwindows (windows) --subsystem windows to the linker\n"
- " -framework [name] (darwin) link against framework\n"
- " -mios-version-min [ver] (darwin) set iOS deployment target\n"
- " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n"
- " --ver-major [ver] dynamic library semver major version\n"
- " --ver-minor [ver] dynamic library semver minor version\n"
- " --ver-patch [ver] dynamic library semver patch version\n"
+ " -framework $name (darwin) link against framework\n"
+ " -mios-version-min $ver (darwin) set iOS deployment target\n"
+ " -mmacosx-version-min $ver (darwin) set Mac OS X deployment target\n"
+ " --ver-major $ver dynamic library semver major version\n"
+ " --ver-minor $ver dynamic library semver minor version\n"
+ " --ver-patch $ver dynamic library semver patch version\n"
"Test Options:\n"
- " --test-filter [text] skip tests that do not match filter\n"
- " --test-name-prefix [text] add prefix to all tests\n"
- " --test-cmd [arg] specify test execution command one arg at a time\n"
+ " --test-filter $text skip tests that do not match filter\n"
+ " --test-name-prefix $text add prefix to all tests\n"
+ " --test-cmd $arg specify test execution command one arg at a time\n"
" --test-cmd-bin appends test binary path to test cmd args\n"
, arg0);
return EXIT_FAILURE;
@@ -273,9 +276,12 @@ int main(int argc, char **argv) {
bool is_static = false;
OutType out_type = OutTypeUnknown;
const char *out_name = nullptr;
- bool verbose = false;
+ bool verbose_tokenize = false;
+ bool verbose_ast = false;
bool verbose_link = false;
bool verbose_ir = false;
+ bool verbose_llvm_ir = false;
+ bool verbose_cimport = false;
ErrColor color = ErrColorAuto;
const char *libc_lib_dir = nullptr;
const char *libc_static_lib_dir = nullptr;
@@ -326,9 +332,7 @@ int main(int argc, char **argv) {
args.append(NULL); // placeholder
args.append(NULL); // placeholder
for (int i = 2; i < argc; i += 1) {
- if (strcmp(argv[i], "--debug-build-verbose") == 0) {
- verbose = true;
- } else if (strcmp(argv[i], "--help") == 0) {
+ if (strcmp(argv[i], "--help") == 0) {
asked_for_help = true;
args.append(argv[i]);
} else if (i + 1 < argc && strcmp(argv[i], "--build-file") == 0) {
@@ -361,7 +365,6 @@ int main(int argc, char **argv) {
CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, zig_lib_dir_buf);
codegen_set_out_name(g, buf_create_from_str("build"));
- codegen_set_verbose(g, verbose);
Buf build_file_abs = BUF_INIT;
os_path_resolve(buf_create_from_str("."), buf_create_from_str(build_file), &build_file_abs);
@@ -396,14 +399,30 @@ int main(int argc, char **argv) {
"\n"
"General Options:\n"
" --help Print this help and exit\n"
- " --build-file [file] Override path to build.zig\n"
- " --cache-dir [path] Override path to cache directory\n"
+ " --build-file $file Override path to build.zig\n"
+ " --cache-dir $path Override path to cache directory\n"
" --verbose Print commands before executing them\n"
- " --debug-build-verbose Print verbose debugging information for the build system itself\n"
- " --prefix [prefix] Override default install prefix\n"
+ " --verbose-tokenize Enable compiler debug output for tokenization\n"
+ " --verbose-ast Enable compiler debug output for parsing into an AST\n"
+ " --verbose-link Enable compiler debug output for linking\n"
+ " --verbose-ir Enable compiler debug output for Zig IR\n"
+ " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n"
+ " --verbose-cimport Enable compiler debug output for C imports\n"
+ " --prefix $path Override default install prefix\n"
"\n"
- "More options become available when the build file is found.\n"
+ "Project-specific options become available when the build file is found.\n"
"Run this command with no options to generate a build.zig template.\n"
+ "\n"
+ "Advanced Options:\n"
+ " --build-file $file Override path to build.zig\n"
+ " --cache-dir $path Override path to cache directory\n"
+ " --verbose-tokenize Enable compiler debug output for tokenization\n"
+ " --verbose-ast Enable compiler debug output for parsing into an AST\n"
+ " --verbose-link Enable compiler debug output for linking\n"
+ " --verbose-ir Enable compiler debug output for Zig IR\n"
+ " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n"
+ " --verbose-cimport Enable compiler debug output for C imports\n"
+ "\n"
, zig_exe_path);
return 0;
}
@@ -450,12 +469,18 @@ int main(int argc, char **argv) {
strip = true;
} else if (strcmp(arg, "--static") == 0) {
is_static = true;
- } else if (strcmp(arg, "--verbose") == 0) {
- verbose = true;
+ } else if (strcmp(arg, "--verbose-tokenize") == 0) {
+ verbose_tokenize = true;
+ } else if (strcmp(arg, "--verbose-ast") == 0) {
+ verbose_ast = true;
} else if (strcmp(arg, "--verbose-link") == 0) {
verbose_link = true;
} else if (strcmp(arg, "--verbose-ir") == 0) {
verbose_ir = true;
+ } else if (strcmp(arg, "--verbose-llvm-ir") == 0) {
+ verbose_llvm_ir = true;
+ } else if (strcmp(arg, "--verbose-cimport") == 0) {
+ verbose_cimport = true;
} else if (strcmp(arg, "-mwindows") == 0) {
mwindows = true;
} else if (strcmp(arg, "-mconsole") == 0) {
@@ -738,9 +763,12 @@ int main(int argc, char **argv) {
codegen_set_kernel32_lib_dir(g, buf_create_from_str(kernel32_lib_dir));
if (dynamic_linker)
codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));
- codegen_set_verbose(g, verbose);
+ g->verbose_tokenize = verbose_tokenize;
+ g->verbose_ast = verbose_ast;
g->verbose_link = verbose_link;
g->verbose_ir = verbose_ir;
+ g->verbose_llvm_ir = verbose_llvm_ir;
+ g->verbose_cimport = verbose_cimport;
codegen_set_errmsg_color(g, color);
for (size_t i = 0; i < lib_dirs.length; i += 1) {
diff --git a/src/parsec.cpp b/src/parsec.cpp
index d200c0531d..586e95bc75 100644
--- a/src/parsec.cpp
+++ b/src/parsec.cpp
@@ -3167,7 +3167,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
{
Context context = {0};
Context *c = &context;
- c->warnings_on = codegen->verbose;
+ c->warnings_on = codegen->verbose_cimport;
c->import = import;
c->errors = errors;
if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) {
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index d277fb2502..77d74c52ee 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -416,6 +416,44 @@ static void handle_string_escape(Tokenize *t, uint8_t c) {
}
}
+static const char* get_escape_shorthand(uint8_t c) {
+ switch (c) {
+ case '\0':
+ return "\\0";
+ case '\a':
+ return "\\a";
+ case '\b':
+ return "\\b";
+ case '\t':
+ return "\\t";
+ case '\n':
+ return "\\n";
+ case '\v':
+ return "\\v";
+ case '\f':
+ return "\\f";
+ case '\r':
+ return "\\r";
+ default:
+ return nullptr;
+ }
+}
+
+static void invalid_char_error(Tokenize *t, uint8_t c) {
+ if (c == '\r') {
+ tokenize_error(t, "invalid carriage return, only '\\n' line endings are supported");
+ } else if (isprint(c)) {
+ tokenize_error(t, "invalid character: '%c'", c);
+ } else {
+ const char *sh = get_escape_shorthand(c);
+ if (sh) {
+ tokenize_error(t, "invalid character: '%s'", sh);
+ } else {
+ tokenize_error(t, "invalid character: '\\x%x'", c);
+ }
+ }
+}
+
void tokenize(Buf *buf, Tokenization *out) {
Tokenize t = {0};
t.out = out;
@@ -580,7 +618,7 @@ void tokenize(Buf *buf, Tokenization *out) {
t.state = TokenizeStateSawQuestionMark;
break;
default:
- tokenize_error(&t, "invalid character: '%c'", c);
+ invalid_char_error(&t, c);
}
break;
case TokenizeStateSawQuestionMark:
@@ -890,7 +928,7 @@ void tokenize(Buf *buf, Tokenization *out) {
t.state = TokenizeStateLineString;
break;
default:
- tokenize_error(&t, "invalid character: '%c'", c);
+ invalid_char_error(&t, c);
break;
}
break;
@@ -919,7 +957,7 @@ void tokenize(Buf *buf, Tokenization *out) {
break;
case '\\':
if (t.cur_tok->data.str_lit.is_c_str) {
- tokenize_error(&t, "invalid character: '%c'", c);
+ invalid_char_error(&t, c);
}
t.state = TokenizeStateLineStringContinue;
break;
@@ -949,7 +987,7 @@ void tokenize(Buf *buf, Tokenization *out) {
buf_append_char(&t.cur_tok->data.str_lit.str, '\n');
break;
default:
- tokenize_error(&t, "invalid character: '%c'", c);
+ invalid_char_error(&t, c);
break;
}
break;
@@ -1073,7 +1111,7 @@ void tokenize(Buf *buf, Tokenization *out) {
handle_string_escape(&t, '\"');
break;
default:
- tokenize_error(&t, "invalid character: '%c'", c);
+ invalid_char_error(&t, c);
}
break;
case TokenizeStateCharCode:
@@ -1147,7 +1185,7 @@ void tokenize(Buf *buf, Tokenization *out) {
t.state = TokenizeStateStart;
break;
default:
- tokenize_error(&t, "invalid character: '%c'", c);
+ invalid_char_error(&t, c);
}
break;
case TokenizeStateZero:
@@ -1189,7 +1227,7 @@ void tokenize(Buf *buf, Tokenization *out) {
uint32_t digit_value = get_digit_value(c);
if (digit_value >= t.radix) {
if (is_symbol_char(c)) {
- tokenize_error(&t, "invalid character: '%c'", c);
+ invalid_char_error(&t, c);
}
// not my char
t.pos -= 1;
@@ -1233,7 +1271,7 @@ void tokenize(Buf *buf, Tokenization *out) {
uint32_t digit_value = get_digit_value(c);
if (digit_value >= t.radix) {
if (is_symbol_char(c)) {
- tokenize_error(&t, "invalid character: '%c'", c);
+ invalid_char_error(&t, c);
}
// not my char
t.pos -= 1;
@@ -1282,7 +1320,7 @@ void tokenize(Buf *buf, Tokenization *out) {
uint32_t digit_value = get_digit_value(c);
if (digit_value >= t.radix) {
if (is_symbol_char(c)) {
- tokenize_error(&t, "invalid character: '%c'", c);
+ invalid_char_error(&t, c);
}
// not my char
t.pos -= 1;
diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp
index f82b1d5423..0e1a067bc6 100644
--- a/src/zig_llvm.cpp
+++ b/src/zig_llvm.cpp
@@ -5,15 +5,6 @@
* See http://opensource.org/licenses/MIT
*/
-// This must go before all includes.
-#include "config.h"
-#if defined(ZIG_LLVM_OLD_CXX_ABI)
-#define _GLIBCXX_USE_CXX11_ABI 0
-#endif
-
-
-#include "zig_llvm.hpp"
-
/*
* The point of this file is to contain all the LLVM C++ API interaction so that:
@@ -22,6 +13,8 @@
* 3. Prevent C++ from infecting the rest of the project.
*/
+#include "zig_llvm.hpp"
+
#include <llvm/Analysis/TargetLibraryInfo.h>
#include <llvm/Analysis/TargetTransformInfo.h>
#include <llvm/IR/DIBuilder.h>
diff --git a/std/build.zig b/std/build.zig
index 84eba6d33b..7cf2ac5987 100644
--- a/std/build.zig
+++ b/std/build.zig
@@ -33,6 +33,12 @@ pub const Builder = struct {
available_options_map: AvailableOptionsMap,
available_options_list: ArrayList(AvailableOption),
verbose: bool,
+ verbose_tokenize: bool,
+ verbose_ast: bool,
+ verbose_link: bool,
+ verbose_ir: bool,
+ verbose_llvm_ir: bool,
+ verbose_cimport: bool,
invalid_user_input: bool,
zig_exe: []const u8,
default_step: &Step,
@@ -88,6 +94,12 @@ pub const Builder = struct {
.build_root = build_root,
.cache_root = %%os.path.relative(allocator, build_root, cache_root),
.verbose = false,
+ .verbose_tokenize = false,
+ .verbose_ast = false,
+ .verbose_link = false,
+ .verbose_ir = false,
+ .verbose_llvm_ir = false,
+ .verbose_cimport = false,
.invalid_user_input = false,
.allocator = allocator,
.lib_paths = ArrayList([]const u8).init(allocator),
@@ -536,15 +548,19 @@ pub const Builder = struct {
return self.spawnChildEnvMap(null, &self.env_map, argv);
}
+ fn printCmd(cwd: ?[]const u8, argv: []const []const u8) {
+ if (cwd) |yes_cwd| %%io.stderr.print("cd {} && ", yes_cwd);
+ for (argv) |arg| {
+ %%io.stderr.print("{} ", arg);
+ }
+ %%io.stderr.printf("\n");
+ }
+
fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
argv: []const []const u8) -> %void
{
if (self.verbose) {
- if (cwd) |yes_cwd| %%io.stderr.print("cd {}; ", yes_cwd);
- for (argv) |arg| {
- %%io.stderr.print("{} ", arg);
- }
- %%io.stderr.printf("\n");
+ printCmd(cwd, argv);
}
const child = %%os.ChildProcess.init(argv, self.allocator);
@@ -561,12 +577,15 @@ pub const Builder = struct {
switch (term) {
Term.Exited => |code| {
if (code != 0) {
- %%io.stderr.printf("Process {} exited with error code {}\n", argv[0], code);
+ %%io.stderr.printf("The following command exited with error code {}:\n", code);
+ printCmd(cwd, argv);
return error.UncleanExit;
}
},
else => {
- %%io.stderr.printf("Process {} terminated unexpectedly\n", argv[0]);
+ %%io.stderr.printf("The following command terminated unexpectedly:\n");
+ printCmd(cwd, argv);
+
return error.UncleanExit;
},
};
@@ -1117,6 +1136,12 @@ pub const LibExeObjStep = struct {
if (self.verbose) {
%%zig_args.append("--verbose");
}
+ if (builder.verbose_tokenize) %%zig_args.append("--verbose-tokenize");
+ if (builder.verbose_ast) %%zig_args.append("--verbose-ast");
+ if (builder.verbose_cimport) %%zig_args.append("--verbose-cimport");
+ if (builder.verbose_ir) %%zig_args.append("--verbose-ir");
+ if (builder.verbose_llvm_ir) %%zig_args.append("--verbose-llvm-ir");
+ if (builder.verbose_link) %%zig_args.append("--verbose-link");
if (self.strip) {
%%zig_args.append("--strip");
diff --git a/std/fmt/errol/index.zig b/std/fmt/errol/index.zig
index ac9f6b0c64..0a1ea7deef 100644
--- a/std/fmt/errol/index.zig
+++ b/std/fmt/errol/index.zig
@@ -32,13 +32,13 @@ pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {
fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {
// check if in integer or fixed range
- if (val >= 9.007199254740992e15 and val < 3.40282366920938e+38) {
+ if (val > 9.007199254740992e15 and val < 3.40282366920938e+38) {
return errolInt(val, buffer);
} else if (val >= 16.0 and val < 9.007199254740992e15) {
return errolFixed(val, buffer);
}
-
+
// normalize the midpoint
const e = math.frexp(val).exponent;
@@ -138,7 +138,7 @@ fn tableLowerBound(k: u64) -> usize {
while (j < enum3.len) {
if (enum3[j] < k) {
- j = 2 * k + 2;
+ j = 2 * j + 2;
} else {
i = j;
j = 2 * j + 1;
@@ -217,7 +217,7 @@ fn hpMul10(hp: &HP) {
hp.val *= 10.0;
hp.off *= 10.0;
-
+
var off = hp.val;
off -= val * 8.0;
off -= val * 2.0;
@@ -235,13 +235,13 @@ fn hpMul10(hp: &HP) {
fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
const pow19 = u128(1e19);
- assert((val >= 9.007199254740992e15) and val < (3.40282366920938e38));
+ assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));
var mid = u128(val);
var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0);
var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0);
- if (@bitCast(u64, val) & 0x1 != 0) {
+ if (@bitCast(u64, val) & 0x1 != 0) {
high -= 1;
} else {
low -= 1;
@@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {
}
fn fpnext(val: f64) -> f64 {
- return @bitCast(f64, @bitCast(u64, val) + 1);
+ return @bitCast(f64, @bitCast(u64, val) +% 1);
}
fn fpprev(val: f64) -> f64 {
- return @bitCast(f64, @bitCast(u64, val) - 1);
+ return @bitCast(f64, @bitCast(u64, val) -% 1);
}
pub const c_digits_lut = []u8 {
@@ -510,10 +510,6 @@ fn u64toa(value_param: u64, buffer: []u8) -> usize {
buf_index += 1;
buffer[buf_index] = c_digits_lut[d8];
buf_index += 1;
- buffer[buf_index] = c_digits_lut[d8];
- buf_index += 1;
- buffer[buf_index] = c_digits_lut[d8];
- buf_index += 1;
buffer[buf_index] = c_digits_lut[d8 + 1];
buf_index += 1;
} else {
@@ -613,7 +609,7 @@ fn fpeint(from: f64) -> u128 {
const bits = @bitCast(u64, from);
assert((bits & ((1 << 52) - 1)) == 0);
- return u64(1) << u6(((bits >> 52) - 1023));
+ return u128(1) << @truncate(u7, (bits >> 52) -% 1023);
}
diff --git a/std/fmt/index.zig b/std/fmt/index.zig
index b378afa1b0..56b9a2e960 100644
--- a/std/fmt/index.zig
+++ b/std/fmt/index.zig
@@ -244,30 +244,47 @@ pub fn formatBuf(buf: []const u8, width: usize,
}
pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {
- var buffer: [20]u8 = undefined;
- const float_decimal = errol3(f64(value), buffer[0..]);
- if (float_decimal.exp != 0) {
- if (!output(context, float_decimal.digits[0..1]))
- return false;
- } else {
- if (!output(context, "0"))
+ var x = f64(value);
+
+ // Errol doesn't handle these special cases.
+ if (math.isNan(x)) {
+ return output(context, "NaN");
+ }
+ if (math.signbit(x)) {
+ if (!output(context, "-"))
return false;
+ x = -x;
}
+ if (math.isPositiveInf(x)) {
+ return output(context, "Infinity");
+ }
+ if (x == 0.0) {
+ return output(context, "0.0");
+ }
+
+ var buffer: [32]u8 = undefined;
+ const float_decimal = errol3(x, buffer[0..]);
+ if (!output(context, float_decimal.digits[0..1]))
+ return false;
if (!output(context, "."))
return false;
if (float_decimal.digits.len > 1) {
- const start = if (float_decimal.exp == 0) usize(0) else usize(1);
- if (!output(context, float_decimal.digits[start .. math.min(usize(7), float_decimal.digits.len)]))
+ const num_digits = if (@typeOf(value) == f32) {
+ math.min(usize(9), float_decimal.digits.len)
+ } else {
+ float_decimal.digits.len
+ };
+ if (!output(context, float_decimal.digits[1 .. num_digits]))
return false;
} else {
if (!output(context, "0"))
return false;
}
- if (float_decimal.exp != 1 and float_decimal.exp != 0) {
+ if (float_decimal.exp != 1) {
if (!output(context, "e"))
return false;
- if (!formatInt(float_decimal.exp, 10, false, 0, context, output))
+ if (!formatInt(float_decimal.exp - 1, 10, false, 0, context, output))
return false;
}
return true;
@@ -514,6 +531,38 @@ test "fmt.format" {
const result = bufPrint(buf1[0..], "u3: {}\n", value);
assert(mem.eql(u8, result, "u3: 5\n"));
}
+
+ // TODO get these tests passing in release modes
+ // https://github.com/zig-lang/zig/issues/564
+ if (builtin.mode == builtin.Mode.Debug) {
+ {
+ var buf1: [32]u8 = undefined;
+ const value: f32 = 12.34;
+ const result = bufPrint(buf1[0..], "f32: {}\n", value);
+ assert(mem.eql(u8, result, "f32: 1.23400001e1\n"));
+ }
+ {
+ var buf1: [32]u8 = undefined;
+ const value: f64 = -12.34e10;
+ const result = bufPrint(buf1[0..], "f64: {}\n", value);
+ assert(mem.eql(u8, result, "f64: -1.234e11\n"));
+ }
+ {
+ var buf1: [32]u8 = undefined;
+ const result = bufPrint(buf1[0..], "f64: {}\n", math.nan_f64);
+ assert(mem.eql(u8, result, "f64: NaN\n"));
+ }
+ {
+ var buf1: [32]u8 = undefined;
+ const result = bufPrint(buf1[0..], "f64: {}\n", math.inf_f64);
+ assert(mem.eql(u8, result, "f64: Infinity\n"));
+ }
+ {
+ var buf1: [32]u8 = undefined;
+ const result = bufPrint(buf1[0..], "f64: {}\n", -math.inf_f64);
+ assert(mem.eql(u8, result, "f64: -Infinity\n"));
+ }
+ }
}
pub fn trim(buf: []const u8) -> []const u8 {
diff --git a/std/special/build_runner.zig b/std/special/build_runner.zig
index b1fbfc6c2b..089137c923 100644
--- a/std/special/build_runner.zig
+++ b/std/special/build_runner.zig
@@ -69,6 +69,18 @@ pub fn main() -> %void {
%%io.stderr.printf("Expected argument after --prefix\n\n");
return usage(&builder, false, &io.stderr);
});
+ } else if (mem.eql(u8, arg, "--verbose-tokenize")) {
+ builder.verbose_tokenize = true;
+ } else if (mem.eql(u8, arg, "--verbose-ast")) {
+ builder.verbose_ast = true;
+ } else if (mem.eql(u8, arg, "--verbose-link")) {
+ builder.verbose_link = true;
+ } else if (mem.eql(u8, arg, "--verbose-ir")) {
+ builder.verbose_ir = true;
+ } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
+ builder.verbose_llvm_ir = true;
+ } else if (mem.eql(u8, arg, "--verbose-cimport")) {
+ builder.verbose_cimport = true;
} else {
%%io.stderr.printf("Unrecognized argument: {}\n\n", arg);
return usage(&builder, false, &io.stderr);
@@ -116,27 +128,40 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)
\\
\\General Options:
\\ --help Print this help and exit
- \\ --build-file [file] Override path to build.zig
- \\ --cache-dir [path] Override path to cache directory
\\ --verbose Print commands before executing them
- \\ --debug-build-verbose Print verbose debugging information for the build system itself
- \\ --prefix [prefix] Override default install prefix
+ \\ --prefix $path Override default install prefix
\\
\\Project-Specific Options:
\\
);
if (builder.available_options_list.len == 0) {
- %%out_stream.printf(" (none)\n");
+ %%out_stream.print(" (none)\n");
} else {
for (builder.available_options_list.toSliceConst()) |option| {
const name = %%fmt.allocPrint(allocator,
- " -D{}=({})", option.name, Builder.typeIdName(option.type_id));
+ " -D{}=${}", option.name, Builder.typeIdName(option.type_id));
defer allocator.free(name);
- %%out_stream.printf("{s24} {}\n", name, option.description);
+ %%out_stream.print("{s24} {}\n", name, option.description);
}
}
+ %%out_stream.write(
+ \\
+ \\Advanced Options:
+ \\ --build-file $file Override path to build.zig
+ \\ --cache-dir $path Override path to zig cache directory
+ \\ --verbose-tokenize Enable compiler debug output for tokenization
+ \\ --verbose-ast Enable compiler debug output for parsing into an AST
+ \\ --verbose-link Enable compiler debug output for linking
+ \\ --verbose-ir Enable compiler debug output for Zig IR
+ \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
+ \\ --verbose-cimport Enable compiler debug output for C imports
+ \\
+ );
+
+ %%out_stream.flush();
+
if (out_stream == &io.stderr)
return error.InvalidArgs;
}
diff --git a/std/special/compiler_rt/comparetf2.zig b/std/special/compiler_rt/comparetf2.zig
index 45c7cb5037..f1552ca61f 100644
--- a/std/special/compiler_rt/comparetf2.zig
+++ b/std/special/compiler_rt/comparetf2.zig
@@ -20,7 +20,7 @@ const infRep = exponentMask;
const builtin = @import("builtin");
const is_test = builtin.is_test;
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __letf2(a: f128, b: f128) -> c_int {
@setDebugSafety(this, is_test);
diff --git a/std/special/compiler_rt/fixunsdfdi.zig b/std/special/compiler_rt/fixunsdfdi.zig
index 0290ad3975..5f730bbc85 100644
--- a/std/special/compiler_rt/fixunsdfdi.zig
+++ b/std/special/compiler_rt/fixunsdfdi.zig
@@ -1,6 +1,6 @@
const fixuint = @import("fixuint.zig").fixuint;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __fixunsdfdi(a: f64) -> u64 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/fixunsdfsi.zig b/std/special/compiler_rt/fixunsdfsi.zig
index 1dbc2525f2..784d5fde4f 100644
--- a/std/special/compiler_rt/fixunsdfsi.zig
+++ b/std/special/compiler_rt/fixunsdfsi.zig
@@ -1,6 +1,6 @@
const fixuint = @import("fixuint.zig").fixuint;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __fixunsdfsi(a: f64) -> u32 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/fixunsdfti.zig b/std/special/compiler_rt/fixunsdfti.zig
index 33b0e7c274..579455c2f9 100644
--- a/std/special/compiler_rt/fixunsdfti.zig
+++ b/std/special/compiler_rt/fixunsdfti.zig
@@ -1,6 +1,6 @@
const fixuint = @import("fixuint.zig").fixuint;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __fixunsdfti(a: f64) -> u128 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/fixunssfdi.zig b/std/special/compiler_rt/fixunssfdi.zig
index c183f17c62..eab553d8c9 100644
--- a/std/special/compiler_rt/fixunssfdi.zig
+++ b/std/special/compiler_rt/fixunssfdi.zig
@@ -1,6 +1,6 @@
const fixuint = @import("fixuint.zig").fixuint;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __fixunssfdi(a: f32) -> u64 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/fixunssfsi.zig b/std/special/compiler_rt/fixunssfsi.zig
index 51ceef65d3..18c0e66677 100644
--- a/std/special/compiler_rt/fixunssfsi.zig
+++ b/std/special/compiler_rt/fixunssfsi.zig
@@ -1,6 +1,6 @@
const fixuint = @import("fixuint.zig").fixuint;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __fixunssfsi(a: f32) -> u32 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/fixunssfti.zig b/std/special/compiler_rt/fixunssfti.zig
index 69e1c82a9d..f513604247 100644
--- a/std/special/compiler_rt/fixunssfti.zig
+++ b/std/special/compiler_rt/fixunssfti.zig
@@ -1,6 +1,6 @@
const fixuint = @import("fixuint.zig").fixuint;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __fixunssfti(a: f32) -> u128 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/fixunstfdi.zig b/std/special/compiler_rt/fixunstfdi.zig
index a5dbe0f52e..85212e2176 100644
--- a/std/special/compiler_rt/fixunstfdi.zig
+++ b/std/special/compiler_rt/fixunstfdi.zig
@@ -1,6 +1,6 @@
const fixuint = @import("fixuint.zig").fixuint;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __fixunstfdi(a: f128) -> u64 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/fixunstfsi.zig b/std/special/compiler_rt/fixunstfsi.zig
index d488f4c602..33c85c9224 100644
--- a/std/special/compiler_rt/fixunstfsi.zig
+++ b/std/special/compiler_rt/fixunstfsi.zig
@@ -1,6 +1,6 @@
const fixuint = @import("fixuint.zig").fixuint;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __fixunstfsi(a: f128) -> u32 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/fixunstfti.zig b/std/special/compiler_rt/fixunstfti.zig
index fc5c645d72..1bf7fbab4b 100644
--- a/std/special/compiler_rt/fixunstfti.zig
+++ b/std/special/compiler_rt/fixunstfti.zig
@@ -1,6 +1,6 @@
const fixuint = @import("fixuint.zig").fixuint;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __fixunstfti(a: f128) -> u128 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/index.zig b/std/special/compiler_rt/index.zig
index 4a4d71fde9..bea06a0b41 100644
--- a/std/special/compiler_rt/index.zig
+++ b/std/special/compiler_rt/index.zig
@@ -26,7 +26,7 @@ const win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.
const win64 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.x86_64;
const win32_nocrt = win32 and !builtin.link_libc;
const win64_nocrt = win64 and !builtin.link_libc;
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+pub const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak;
const strong_linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;
const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
@@ -152,10 +152,6 @@ export nakedcc fn _chkstk() align(4) {
@setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal);
}
-// TODO The implementation from compiler-rt causes crashes and
-// the implementation from disassembled ntdll seems to depend on
-// thread local storage. So we have given up this safety check
-// and simply have `ret`.
export nakedcc fn __chkstk() align(4) {
@setDebugSafety(this, false);
diff --git a/std/special/compiler_rt/udivmoddi4.zig b/std/special/compiler_rt/udivmoddi4.zig
index 2e167bc64a..8005538d9a 100644
--- a/std/special/compiler_rt/udivmoddi4.zig
+++ b/std/special/compiler_rt/udivmoddi4.zig
@@ -1,6 +1,6 @@
const udivmod = @import("udivmod.zig").udivmod;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/udivmodti4.zig b/std/special/compiler_rt/udivmodti4.zig
index d7507e9521..2ee2fdb57f 100644
--- a/std/special/compiler_rt/udivmodti4.zig
+++ b/std/special/compiler_rt/udivmodti4.zig
@@ -1,6 +1,6 @@
const udivmod = @import("udivmod.zig").udivmod;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/udivti3.zig b/std/special/compiler_rt/udivti3.zig
index 67ea15eb96..3764449758 100644
--- a/std/special/compiler_rt/udivti3.zig
+++ b/std/special/compiler_rt/udivti3.zig
@@ -1,6 +1,6 @@
const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __udivti3(a: u128, b: u128) -> u128 {
@setDebugSafety(this, builtin.is_test);
diff --git a/std/special/compiler_rt/umodti3.zig b/std/special/compiler_rt/umodti3.zig
index e4a4e7a7ee..0ad9e127b3 100644
--- a/std/special/compiler_rt/umodti3.zig
+++ b/std/special/compiler_rt/umodti3.zig
@@ -1,6 +1,6 @@
const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
const builtin = @import("builtin");
-const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;
+const linkage = @import("index.zig").linkage;
export fn __umodti3(a: u128, b: u128) -> u128 {
@setDebugSafety(this, builtin.is_test);
diff --git a/test/behavior.zig b/test/behavior.zig
index 54c954be3d..952c725e8c 100644
--- a/test/behavior.zig
+++ b/test/behavior.zig
@@ -40,6 +40,7 @@ comptime {
_ = @import("cases/this.zig");
_ = @import("cases/try.zig");
_ = @import("cases/undefined.zig");
+ _ = @import("cases/union.zig");
_ = @import("cases/var_args.zig");
_ = @import("cases/void.zig");
_ = @import("cases/while.zig");
diff --git a/test/cases/align.zig b/test/cases/align.zig
index cd806a5dc6..3bf0d9c9af 100644
--- a/test/cases/align.zig
+++ b/test/cases/align.zig
@@ -188,6 +188,6 @@ test "alignstack" {
}
fn fnWithAlignedStack() -> i32 {
- @setAlignStack(1024);
+ @setAlignStack(256);
return 1234;
}
diff --git a/test/cases/union.zig b/test/cases/union.zig
new file mode 100644
index 0000000000..4b8ccb7245
--- /dev/null
+++ b/test/cases/union.zig
@@ -0,0 +1,33 @@
+const assert = @import("std").debug.assert;
+
+const Value = enum {
+ Int: u64,
+ Array: [9]u8,
+};
+
+const Agg = struct {
+ val1: Value,
+ val2: Value,
+};
+
+const v1 = Value.Int { 1234 };
+const v2 = Value.Array { []u8{3} ** 9 };
+
+const err = (%Agg)(Agg {
+ .val1 = v1,
+ .val2 = v2,
+});
+
+const array = []Value { v1, v2, v1, v2};
+
+
+test "unions embedded in aggregate types" {
+ switch (array[1]) {
+ Value.Array => |arr| assert(arr[4] == 3),
+ else => unreachable,
+ }
+ switch((%%err).val1) {
+ Value.Int => |x| assert(x == 1234),
+ else => unreachable,
+ }
+}
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index dd25886d2b..f8e08d599f 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -2187,6 +2187,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
".tmp_source.zig:3:5: error: alignstack set twice",
".tmp_source.zig:2:5: note: first set here");
+ cases.add("@setAlignStack too big",
+ \\export fn entry() {
+ \\ @setAlignStack(511 + 1);
+ \\}
+ ,
+ ".tmp_source.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256");
+
cases.add("storing runtime value in compile time variable then using it",
\\const Mode = @import("builtin").Mode;
\\
@@ -2231,4 +2238,41 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
\\}
,
".tmp_source.zig:37:16: error: cannot store runtime value in compile time variable");
+
+ cases.add("field access of opaque type",
+ \\const MyType = @OpaqueType();
+ \\
+ \\export fn entry() -> bool {
+ \\ var x: i32 = 1;
+ \\ return bar(@ptrCast(&MyType, &x));
+ \\}
+ \\
+ \\fn bar(x: &MyType) -> bool {
+ \\ return x.blah;
+ \\}
+ ,
+ ".tmp_source.zig:9:13: error: type '&MyType' does not support field access");
+
+ cases.add("carriage return special case",
+ "fn test() -> bool {\r\n" ++
+ " true\r\n" ++
+ "}\r\n"
+ ,
+ ".tmp_source.zig:1:20: error: invalid carriage return, only '\\n' line endings are supported");
+
+ cases.add("non-printable invalid character",
+ "\xff\xfe" ++
+ \\fn test() -> bool {\r
+ \\ true\r
+ \\}
+ ,
+ ".tmp_source.zig:1:1: error: invalid character: '\\xff'");
+
+ cases.add("non-printable invalid character with escape alternative",
+ "fn test() -> bool {\n" ++
+ "\ttrue\n" ++
+ "}\n"
+ ,
+ ".tmp_source.zig:2:1: error: invalid character: '\\t'");
+
}