authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-18 09:59:57-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-18 09:59:57-05:00
log1fdebc1dc4881a00766f7c2b4b2d8ee6ad6e79b6
treec6dc0f8f2ce01f7d38d1c5921eaa11f2d163c589
parent68f63323437e1b974be7a9982f5d70b95624878b

wip export rewrite


46 files changed, 1486 insertions(+), 1193 deletions(-)

doc/langref.html.in+3-5
...@@ -5815,13 +5815,13 @@ TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestD...@@ -5815,13 +5815,13 @@ TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestD
58155815
5816TestDecl = "test" String Block5816TestDecl = "test" String Block
58175817
5818TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | UseDecl)5818TopLevelDecl = option("pub") (FnDef | ExternDecl | GlobalVarDecl | UseDecl)
58195819
5820ErrorValueDecl = "error" Symbol ";"5820ErrorValueDecl = "error" Symbol ";"
58215821
5822GlobalVarDecl = VariableDeclaration ";"5822GlobalVarDecl = VariableDeclaration ";"
58235823
5824VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") "=" Expression5824VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") option("section" "(" Expression ")") "=" Expression
58255825
5826ContainerMember = (ContainerField | FnDef | GlobalVarDecl)5826ContainerMember = (ContainerField | FnDef | GlobalVarDecl)
58275827
...@@ -5831,9 +5831,7 @@ UseDecl = "use" Expression ";"...@@ -5831,9 +5831,7 @@ UseDecl = "use" Expression ";"
58315831
5832ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";"5832ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";"
58335833
5834FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("-&gt;" TypeExpr)5834FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("-&gt;" TypeExpr)
5835
5836VisibleMod = "pub" | "export"
58375835
5838FnDef = option("inline" | "extern") FnProto Block5836FnDef = option("inline" | "extern") FnProto Block
58395837
example/hello_world/hello_libc.zig+6-2
...@@ -5,9 +5,13 @@ const c = @cImport({...@@ -5,9 +5,13 @@ const c = @cImport({
5 @cInclude("string.h");5 @cInclude("string.h");
6});6});
77
8const msg = c"Hello, world!\n";8comptime {
9 @export("main", main);
10}
11
12extern fn main(argc: c_int, argv: &&u8) -> c_int {
13 const msg = c"Hello, world!\n";
914
10export fn main(argc: c_int, argv: &&u8) -> c_int {
11 if (c.printf(msg) != c_int(c.strlen(msg)))15 if (c.printf(msg) != c_int(c.strlen(msg)))
12 return -1;16 return -1;
1317
example/mix_o_files/base64.zig+4-1
...@@ -1,6 +1,9 @@...@@ -1,6 +1,9 @@
1const base64 = @import("std").base64;1const base64 = @import("std").base64;
22
3export fn decode_base_64(dest_ptr: &u8, dest_len: usize, source_ptr: &const u8, source_len: usize) -> usize {3comptime {
4 @export("decode_base_64", decode_base_64);
5}
6extern fn decode_base_64(dest_ptr: &u8, dest_len: usize, source_ptr: &const u8, source_len: usize) -> usize {
4 const src = source_ptr[0..source_len];7 const src = source_ptr[0..source_len];
5 const dest = dest_ptr[0..dest_len];8 const dest = dest_ptr[0..dest_len];
6 const base64_decoder = base64.standard_decoder_unsafe;9 const base64_decoder = base64.standard_decoder_unsafe;
example/shared_library/mathtest.zig+4-1
...@@ -1,3 +1,6 @@...@@ -1,3 +1,6 @@
1export fn add(a: i32, b: i32) -> i32 {1comptime {
2 @export("add", add);
3}
4extern fn add(a: i32, b: i32) -> i32 {
2 a + b5 a + b
3}6}
src/all_types.hpp+33-28
...@@ -37,6 +37,7 @@ struct IrBasicBlock;...@@ -37,6 +37,7 @@ struct IrBasicBlock;
37struct ScopeDecls;37struct ScopeDecls;
38struct ZigWindowsSDK;38struct ZigWindowsSDK;
39struct Tld;39struct Tld;
40struct TldExport;
4041
41struct IrGotoItem {42struct IrGotoItem {
42 AstNode *source_node;43 AstNode *source_node;
...@@ -272,7 +273,6 @@ enum ReturnKnowledge {...@@ -272,7 +273,6 @@ enum ReturnKnowledge {
272enum VisibMod {273enum VisibMod {
273 VisibModPrivate,274 VisibModPrivate,
274 VisibModPub,275 VisibModPub,
275 VisibModExport,
276};276};
277277
278enum GlobalLinkageId {278enum GlobalLinkageId {
...@@ -313,11 +313,14 @@ struct TldVar {...@@ -313,11 +313,14 @@ struct TldVar {
313 Tld base;313 Tld base;
314314
315 VariableTableEntry *var;315 VariableTableEntry *var;
316 AstNode *set_global_section_node;
317 Buf *section_name;
318 AstNode *set_global_linkage_node;
319 GlobalLinkageId linkage;
320 Buf *extern_lib_name;316 Buf *extern_lib_name;
317 Buf *section_name;
318
319 size_t export_count;
320 union {
321 TldExport *tld; // if export_count == 1
322 TldExport **tld_list; // if export_count > 1
323 } export_data;
321};324};
322325
323struct TldFn {326struct TldFn {
...@@ -432,6 +435,8 @@ struct AstNodeFnProto {...@@ -432,6 +435,8 @@ struct AstNodeFnProto {
432 Buf *lib_name;435 Buf *lib_name;
433 // populated if the "align A" is present436 // populated if the "align A" is present
434 AstNode *align_expr;437 AstNode *align_expr;
438 // populated if the "section(S)" is present
439 AstNode *section_expr;
435};440};
436441
437struct AstNodeFnDef {442struct AstNodeFnDef {
...@@ -487,8 +492,10 @@ struct AstNodeVariableDeclaration {...@@ -487,8 +492,10 @@ struct AstNodeVariableDeclaration {
487 AstNode *expr;492 AstNode *expr;
488 // populated if this is an extern declaration493 // populated if this is an extern declaration
489 Buf *lib_name;494 Buf *lib_name;
490 // populated if the "align A" is present495 // populated if the "align(A)" is present
491 AstNode *align_expr;496 AstNode *align_expr;
497 // populated if the "section(S)" is present
498 AstNode *section_expr;
492};499};
493500
494struct AstNodeErrorValueDecl {501struct AstNodeErrorValueDecl {
...@@ -1177,6 +1184,12 @@ enum FnInline {...@@ -1177,6 +1184,12 @@ enum FnInline {
1177 FnInlineNever,1184 FnInlineNever,
1178};1185};
11791186
1187struct FnExport {
1188 Buf name;
1189 GlobalLinkageId linkage;
1190 AstNode *source_node;
1191};
1192
1180struct FnTableEntry {1193struct FnTableEntry {
1181 LLVMValueRef llvm_value;1194 LLVMValueRef llvm_value;
1182 const char *llvm_name;1195 const char *llvm_name;
...@@ -1204,12 +1217,11 @@ struct FnTableEntry {...@@ -1204,12 +1217,11 @@ struct FnTableEntry {
1204 ZigList<IrInstruction *> alloca_list;1217 ZigList<IrInstruction *> alloca_list;
1205 ZigList<VariableTableEntry *> variable_list;1218 ZigList<VariableTableEntry *> variable_list;
12061219
1207 AstNode *set_global_section_node;
1208 Buf *section_name;1220 Buf *section_name;
1209 AstNode *set_global_linkage_node;
1210 GlobalLinkageId linkage;
1211 AstNode *set_alignstack_node;1221 AstNode *set_alignstack_node;
1212 uint32_t alignstack_value;1222 uint32_t alignstack_value;
1223
1224 ZigList<FnExport> export_list;
1213};1225};
12141226
1215uint32_t fn_table_entry_hash(FnTableEntry*);1227uint32_t fn_table_entry_hash(FnTableEntry*);
...@@ -1258,8 +1270,6 @@ enum BuiltinFnId {...@@ -1258,8 +1270,6 @@ enum BuiltinFnId {
1258 BuiltinFnIdSetFloatMode,1270 BuiltinFnIdSetFloatMode,
1259 BuiltinFnIdTypeName,1271 BuiltinFnIdTypeName,
1260 BuiltinFnIdCanImplicitCast,1272 BuiltinFnIdCanImplicitCast,
1261 BuiltinFnIdSetGlobalSection,
1262 BuiltinFnIdSetGlobalLinkage,
1263 BuiltinFnIdPanic,1273 BuiltinFnIdPanic,
1264 BuiltinFnIdPtrCast,1274 BuiltinFnIdPtrCast,
1265 BuiltinFnIdBitCast,1275 BuiltinFnIdBitCast,
...@@ -1279,6 +1289,8 @@ enum BuiltinFnId {...@@ -1279,6 +1289,8 @@ enum BuiltinFnId {
1279 BuiltinFnIdOpaqueType,1289 BuiltinFnIdOpaqueType,
1280 BuiltinFnIdSetAlignStack,1290 BuiltinFnIdSetAlignStack,
1281 BuiltinFnIdArgType,1291 BuiltinFnIdArgType,
1292 BuiltinFnIdExport,
1293 BuiltinFnIdExportWithLinkage,
1282};1294};
12831295
1284struct BuiltinFnEntry {1296struct BuiltinFnEntry {
...@@ -1425,7 +1437,7 @@ struct CodeGen {...@@ -1425,7 +1437,7 @@ struct CodeGen {
1425 HashMap<GenericFnTypeId *, FnTableEntry *, generic_fn_type_id_hash, generic_fn_type_id_eql> generic_table;1437 HashMap<GenericFnTypeId *, FnTableEntry *, generic_fn_type_id_hash, generic_fn_type_id_eql> generic_table;
1426 HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table;1438 HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table;
1427 HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table;1439 HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table;
1428 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> exported_symbol_names;1440 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names;
1429 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;1441 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;
14301442
14311443
...@@ -1886,8 +1898,6 @@ enum IrInstructionId {...@@ -1886,8 +1898,6 @@ enum IrInstructionId {
1886 IrInstructionIdCheckStatementIsVoid,1898 IrInstructionIdCheckStatementIsVoid,
1887 IrInstructionIdTypeName,1899 IrInstructionIdTypeName,
1888 IrInstructionIdCanImplicitCast,1900 IrInstructionIdCanImplicitCast,
1889 IrInstructionIdSetGlobalSection,
1890 IrInstructionIdSetGlobalLinkage,
1891 IrInstructionIdDeclRef,1901 IrInstructionIdDeclRef,
1892 IrInstructionIdPanic,1902 IrInstructionIdPanic,
1893 IrInstructionIdTagName,1903 IrInstructionIdTagName,
...@@ -1901,6 +1911,7 @@ enum IrInstructionId {...@@ -1901,6 +1911,7 @@ enum IrInstructionId {
1901 IrInstructionIdOpaqueType,1911 IrInstructionIdOpaqueType,
1902 IrInstructionIdSetAlignStack,1912 IrInstructionIdSetAlignStack,
1903 IrInstructionIdArgType,1913 IrInstructionIdArgType,
1914 IrInstructionIdExport,
1904};1915};
19051916
1906struct IrInstruction {1917struct IrInstruction {
...@@ -2626,20 +2637,6 @@ struct IrInstructionCanImplicitCast {...@@ -2626,20 +2637,6 @@ struct IrInstructionCanImplicitCast {
2626 IrInstruction *target_value;2637 IrInstruction *target_value;
2627};2638};
26282639
2629struct IrInstructionSetGlobalSection {
2630 IrInstruction base;
2631
2632 Tld *tld;
2633 IrInstruction *value;
2634};
2635
2636struct IrInstructionSetGlobalLinkage {
2637 IrInstruction base;
2638
2639 Tld *tld;
2640 IrInstruction *value;
2641};
2642
2643struct IrInstructionDeclRef {2640struct IrInstructionDeclRef {
2644 IrInstruction base;2641 IrInstruction base;
26452642
...@@ -2728,6 +2725,14 @@ struct IrInstructionArgType {...@@ -2728,6 +2725,14 @@ struct IrInstructionArgType {
2728 IrInstruction *arg_index;2725 IrInstruction *arg_index;
2729};2726};
27302727
2728struct IrInstructionExport {
2729 IrInstruction base;
2730
2731 IrInstruction *name;
2732 IrInstruction *linkage;
2733 IrInstruction *target;
2734};
2735
2731static const size_t slice_ptr_index = 0;2736static const size_t slice_ptr_index = 0;
2732static const size_t slice_len_index = 1;2737static const size_t slice_len_index = 1;
27332738
src/analyze.cpp+66-63
...@@ -1062,7 +1062,7 @@ void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_cou...@@ -1062,7 +1062,7 @@ void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_cou
1062 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;1062 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
10631063
1064 if (fn_proto->cc == CallingConventionUnspecified) {1064 if (fn_proto->cc == CallingConventionUnspecified) {
1065 bool extern_abi = fn_proto->is_extern || (fn_proto->visib_mod == VisibModExport);1065 bool extern_abi = fn_proto->is_extern;
1066 fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified;1066 fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified;
1067 } else {1067 } else {
1068 fn_type_id->cc = fn_proto->cc;1068 fn_type_id->cc = fn_proto->cc;
...@@ -1093,6 +1093,38 @@ static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_...@@ -1093,6 +1093,38 @@ static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_
1093 return true;1093 return true;
1094}1094}
10951095
1096static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **out_buffer) {
1097 TypeTableEntry *ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
1098 TypeTableEntry *str_type = get_slice_type(g, ptr_type);
1099 IrInstruction *instr = analyze_const_value(g, scope, node, str_type, nullptr);
1100 if (type_is_invalid(instr->value.type))
1101 return false;
1102
1103 ConstExprValue *ptr_field = &instr->value.data.x_struct.fields[slice_ptr_index];
1104 ConstExprValue *len_field = &instr->value.data.x_struct.fields[slice_len_index];
1105
1106 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
1107 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
1108 expand_undef_array(g, array_val);
1109 size_t len = bigint_as_unsigned(&len_field->data.x_bigint);
1110 Buf *result = buf_alloc();
1111 buf_resize(result, len);
1112 for (size_t i = 0; i < len; i += 1) {
1113 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;
1114 ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index];
1115 if (char_val->special == ConstValSpecialUndef) {
1116 add_node_error(g, node, buf_sprintf("use of undefined value"));
1117 return false;
1118 }
1119 uint64_t big_c = bigint_as_unsigned(&char_val->data.x_bigint);
1120 assert(big_c <= UINT8_MAX);
1121 uint8_t c = (uint8_t)big_c;
1122 buf_ptr(result)[i] = c;
1123 }
1124 *out_buffer = result;
1125 return true;
1126}
1127
1096static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) {1128static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) {
1097 assert(proto_node->type == NodeTypeFnProto);1129 assert(proto_node->type == NodeTypeFnProto);
1098 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;1130 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
...@@ -2472,7 +2504,7 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) {...@@ -2472,7 +2504,7 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) {
2472 buf_append_buf(buf, tld->name);2504 buf_append_buf(buf, tld->name);
2473}2505}
24742506
2475FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) {2507FnTableEntry *create_fn_raw(FnInline inline_value) {
2476 FnTableEntry *fn_entry = allocate<FnTableEntry>(1);2508 FnTableEntry *fn_entry = allocate<FnTableEntry>(1);
24772509
2478 fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;2510 fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;
...@@ -2480,7 +2512,6 @@ FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) {...@@ -2480,7 +2512,6 @@ FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) {
2480 fn_entry->analyzed_executable.fn_entry = fn_entry;2512 fn_entry->analyzed_executable.fn_entry = fn_entry;
2481 fn_entry->ir_executable.fn_entry = fn_entry;2513 fn_entry->ir_executable.fn_entry = fn_entry;
2482 fn_entry->fn_inline = inline_value;2514 fn_entry->fn_inline = inline_value;
2483 fn_entry->linkage = linkage;
24842515
2485 return fn_entry;2516 return fn_entry;
2486}2517}
...@@ -2490,9 +2521,7 @@ FnTableEntry *create_fn(AstNode *proto_node) {...@@ -2490,9 +2521,7 @@ FnTableEntry *create_fn(AstNode *proto_node) {
2490 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;2521 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
24912522
2492 FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto;2523 FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto;
2493 GlobalLinkageId linkage = (fn_proto->visib_mod == VisibModExport || proto_node->data.fn_proto.is_extern) ?2524 FnTableEntry *fn_entry = create_fn_raw(inline_value);
2494 GlobalLinkageIdStrong : GlobalLinkageIdInternal;
2495 FnTableEntry *fn_entry = create_fn_raw(inline_value, linkage);
24962525
2497 fn_entry->proto_node = proto_node;2526 fn_entry->proto_node = proto_node;
2498 fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr :2527 fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr :
...@@ -2572,7 +2601,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -2572,7 +2601,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
2572 add_node_error(g, param_node, buf_sprintf("missing parameter name"));2601 add_node_error(g, param_node, buf_sprintf("missing parameter name"));
2573 }2602 }
2574 }2603 }
2575 } else if (fn_table_entry->linkage != GlobalLinkageIdInternal) {2604 } else {
2576 g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base);2605 g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base);
2577 }2606 }
25782607
...@@ -2580,6 +2609,15 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -2580,6 +2609,15 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
25802609
2581 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope);2610 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope);
25822611
2612 if (fn_proto->section_expr != nullptr) {
2613 if (fn_table_entry->body_node == nullptr) {
2614 add_node_error(g, fn_proto->section_expr,
2615 buf_sprintf("cannot set section of external function '%s'", buf_ptr(&fn_table_entry->symbol_name)));
2616 } else {
2617 analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name);
2618 }
2619 }
2620
2583 if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) {2621 if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) {
2584 tld_fn->base.resolution = TldResolutionInvalid;2622 tld_fn->base.resolution = TldResolutionInvalid;
2585 return;2623 return;
...@@ -2594,15 +2632,12 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -2594,15 +2632,12 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
2594 {2632 {
2595 if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) {2633 if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) {
2596 g->main_fn = fn_table_entry;2634 g->main_fn = fn_table_entry;
25972635 TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void);
2598 if (tld_fn->base.visib_mod != VisibModExport) {2636 TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;
2599 TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void);2637 if (actual_return_type != err_void) {
2600 TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;2638 add_node_error(g, fn_proto->return_type,
2601 if (actual_return_type != err_void) {2639 buf_sprintf("expected return type of main to be '%%void', instead is '%s'",
2602 add_node_error(g, fn_proto->return_type,2640 buf_ptr(&actual_return_type->name)));
2603 buf_sprintf("expected return type of main to be '%%void', instead is '%s'",
2604 buf_ptr(&actual_return_type->name)));
2605 }
2606 }2641 }
2607 } else if ((import->package == g->panic_package || g->have_pub_panic) &&2642 } else if ((import->package == g->panic_package || g->have_pub_panic) &&
2608 buf_eql_str(&fn_table_entry->symbol_name, "panic"))2643 buf_eql_str(&fn_table_entry->symbol_name, "panic"))
...@@ -2613,7 +2648,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -2613,7 +2648,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
2613 }2648 }
2614 }2649 }
2615 } else if (source_node->type == NodeTypeTestDecl) {2650 } else if (source_node->type == NodeTypeTestDecl) {
2616 FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong);2651 FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto);
26172652
2618 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');2653 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
26192654
...@@ -2640,20 +2675,6 @@ static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) {...@@ -2640,20 +2675,6 @@ static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) {
2640}2675}
26412676
2642static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {2677static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
2643 if (tld->visib_mod == VisibModExport) {
2644 g->resolve_queue.append(tld);
2645 }
2646
2647 if (tld->visib_mod == VisibModExport) {
2648 auto entry = g->exported_symbol_names.put_unique(tld->name, tld);
2649 if (entry) {
2650 Tld *other_tld = entry->value;
2651 ErrorMsg *msg = add_node_error(g, tld->source_node,
2652 buf_sprintf("exported symbol collision: '%s'", buf_ptr(tld->name)));
2653 add_error_note(g, msg, other_tld->source_node, buf_sprintf("other symbol is here"));
2654 }
2655 }
2656
2657 {2678 {
2658 auto entry = decls_scope->decl_table.put_unique(tld->name, tld);2679 auto entry = decls_scope->decl_table.put_unique(tld->name, tld);
2659 if (entry) {2680 if (entry) {
...@@ -2729,7 +2750,6 @@ static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_s...@@ -2729,7 +2750,6 @@ static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_s
2729 g->resolve_queue.append(&tld_comptime->base);2750 g->resolve_queue.append(&tld_comptime->base);
2730}2751}
27312752
2732
2733void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node,2753void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node,
2734 Scope *parent_scope)2754 Scope *parent_scope)
2735{2755{
...@@ -2985,7 +3005,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -2985,7 +3005,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
2985 AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration;3005 AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration;
29863006
2987 bool is_const = var_decl->is_const;3007 bool is_const = var_decl->is_const;
2988 bool is_export = (tld_var->base.visib_mod == VisibModExport);
2989 bool is_extern = var_decl->is_extern;3008 bool is_extern = var_decl->is_extern;
29903009
2991 TypeTableEntry *explicit_type = nullptr;3010 TypeTableEntry *explicit_type = nullptr;
...@@ -2994,20 +3013,13 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -2994,20 +3013,13 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
2994 explicit_type = validate_var_type(g, var_decl->type, proposed_type);3013 explicit_type = validate_var_type(g, var_decl->type, proposed_type);
2995 }3014 }
29963015
2997 if (is_export && is_extern) {
2998 add_node_error(g, source_node, buf_sprintf("variable is both export and extern"));
2999 }
3000
3001 VarLinkage linkage;3016 VarLinkage linkage;
3002 if (is_export) {3017 if (is_extern) {
3003 linkage = VarLinkageExport;
3004 } else if (is_extern) {
3005 linkage = VarLinkageExternal;3018 linkage = VarLinkageExternal;
3006 } else {3019 } else {
3007 linkage = VarLinkageInternal;3020 linkage = VarLinkageInternal;
3008 }3021 }
30093022
3010
3011 IrInstruction *init_value = nullptr;3023 IrInstruction *init_value = nullptr;
30123024
3013 // TODO more validation for types that can't be used for export/extern variables3025 // TODO more validation for types that can't be used for export/extern variables
...@@ -3056,6 +3068,15 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -3056,6 +3068,15 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
3056 }3068 }
3057 }3069 }
30583070
3071 if (var_decl->section_expr != nullptr) {
3072 if (var_decl->is_extern) {
3073 add_node_error(g, var_decl->section_expr,
3074 buf_sprintf("cannot set section of external variable '%s'", buf_ptr(var_decl->symbol)));
3075 } else if (!analyze_const_string(g, tld_var->base.parent_scope, var_decl->section_expr, &tld_var->section_name)) {
3076 tld_var->section_name = nullptr;
3077 }
3078 }
3079
3059 g->global_vars.append(tld_var);3080 g->global_vars.append(tld_var);
3060}3081}
30613082
...@@ -3724,8 +3745,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a...@@ -3724,8 +3745,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
3724 Buf *proto_name = proto_node->data.fn_proto.name;3745 Buf *proto_name = proto_node->data.fn_proto.name;
37253746
3726 bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub);3747 bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub);
3748 bool ok_cc = (proto_node->data.fn_proto.cc == CallingConventionUnspecified ||
3749 proto_node->data.fn_proto.cc == CallingConventionCold);
37273750
3728 if (is_pub) {3751 if (is_pub && ok_cc) {
3729 if (buf_eql_str(proto_name, "main")) {3752 if (buf_eql_str(proto_name, "main")) {
3730 g->have_pub_main = true;3753 g->have_pub_main = true;
3731 g->windows_subsystem_windows = false;3754 g->windows_subsystem_windows = false;
...@@ -3733,28 +3756,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a...@@ -3733,28 +3756,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
3733 } else if (buf_eql_str(proto_name, "panic")) {3756 } else if (buf_eql_str(proto_name, "panic")) {
3734 g->have_pub_panic = true;3757 g->have_pub_panic = true;
3735 }3758 }
3736 } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && buf_eql_str(proto_name, "main") &&
3737 g->libc_link_lib != nullptr)
3738 {
3739 g->have_c_main = true;
3740 g->windows_subsystem_windows = false;
3741 g->windows_subsystem_console = true;
3742 } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && buf_eql_str(proto_name, "WinMain") &&
3743 g->zig_target.os == ZigLLVM_Win32)
3744 {
3745 g->have_winmain = true;
3746 g->windows_subsystem_windows = true;
3747 g->windows_subsystem_console = false;
3748 } else if (proto_node->data.fn_proto.visib_mod == VisibModExport &&
3749 buf_eql_str(proto_name, "WinMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32)
3750 {
3751 g->have_winmain_crt_startup = true;
3752 } else if (proto_node->data.fn_proto.visib_mod == VisibModExport &&
3753 buf_eql_str(proto_name, "DllMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32)
3754 {
3755 g->have_dllmain_crt_startup = true;
3756 }3759 }
3757
3758 }3760 }
3759 }3761 }
37603762
...@@ -5445,3 +5447,4 @@ uint32_t type_ptr_hash(const TypeTableEntry *ptr) {...@@ -5445,3 +5447,4 @@ uint32_t type_ptr_hash(const TypeTableEntry *ptr) {
5445bool type_ptr_eql(const TypeTableEntry *a, const TypeTableEntry *b) {5447bool type_ptr_eql(const TypeTableEntry *a, const TypeTableEntry *b) {
5446 return a == b;5448 return a == b;
5447}5449}
5450
src/analyze.hpp+2
...@@ -182,4 +182,6 @@ uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry);...@@ -182,4 +182,6 @@ uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry);
182TypeTableEntry *get_align_amt_type(CodeGen *g);182TypeTableEntry *get_align_amt_type(CodeGen *g);
183PackageTableEntry *new_anonymous_package(void);183PackageTableEntry *new_anonymous_package(void);
184184
185Buf *const_value_to_buffer(ConstExprValue *const_val);
186
185#endif187#endif
src/ast_render.cpp+20-1
...@@ -78,7 +78,6 @@ static const char *visib_mod_string(VisibMod mod) {...@@ -78,7 +78,6 @@ static const char *visib_mod_string(VisibMod mod) {
78 switch (mod) {78 switch (mod) {
79 case VisibModPub: return "pub ";79 case VisibModPub: return "pub ";
80 case VisibModPrivate: return "";80 case VisibModPrivate: return "";
81 case VisibModExport: return "export ";
82 }81 }
83 zig_unreachable();82 zig_unreachable();
84}83}
...@@ -440,6 +439,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -440,6 +439,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
440 }439 }
441 }440 }
442 fprintf(ar->f, ")");441 fprintf(ar->f, ")");
442 if (node->data.fn_proto.align_expr) {
443 fprintf(ar->f, " align(");
444 render_node_grouped(ar, node->data.fn_proto.align_expr);
445 fprintf(ar->f, ")");
446 }
447 if (node->data.fn_proto.section_expr) {
448 fprintf(ar->f, " section(");
449 render_node_grouped(ar, node->data.fn_proto.section_expr);
450 fprintf(ar->f, ")");
451 }
443452
444 AstNode *return_type_node = node->data.fn_proto.return_type;453 AstNode *return_type_node = node->data.fn_proto.return_type;
445 if (return_type_node != nullptr) {454 if (return_type_node != nullptr) {
...@@ -526,6 +535,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -526,6 +535,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
526 fprintf(ar->f, ": ");535 fprintf(ar->f, ": ");
527 render_node_grouped(ar, node->data.variable_declaration.type);536 render_node_grouped(ar, node->data.variable_declaration.type);
528 }537 }
538 if (node->data.variable_declaration.align_expr) {
539 fprintf(ar->f, "align(");
540 render_node_grouped(ar, node->data.variable_declaration.align_expr);
541 fprintf(ar->f, ") ");
542 }
543 if (node->data.variable_declaration.section_expr) {
544 fprintf(ar->f, "section(");
545 render_node_grouped(ar, node->data.variable_declaration.section_expr);
546 fprintf(ar->f, ") ");
547 }
529 if (node->data.variable_declaration.expr) {548 if (node->data.variable_declaration.expr) {
530 fprintf(ar->f, " = ");549 fprintf(ar->f, " = ");
531 render_node_grouped(ar, node->data.variable_declaration.expr);550 render_node_grouped(ar, node->data.variable_declaration.expr);
src/codegen.cpp+68-38
...@@ -391,24 +391,51 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {...@@ -391,24 +391,51 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {
391 }391 }
392}392}
393393
394static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) {
395 switch (id) {
396 case GlobalLinkageIdInternal:
397 return LLVMInternalLinkage;
398 case GlobalLinkageIdStrong:
399 return LLVMExternalLinkage;
400 case GlobalLinkageIdWeak:
401 return LLVMWeakODRLinkage;
402 case GlobalLinkageIdLinkOnce:
403 return LLVMLinkOnceODRLinkage;
404 }
405 zig_unreachable();
406}
407
394static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {408static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
395 if (fn_table_entry->llvm_value)409 if (fn_table_entry->llvm_value)
396 return fn_table_entry->llvm_value;410 return fn_table_entry->llvm_value;
397411
398 bool external_linkage = (fn_table_entry->linkage != GlobalLinkageIdInternal);412 Buf *unmangled_name = &fn_table_entry->symbol_name;
399 Buf *symbol_name = get_mangled_name(g, &fn_table_entry->symbol_name, external_linkage);413 Buf *symbol_name;
414 GlobalLinkageId linkage;
415 if (fn_table_entry->body_node == nullptr) {
416 symbol_name = unmangled_name;
417 linkage = GlobalLinkageIdStrong;
418 } else if (fn_table_entry->export_list.length == 0) {
419 symbol_name = get_mangled_name(g, unmangled_name, false);
420 linkage = GlobalLinkageIdInternal;
421 } else {
422 FnExport *fn_export = &fn_table_entry->export_list.items[0];
423 symbol_name = &fn_export->name;
424 linkage = fn_export->linkage;
425 }
400426
427 bool external_linkage = linkage != GlobalLinkageIdInternal;
401 if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall && external_linkage &&428 if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall && external_linkage &&
402 g->zig_target.arch.arch == ZigLLVM_x86)429 g->zig_target.arch.arch == ZigLLVM_x86)
403 {430 {
404 // prevent name mangling431 // prevent llvm name mangling
405 symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name));432 symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name));
406 }433 }
407434
408435
409 TypeTableEntry *fn_type = fn_table_entry->type_entry;436 TypeTableEntry *fn_type = fn_table_entry->type_entry;
410 LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref;437 LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref;
411 if (external_linkage && fn_table_entry->body_node == nullptr) {438 if (fn_table_entry->body_node == nullptr) {
412 LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name));439 LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name));
413 if (existing_llvm_fn) {440 if (existing_llvm_fn) {
414 fn_table_entry->llvm_value = LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0));441 fn_table_entry->llvm_value = LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0));
...@@ -418,6 +445,12 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -418,6 +445,12 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
418 }445 }
419 } else {446 } else {
420 fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type);447 fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type);
448
449 for (size_t i = 1; i < fn_table_entry->export_list.length; i += 1) {
450 FnExport *fn_export = &fn_table_entry->export_list.items[i];
451 LLVMAddAlias(g->module, LLVMTypeOf(fn_table_entry->llvm_value),
452 fn_table_entry->llvm_value, buf_ptr(&fn_export->name));
453 }
421 }454 }
422 fn_table_entry->llvm_name = LLVMGetValueName(fn_table_entry->llvm_value);455 fn_table_entry->llvm_name = LLVMGetValueName(fn_table_entry->llvm_value);
423456
...@@ -445,20 +478,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -445,20 +478,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
445 }478 }
446 }479 }
447480
448 switch (fn_table_entry->linkage) {481 LLVMSetLinkage(fn_table_entry->llvm_value, to_llvm_linkage(linkage));
449 case GlobalLinkageIdInternal:482
450 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMInternalLinkage);483 if (linkage == GlobalLinkageIdInternal) {
451 LLVMSetUnnamedAddr(fn_table_entry->llvm_value, true);484 LLVMSetUnnamedAddr(fn_table_entry->llvm_value, true);
452 break;
453 case GlobalLinkageIdStrong:
454 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMExternalLinkage);
455 break;
456 case GlobalLinkageIdWeak:
457 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakODRLinkage);
458 break;
459 case GlobalLinkageIdLinkOnce:
460 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceODRLinkage);
461 break;
462 }485 }
463486
464 if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdUnreachable) {487 if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdUnreachable) {
...@@ -565,7 +588,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -565,7 +588,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
565 bool is_definition = fn_table_entry->body_node != nullptr;588 bool is_definition = fn_table_entry->body_node != nullptr;
566 unsigned flags = 0;589 unsigned flags = 0;
567 bool is_optimized = g->build_mode != BuildModeDebug;590 bool is_optimized = g->build_mode != BuildModeDebug;
568 bool is_internal_linkage = (fn_table_entry->linkage == GlobalLinkageIdInternal);591 bool is_internal_linkage = (fn_table_entry->body_node != nullptr &&
592 fn_table_entry->export_list.length == 0);
569 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,593 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,
570 get_di_scope(g, scope->parent), buf_ptr(&fn_table_entry->symbol_name), "",594 get_di_scope(g, scope->parent), buf_ptr(&fn_table_entry->symbol_name), "",
571 import->di_file, line_number,595 import->di_file, line_number,
...@@ -3487,8 +3511,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -3487,8 +3511,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
3487 case IrInstructionIdCheckStatementIsVoid:3511 case IrInstructionIdCheckStatementIsVoid:
3488 case IrInstructionIdTypeName:3512 case IrInstructionIdTypeName:
3489 case IrInstructionIdCanImplicitCast:3513 case IrInstructionIdCanImplicitCast:
3490 case IrInstructionIdSetGlobalSection:
3491 case IrInstructionIdSetGlobalLinkage:
3492 case IrInstructionIdDeclRef:3514 case IrInstructionIdDeclRef:
3493 case IrInstructionIdSwitchVar:3515 case IrInstructionIdSwitchVar:
3494 case IrInstructionIdOffsetOf:3516 case IrInstructionIdOffsetOf:
...@@ -3499,6 +3521,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -3499,6 +3521,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
3499 case IrInstructionIdSetAlignStack:3521 case IrInstructionIdSetAlignStack:
3500 case IrInstructionIdArgType:3522 case IrInstructionIdArgType:
3501 case IrInstructionIdTagType:3523 case IrInstructionIdTagType:
3524 case IrInstructionIdExport:
3502 zig_unreachable();3525 zig_unreachable();
3503 case IrInstructionIdReturn:3526 case IrInstructionIdReturn:
3504 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);3527 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
...@@ -4969,8 +4992,6 @@ static void define_builtin_fns(CodeGen *g) {...@@ -4969,8 +4992,6 @@ static void define_builtin_fns(CodeGen *g) {
4969 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int4992 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
4970 create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);4993 create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
4971 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2);4994 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2);
4972 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
4973 create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
4974 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);4995 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
4975 create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2);4996 create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2);
4976 create_builtin_fn(g, BuiltinFnIdBitCast, "bitCast", 2);4997 create_builtin_fn(g, BuiltinFnIdBitCast, "bitCast", 2);
...@@ -4995,6 +5016,8 @@ static void define_builtin_fns(CodeGen *g) {...@@ -4995,6 +5016,8 @@ static void define_builtin_fns(CodeGen *g) {
4995 create_builtin_fn(g, BuiltinFnIdOpaqueType, "OpaqueType", 0);5016 create_builtin_fn(g, BuiltinFnIdOpaqueType, "OpaqueType", 0);
4996 create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1);5017 create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1);
4997 create_builtin_fn(g, BuiltinFnIdArgType, "ArgType", 2);5018 create_builtin_fn(g, BuiltinFnIdArgType, "ArgType", 2);
5019 create_builtin_fn(g, BuiltinFnIdExport, "export", 2);
5020 create_builtin_fn(g, BuiltinFnIdExportWithLinkage, "exportWithLinkage", 3);
4998}5021}
49995022
5000static const char *bool_to_str(bool b) {5023static const char *bool_to_str(bool b) {
...@@ -5433,6 +5456,27 @@ static void gen_root_source(CodeGen *g) {...@@ -5433,6 +5456,27 @@ static void gen_root_source(CodeGen *g) {
5433 assert(g->root_out_name);5456 assert(g->root_out_name);
5434 assert(g->out_type != OutTypeUnknown);5457 assert(g->out_type != OutTypeUnknown);
54355458
5459 {
5460 // Zig has lazy top level definitions. Here we semantically analyze the panic function.
5461 ImportTableEntry *import_with_panic;
5462 if (g->have_pub_panic) {
5463 import_with_panic = g->root_import;
5464 } else {
5465 g->panic_package = create_panic_pkg(g);
5466 import_with_panic = add_special_code(g, g->panic_package, "panic.zig");
5467 }
5468 scan_import(g, import_with_panic);
5469 Tld *panic_tld = find_decl(g, &import_with_panic->decls_scope->base, buf_create_from_str("panic"));
5470 assert(panic_tld != nullptr);
5471 resolve_top_level_decl(g, panic_tld, false, nullptr);
5472 }
5473
5474
5475 if (!g->error_during_imports) {
5476 semantic_analyze(g);
5477 }
5478 report_errors_and_maybe_exit(g);
5479
5436 if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS &&5480 if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS &&
5437 !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup &&5481 !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup &&
5438 ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe))5482 ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe))
...@@ -5442,20 +5486,6 @@ static void gen_root_source(CodeGen *g) {...@@ -5442,20 +5486,6 @@ static void gen_root_source(CodeGen *g) {
5442 if (g->zig_target.os == ZigLLVM_Win32 && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) {5486 if (g->zig_target.os == ZigLLVM_Win32 && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) {
5443 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig");5487 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig");
5444 }5488 }
5445 ImportTableEntry *import_with_panic;
5446 if (g->have_pub_panic) {
5447 import_with_panic = g->root_import;
5448 } else {
5449 g->panic_package = create_panic_pkg(g);
5450 import_with_panic = add_special_code(g, g->panic_package, "panic.zig");
5451 }
5452 // Zig has lazy top level definitions. Here we semantically analyze the panic function.
5453 {
5454 scan_import(g, import_with_panic);
5455 Tld *panic_tld = find_decl(g, &import_with_panic->decls_scope->base, buf_create_from_str("panic"));
5456 assert(panic_tld != nullptr);
5457 resolve_top_level_decl(g, panic_tld, false, nullptr);
5458 }
54595489
5460 if (!g->error_during_imports) {5490 if (!g->error_during_imports) {
5461 semantic_analyze(g);5491 semantic_analyze(g);
...@@ -5682,7 +5712,7 @@ static void gen_h_file(CodeGen *g) {...@@ -5682,7 +5712,7 @@ static void gen_h_file(CodeGen *g) {
5682 for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) {5712 for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) {
5683 FnTableEntry *fn_table_entry = g->fn_defs.at(fn_def_i);5713 FnTableEntry *fn_table_entry = g->fn_defs.at(fn_def_i);
56845714
5685 if (fn_table_entry->linkage == GlobalLinkageIdInternal)5715 if (fn_table_entry->export_list.length == 0)
5686 continue;5716 continue;
56875717
5688 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;5718 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
src/ir.cpp+264-195
...@@ -207,6 +207,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVar *) {...@@ -207,6 +207,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVar *) {
207 return IrInstructionIdDeclVar;207 return IrInstructionIdDeclVar;
208}208}
209209
210static constexpr IrInstructionId ir_instruction_id(IrInstructionExport *) {
211 return IrInstructionIdExport;
212}
213
210static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) {214static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) {
211 return IrInstructionIdLoadPtr;215 return IrInstructionIdLoadPtr;
212}216}
...@@ -523,14 +527,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCanImplicitCast...@@ -523,14 +527,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCanImplicitCast
523 return IrInstructionIdCanImplicitCast;527 return IrInstructionIdCanImplicitCast;
524}528}
525529
526static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalSection *) {
527 return IrInstructionIdSetGlobalSection;
528}
529
530static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalLinkage *) {
531 return IrInstructionIdSetGlobalLinkage;
532}
533
534static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) {530static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) {
535 return IrInstructionIdDeclRef;531 return IrInstructionIdDeclRef;
536}532}
...@@ -1205,6 +1201,24 @@ static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_...@@ -1205,6 +1201,24 @@ static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_
1205 return new_instruction;1201 return new_instruction;
1206}1202}
12071203
1204static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node,
1205 IrInstruction *name, IrInstruction *target, IrInstruction *linkage)
1206{
1207 IrInstructionExport *export_instruction = ir_build_instruction<IrInstructionExport>(
1208 irb, scope, source_node);
1209 export_instruction->base.value.special = ConstValSpecialStatic;
1210 export_instruction->base.value.type = irb->codegen->builtin_types.entry_void;
1211 export_instruction->name = name;
1212 export_instruction->target = target;
1213 export_instruction->linkage = linkage;
1214
1215 ir_ref_instruction(name, irb->current_basic_block);
1216 ir_ref_instruction(target, irb->current_basic_block);
1217 if (linkage) ir_ref_instruction(linkage, irb->current_basic_block);
1218
1219 return &export_instruction->base;
1220}
1221
1208static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) {1222static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) {
1209 IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node);1223 IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node);
1210 instruction->ptr = ptr;1224 instruction->ptr = ptr;
...@@ -2159,32 +2173,6 @@ static IrInstruction *ir_build_can_implicit_cast(IrBuilder *irb, Scope *scope, A...@@ -2159,32 +2173,6 @@ static IrInstruction *ir_build_can_implicit_cast(IrBuilder *irb, Scope *scope, A
2159 return &instruction->base;2173 return &instruction->base;
2160}2174}
21612175
2162static IrInstruction *ir_build_set_global_section(IrBuilder *irb, Scope *scope, AstNode *source_node,
2163 Tld *tld, IrInstruction *value)
2164{
2165 IrInstructionSetGlobalSection *instruction = ir_build_instruction<IrInstructionSetGlobalSection>(
2166 irb, scope, source_node);
2167 instruction->tld = tld;
2168 instruction->value = value;
2169
2170 ir_ref_instruction(value, irb->current_basic_block);
2171
2172 return &instruction->base;
2173}
2174
2175static IrInstruction *ir_build_set_global_linkage(IrBuilder *irb, Scope *scope, AstNode *source_node,
2176 Tld *tld, IrInstruction *value)
2177{
2178 IrInstructionSetGlobalLinkage *instruction = ir_build_instruction<IrInstructionSetGlobalLinkage>(
2179 irb, scope, source_node);
2180 instruction->tld = tld;
2181 instruction->value = value;
2182
2183 ir_ref_instruction(value, irb->current_basic_block);
2184
2185 return &instruction->base;
2186}
2187
2188static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node,2176static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node,
2189 Tld *tld, LVal lval)2177 Tld *tld, LVal lval)
2190{2178{
...@@ -2396,6 +2384,21 @@ static IrInstruction *ir_instruction_declvar_get_dep(IrInstructionDeclVar *instr...@@ -2396,6 +2384,21 @@ static IrInstruction *ir_instruction_declvar_get_dep(IrInstructionDeclVar *instr
2396 return nullptr;2384 return nullptr;
2397}2385}
23982386
2387static IrInstruction *ir_instruction_export_get_dep(IrInstructionExport *instruction, size_t index) {
2388 if (index < 1) return instruction->name;
2389 index -= 1;
2390
2391 if (index < 1) return instruction->target;
2392 index -= 1;
2393
2394 if (instruction->linkage != nullptr) {
2395 if (index < 1) return instruction->linkage;
2396 index -= 1;
2397 }
2398
2399 return nullptr;
2400}
2401
2399static IrInstruction *ir_instruction_loadptr_get_dep(IrInstructionLoadPtr *instruction, size_t index) {2402static IrInstruction *ir_instruction_loadptr_get_dep(IrInstructionLoadPtr *instruction, size_t index) {
2400 switch (index) {2403 switch (index) {
2401 case 0: return instruction->ptr;2404 case 0: return instruction->ptr;
...@@ -2979,20 +2982,6 @@ static IrInstruction *ir_instruction_canimplicitcast_get_dep(IrInstructionCanImp...@@ -2979,20 +2982,6 @@ static IrInstruction *ir_instruction_canimplicitcast_get_dep(IrInstructionCanImp
2979 }2982 }
2980}2983}
29812984
2982static IrInstruction *ir_instruction_setglobalsection_get_dep(IrInstructionSetGlobalSection *instruction, size_t index) {
2983 switch (index) {
2984 case 0: return instruction->value;
2985 default: return nullptr;
2986 }
2987}
2988
2989static IrInstruction *ir_instruction_setgloballinkage_get_dep(IrInstructionSetGlobalLinkage *instruction, size_t index) {
2990 switch (index) {
2991 case 0: return instruction->value;
2992 default: return nullptr;
2993 }
2994}
2995
2996static IrInstruction *ir_instruction_declref_get_dep(IrInstructionDeclRef *instruction, size_t index) {2985static IrInstruction *ir_instruction_declref_get_dep(IrInstructionDeclRef *instruction, size_t index) {
2997 return nullptr;2986 return nullptr;
2998}2987}
...@@ -3106,6 +3095,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t...@@ -3106,6 +3095,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
3106 return ir_instruction_binop_get_dep((IrInstructionBinOp *) instruction, index);3095 return ir_instruction_binop_get_dep((IrInstructionBinOp *) instruction, index);
3107 case IrInstructionIdDeclVar:3096 case IrInstructionIdDeclVar:
3108 return ir_instruction_declvar_get_dep((IrInstructionDeclVar *) instruction, index);3097 return ir_instruction_declvar_get_dep((IrInstructionDeclVar *) instruction, index);
3098 case IrInstructionIdExport:
3099 return ir_instruction_export_get_dep((IrInstructionExport *) instruction, index);
3109 case IrInstructionIdLoadPtr:3100 case IrInstructionIdLoadPtr:
3110 return ir_instruction_loadptr_get_dep((IrInstructionLoadPtr *) instruction, index);3101 return ir_instruction_loadptr_get_dep((IrInstructionLoadPtr *) instruction, index);
3111 case IrInstructionIdStorePtr:3102 case IrInstructionIdStorePtr:
...@@ -3264,10 +3255,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t...@@ -3264,10 +3255,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
3264 return ir_instruction_typename_get_dep((IrInstructionTypeName *) instruction, index);3255 return ir_instruction_typename_get_dep((IrInstructionTypeName *) instruction, index);
3265 case IrInstructionIdCanImplicitCast:3256 case IrInstructionIdCanImplicitCast:
3266 return ir_instruction_canimplicitcast_get_dep((IrInstructionCanImplicitCast *) instruction, index);3257 return ir_instruction_canimplicitcast_get_dep((IrInstructionCanImplicitCast *) instruction, index);
3267 case IrInstructionIdSetGlobalSection:
3268 return ir_instruction_setglobalsection_get_dep((IrInstructionSetGlobalSection *) instruction, index);
3269 case IrInstructionIdSetGlobalLinkage:
3270 return ir_instruction_setgloballinkage_get_dep((IrInstructionSetGlobalLinkage *) instruction, index);
3271 case IrInstructionIdDeclRef:3258 case IrInstructionIdDeclRef:
3272 return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index);3259 return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index);
3273 case IrInstructionIdPanic:3260 case IrInstructionIdPanic:
...@@ -4528,39 +4515,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4528,39 +4515,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
45284515
4529 return ir_build_can_implicit_cast(irb, scope, node, arg0_value, arg1_value);4516 return ir_build_can_implicit_cast(irb, scope, node, arg0_value, arg1_value);
4530 }4517 }
4531 case BuiltinFnIdSetGlobalSection:
4532 case BuiltinFnIdSetGlobalLinkage:
4533 {
4534 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4535 if (arg0_node->type != NodeTypeSymbol) {
4536 add_node_error(irb->codegen, arg0_node, buf_sprintf("expected identifier"));
4537 return irb->codegen->invalid_instruction;
4538 }
4539 Buf *variable_name = arg0_node->data.symbol_expr.symbol;
4540 Tld *tld = find_decl(irb->codegen, scope, variable_name);
4541 if (!tld) {
4542 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'",
4543 buf_ptr(variable_name)));
4544 return irb->codegen->invalid_instruction;
4545 }
4546 if (tld->id != TldIdVar && tld->id != TldIdFn) {
4547 add_node_error(irb->codegen, node, buf_sprintf("'%s' must be global variable or function",
4548 buf_ptr(variable_name)));
4549 return irb->codegen->invalid_instruction;
4550 }
4551 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4552 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4553 if (arg1_value == irb->codegen->invalid_instruction)
4554 return arg1_value;
4555
4556 if (builtin_fn->id == BuiltinFnIdSetGlobalSection) {
4557 return ir_build_set_global_section(irb, scope, node, tld, arg1_value);
4558 } else if (builtin_fn->id == BuiltinFnIdSetGlobalLinkage) {
4559 return ir_build_set_global_linkage(irb, scope, node, tld, arg1_value);
4560 } else {
4561 zig_unreachable();
4562 }
4563 }
4564 case BuiltinFnIdPanic:4518 case BuiltinFnIdPanic:
4565 {4519 {
4566 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);4520 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -4784,6 +4738,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4784,6 +4738,31 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
47844738
4785 return ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);4739 return ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);
4786 }4740 }
4741 case BuiltinFnIdExport:
4742 case BuiltinFnIdExportWithLinkage:
4743 {
4744 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4745 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4746 if (arg0_value == irb->codegen->invalid_instruction)
4747 return arg0_value;
4748
4749 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4750 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4751 if (arg1_value == irb->codegen->invalid_instruction)
4752 return arg1_value;
4753
4754 IrInstruction *arg2_value;
4755 if (builtin_fn->id == BuiltinFnIdExportWithLinkage) {
4756 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4757 arg2_value = ir_gen_node(irb, arg2_node, scope);
4758 if (arg2_value == irb->codegen->invalid_instruction)
4759 return arg2_value;
4760 } else {
4761 arg2_value = nullptr;
4762 }
4763
4764 return ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value);
4765 }
4787 }4766 }
4788 zig_unreachable();4767 zig_unreachable();
4789}4768}
...@@ -5106,6 +5085,11 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -5106,6 +5085,11 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
5106 return align_value;5085 return align_value;
5107 }5086 }
51085087
5088 if (variable_declaration->section_expr != nullptr) {
5089 add_node_error(irb->codegen, variable_declaration->section_expr,
5090 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol)));
5091 }
5092
5109 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope);5093 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope);
5110 if (init_value == irb->codegen->invalid_instruction)5094 if (init_value == irb->codegen->invalid_instruction)
5111 return init_value;5095 return init_value;
...@@ -6355,6 +6339,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -6355,6 +6339,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
6355 case NodeTypeSwitchRange:6339 case NodeTypeSwitchRange:
6356 case NodeTypeStructField:6340 case NodeTypeStructField:
6357 case NodeTypeLabel:6341 case NodeTypeLabel:
6342 case NodeTypeFnDef:
6343 case NodeTypeFnDecl:
6344 case NodeTypeErrorValueDecl:
6345 case NodeTypeTestDecl:
6358 zig_unreachable();6346 zig_unreachable();
6359 case NodeTypeBlock:6347 case NodeTypeBlock:
6360 return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval);6348 return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval);
...@@ -6436,14 +6424,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop...@@ -6436,14 +6424,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
6436 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval);6424 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval);
6437 case NodeTypeFnProto:6425 case NodeTypeFnProto:
6438 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval);6426 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval);
6439 case NodeTypeFnDef:
6440 zig_panic("TODO IR gen NodeTypeFnDef");
6441 case NodeTypeFnDecl:
6442 zig_panic("TODO IR gen NodeTypeFnDecl");
6443 case NodeTypeErrorValueDecl:
6444 zig_panic("TODO IR gen NodeTypeErrorValueDecl");
6445 case NodeTypeTestDecl:
6446 zig_panic("TODO IR gen NodeTypeTestDecl");
6447 }6427 }
6448 zig_unreachable();6428 zig_unreachable();
6449}6429}
...@@ -10481,6 +10461,194 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -10481,6 +10461,194 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
10481 return ira->codegen->builtin_types.entry_void;10461 return ira->codegen->builtin_types.entry_void;
10482}10462}
1048310463
10464static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) {
10465 IrInstruction *name = instruction->name->other;
10466 Buf *symbol_name = ir_resolve_str(ira, name);
10467 if (symbol_name == nullptr) {
10468 return ira->codegen->builtin_types.entry_invalid;
10469 }
10470
10471 IrInstruction *target = instruction->target->other;
10472 if (type_is_invalid(target->value.type)) {
10473 return ira->codegen->builtin_types.entry_invalid;
10474 }
10475
10476 GlobalLinkageId global_linkage_id = GlobalLinkageIdStrong;
10477 if (instruction->linkage != nullptr) {
10478 IrInstruction *linkage_value = instruction->linkage->other;
10479 if (!ir_resolve_global_linkage(ira, linkage_value, &global_linkage_id)) {
10480 return ira->codegen->builtin_types.entry_invalid;
10481 }
10482 }
10483
10484 auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, instruction->base.source_node);
10485 if (entry) {
10486 AstNode *other_export_node = entry->value;
10487 ErrorMsg *msg = ir_add_error(ira, &instruction->base,
10488 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name)));
10489 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here"));
10490 }
10491
10492 switch (target->value.type->id) {
10493 case TypeTableEntryIdInvalid:
10494 case TypeTableEntryIdVar:
10495 case TypeTableEntryIdUnreachable:
10496 zig_unreachable();
10497 case TypeTableEntryIdFn: {
10498 FnTableEntry *fn_entry = target->value.data.x_fn.fn_entry;
10499 CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc;
10500 switch (cc) {
10501 case CallingConventionUnspecified: {
10502 ErrorMsg *msg = ir_add_error(ira, target,
10503 buf_sprintf("exported function must specify calling convention"));
10504 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here"));
10505 } break;
10506 case CallingConventionC:
10507 if (buf_eql_str(symbol_name, "main") && ira->codegen->libc_link_lib != nullptr) {
10508 ira->codegen->have_c_main = true;
10509 ira->codegen->windows_subsystem_windows = false;
10510 ira->codegen->windows_subsystem_console = true;
10511 } else if (buf_eql_str(symbol_name, "WinMain") &&
10512 ira->codegen->zig_target.os == ZigLLVM_Win32)
10513 {
10514 ira->codegen->have_winmain = true;
10515 ira->codegen->windows_subsystem_windows = true;
10516 ira->codegen->windows_subsystem_console = false;
10517 } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&
10518 ira->codegen->zig_target.os == ZigLLVM_Win32)
10519 {
10520 ira->codegen->have_winmain_crt_startup = true;
10521 } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") &&
10522 ira->codegen->zig_target.os == ZigLLVM_Win32)
10523 {
10524 ira->codegen->have_dllmain_crt_startup = true;
10525 }
10526 // fallthrough
10527 case CallingConventionNaked:
10528 case CallingConventionCold:
10529 case CallingConventionStdcall: {
10530 FnExport *fn_export = fn_entry->export_list.add_one();
10531 memset(fn_export, 0, sizeof(FnExport));
10532 buf_init_from_buf(&fn_export->name, symbol_name);
10533 fn_export->linkage = global_linkage_id;
10534 fn_export->source_node = instruction->base.source_node;
10535 } break;
10536 }
10537 } break;
10538 case TypeTableEntryIdStruct:
10539 if (is_slice(target->value.type)) {
10540 ir_add_error(ira, target,
10541 buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value.type->name)));
10542 } else if (target->value.type->data.structure.layout != ContainerLayoutExtern) {
10543 ErrorMsg *msg = ir_add_error(ira, target,
10544 buf_sprintf("exported struct value must be declared extern"));
10545 add_error_note(ira->codegen, msg, target->value.type->data.structure.decl_node, buf_sprintf("declared here"));
10546 }
10547 break;
10548 case TypeTableEntryIdUnion:
10549 if (target->value.type->data.unionation.layout != ContainerLayoutExtern) {
10550 ErrorMsg *msg = ir_add_error(ira, target,
10551 buf_sprintf("exported union value must be declared extern"));
10552 add_error_note(ira->codegen, msg, target->value.type->data.unionation.decl_node, buf_sprintf("declared here"));
10553 }
10554 break;
10555 case TypeTableEntryIdEnum:
10556 if (target->value.type->data.enumeration.layout != ContainerLayoutExtern) {
10557 ErrorMsg *msg = ir_add_error(ira, target,
10558 buf_sprintf("exported enum value must be declared extern"));
10559 add_error_note(ira->codegen, msg, target->value.type->data.enumeration.decl_node, buf_sprintf("declared here"));
10560 }
10561 break;
10562 case TypeTableEntryIdMetaType: {
10563 TypeTableEntry *type_value = target->value.data.x_type;
10564 switch (type_value->id) {
10565 case TypeTableEntryIdInvalid:
10566 case TypeTableEntryIdVar:
10567 zig_unreachable();
10568 case TypeTableEntryIdStruct:
10569 if (is_slice(type_value)) {
10570 ir_add_error(ira, target,
10571 buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name)));
10572 } else if (type_value->data.structure.layout != ContainerLayoutExtern) {
10573 ErrorMsg *msg = ir_add_error(ira, target,
10574 buf_sprintf("exported struct must be declared extern"));
10575 add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here"));
10576 }
10577 break;
10578 case TypeTableEntryIdUnion:
10579 if (type_value->data.unionation.layout != ContainerLayoutExtern) {
10580 ErrorMsg *msg = ir_add_error(ira, target,
10581 buf_sprintf("exported union must be declared extern"));
10582 add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here"));
10583 }
10584 break;
10585 case TypeTableEntryIdEnum:
10586 if (type_value->data.enumeration.layout != ContainerLayoutExtern) {
10587 ErrorMsg *msg = ir_add_error(ira, target,
10588 buf_sprintf("exported enum must be declared extern"));
10589 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here"));
10590 }
10591 break;
10592 case TypeTableEntryIdFn: {
10593 if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) {
10594 ir_add_error(ira, target,
10595 buf_sprintf("exported function type must specify calling convention"));
10596 }
10597 } break;
10598 case TypeTableEntryIdInt:
10599 case TypeTableEntryIdFloat:
10600 case TypeTableEntryIdPointer:
10601 case TypeTableEntryIdArray:
10602 case TypeTableEntryIdBool:
10603 break;
10604 case TypeTableEntryIdMetaType:
10605 case TypeTableEntryIdVoid:
10606 case TypeTableEntryIdUnreachable:
10607 case TypeTableEntryIdNumLitFloat:
10608 case TypeTableEntryIdNumLitInt:
10609 case TypeTableEntryIdUndefLit:
10610 case TypeTableEntryIdNullLit:
10611 case TypeTableEntryIdMaybe:
10612 case TypeTableEntryIdErrorUnion:
10613 case TypeTableEntryIdPureError:
10614 case TypeTableEntryIdNamespace:
10615 case TypeTableEntryIdBlock:
10616 case TypeTableEntryIdBoundFn:
10617 case TypeTableEntryIdArgTuple:
10618 case TypeTableEntryIdOpaque:
10619 ir_add_error(ira, target,
10620 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name)));
10621 break;
10622 }
10623 } break;
10624 case TypeTableEntryIdVoid:
10625 case TypeTableEntryIdBool:
10626 case TypeTableEntryIdInt:
10627 case TypeTableEntryIdFloat:
10628 case TypeTableEntryIdPointer:
10629 case TypeTableEntryIdArray:
10630 case TypeTableEntryIdNumLitFloat:
10631 case TypeTableEntryIdNumLitInt:
10632 case TypeTableEntryIdUndefLit:
10633 case TypeTableEntryIdNullLit:
10634 case TypeTableEntryIdMaybe:
10635 case TypeTableEntryIdErrorUnion:
10636 case TypeTableEntryIdPureError:
10637 zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name));
10638 case TypeTableEntryIdNamespace:
10639 case TypeTableEntryIdBlock:
10640 case TypeTableEntryIdBoundFn:
10641 case TypeTableEntryIdArgTuple:
10642 case TypeTableEntryIdOpaque:
10643 ir_add_error(ira, target,
10644 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name)));
10645 break;
10646 }
10647
10648 ir_build_const_from(ira, &instruction->base);
10649 return ira->codegen->builtin_types.entry_void;
10650}
10651
10484static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,10652static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,
10485 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)10653 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)
10486{10654{
...@@ -12399,102 +12567,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,...@@ -12399,102 +12567,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,
12399 return ira->codegen->builtin_types.entry_type;12567 return ira->codegen->builtin_types.entry_type;
12400}12568}
1240112569
12402static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira,
12403 IrInstructionSetGlobalSection *instruction)
12404{
12405 Tld *tld = instruction->tld;
12406 IrInstruction *section_value = instruction->value->other;
12407
12408 resolve_top_level_decl(ira->codegen, tld, true, instruction->base.source_node);
12409 if (tld->resolution == TldResolutionInvalid)
12410 return ira->codegen->builtin_types.entry_invalid;
12411
12412 Buf *section_name = ir_resolve_str(ira, section_value);
12413 if (!section_name)
12414 return ira->codegen->builtin_types.entry_invalid;
12415
12416 AstNode **set_global_section_node;
12417 Buf **section_name_ptr;
12418 if (tld->id == TldIdVar) {
12419 TldVar *tld_var = (TldVar *)tld;
12420 set_global_section_node = &tld_var->set_global_section_node;
12421 section_name_ptr = &tld_var->section_name;
12422
12423 if (tld_var->var->linkage == VarLinkageExternal) {
12424 ErrorMsg *msg = ir_add_error(ira, &instruction->base,
12425 buf_sprintf("cannot set section of external variable '%s'", buf_ptr(&tld_var->var->name)));
12426 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here"));
12427 return ira->codegen->builtin_types.entry_invalid;
12428 }
12429 } else if (tld->id == TldIdFn) {
12430 TldFn *tld_fn = (TldFn *)tld;
12431 FnTableEntry *fn_entry = tld_fn->fn_entry;
12432 set_global_section_node = &fn_entry->set_global_section_node;
12433 section_name_ptr = &fn_entry->section_name;
12434
12435 if (fn_entry->def_scope == nullptr) {
12436 ErrorMsg *msg = ir_add_error(ira, &instruction->base,
12437 buf_sprintf("cannot set section of external function '%s'", buf_ptr(&fn_entry->symbol_name)));
12438 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here"));
12439 return ira->codegen->builtin_types.entry_invalid;
12440 }
12441 } else {
12442 // error is caught in pass1 IR gen
12443 zig_unreachable();
12444 }
12445
12446 AstNode *source_node = instruction->base.source_node;
12447 if (*set_global_section_node) {
12448 ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("section set twice"));
12449 add_error_note(ira->codegen, msg, *set_global_section_node, buf_sprintf("first set here"));
12450 return ira->codegen->builtin_types.entry_invalid;
12451 }
12452 *set_global_section_node = source_node;
12453 *section_name_ptr = section_name;
12454
12455 ir_build_const_from(ira, &instruction->base);
12456 return ira->codegen->builtin_types.entry_void;
12457}
12458
12459static TypeTableEntry *ir_analyze_instruction_set_global_linkage(IrAnalyze *ira,
12460 IrInstructionSetGlobalLinkage *instruction)
12461{
12462 Tld *tld = instruction->tld;
12463 IrInstruction *linkage_value = instruction->value->other;
12464
12465 GlobalLinkageId linkage_scalar;
12466 if (!ir_resolve_global_linkage(ira, linkage_value, &linkage_scalar))
12467 return ira->codegen->builtin_types.entry_invalid;
12468
12469 AstNode **set_global_linkage_node;
12470 GlobalLinkageId *dest_linkage_ptr;
12471 if (tld->id == TldIdVar) {
12472 TldVar *tld_var = (TldVar *)tld;
12473 set_global_linkage_node = &tld_var->set_global_linkage_node;
12474 dest_linkage_ptr = &tld_var->linkage;
12475 } else if (tld->id == TldIdFn) {
12476 TldFn *tld_fn = (TldFn *)tld;
12477 FnTableEntry *fn_entry = tld_fn->fn_entry;
12478 set_global_linkage_node = &fn_entry->set_global_linkage_node;
12479 dest_linkage_ptr = &fn_entry->linkage;
12480 } else {
12481 // error is caught in pass1 IR gen
12482 zig_unreachable();
12483 }
12484
12485 AstNode *source_node = instruction->base.source_node;
12486 if (*set_global_linkage_node) {
12487 ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("linkage set twice"));
12488 add_error_note(ira->codegen, msg, *set_global_linkage_node, buf_sprintf("first set here"));
12489 return ira->codegen->builtin_types.entry_invalid;
12490 }
12491 *set_global_linkage_node = source_node;
12492 *dest_linkage_ptr = linkage_scalar;
12493
12494 ir_build_const_from(ira, &instruction->base);
12495 return ira->codegen->builtin_types.entry_void;
12496}
12497
12498static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,12570static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
12499 IrInstructionSetDebugSafety *set_debug_safety_instruction)12571 IrInstructionSetDebugSafety *set_debug_safety_instruction)
12500{12572{
...@@ -16165,10 +16237,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -16165,10 +16237,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
16165 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);16237 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);
16166 case IrInstructionIdPtrTypeChild:16238 case IrInstructionIdPtrTypeChild:
16167 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);16239 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);
16168 case IrInstructionIdSetGlobalSection:
16169 return ir_analyze_instruction_set_global_section(ira, (IrInstructionSetGlobalSection *)instruction);
16170 case IrInstructionIdSetGlobalLinkage:
16171 return ir_analyze_instruction_set_global_linkage(ira, (IrInstructionSetGlobalLinkage *)instruction);
16172 case IrInstructionIdSetDebugSafety:16240 case IrInstructionIdSetDebugSafety:
16173 return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);16241 return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);
16174 case IrInstructionIdSetFloatMode:16242 case IrInstructionIdSetFloatMode:
...@@ -16311,6 +16379,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -16311,6 +16379,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
16311 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction);16379 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction);
16312 case IrInstructionIdTagType:16380 case IrInstructionIdTagType:
16313 return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction);16381 return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction);
16382 case IrInstructionIdExport:
16383 return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction);
16314 }16384 }
16315 zig_unreachable();16385 zig_unreachable();
16316}16386}
...@@ -16418,12 +16488,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -16418,12 +16488,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {
16418 case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free16488 case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free
16419 case IrInstructionIdCheckSwitchProngs:16489 case IrInstructionIdCheckSwitchProngs:
16420 case IrInstructionIdCheckStatementIsVoid:16490 case IrInstructionIdCheckStatementIsVoid:
16421 case IrInstructionIdSetGlobalSection:
16422 case IrInstructionIdSetGlobalLinkage:
16423 case IrInstructionIdPanic:16491 case IrInstructionIdPanic:
16424 case IrInstructionIdSetEvalBranchQuota:16492 case IrInstructionIdSetEvalBranchQuota:
16425 case IrInstructionIdPtrTypeOf:16493 case IrInstructionIdPtrTypeOf:
16426 case IrInstructionIdSetAlignStack:16494 case IrInstructionIdSetAlignStack:
16495 case IrInstructionIdExport:
16427 return true;16496 return true;
16428 case IrInstructionIdPhi:16497 case IrInstructionIdPhi:
16429 case IrInstructionIdUnOp:16498 case IrInstructionIdUnOp:
src/ir_print.cpp+21-19
...@@ -899,19 +899,6 @@ static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instructi...@@ -899,19 +899,6 @@ static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instructi
899 ir_print_other_instruction(irp, instruction->child_type);899 ir_print_other_instruction(irp, instruction->child_type);
900}900}
901901
902static void ir_print_set_global_section(IrPrint *irp, IrInstructionSetGlobalSection *instruction) {
903 fprintf(irp->f, "@setGlobalSection(%s,", buf_ptr(instruction->tld->name));
904 ir_print_other_instruction(irp, instruction->value);
905 fprintf(irp->f, ")");
906}
907
908static void ir_print_set_global_linkage(IrPrint *irp, IrInstructionSetGlobalLinkage *instruction) {
909 fprintf(irp->f, "@setGlobalLinkage(%s,", buf_ptr(instruction->tld->name));
910 ir_print_other_instruction(irp, instruction->value);
911 fprintf(irp->f, ")");
912}
913
914
915static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) {902static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) {
916 const char *ptr_str = instruction->lval.is_ptr ? "ptr " : "";903 const char *ptr_str = instruction->lval.is_ptr ? "ptr " : "";
917 const char *const_str = instruction->lval.is_const ? "const " : "";904 const char *const_str = instruction->lval.is_const ? "const " : "";
...@@ -991,6 +978,24 @@ static void ir_print_enum_tag_type(IrPrint *irp, IrInstructionTagType *instructi...@@ -991,6 +978,24 @@ static void ir_print_enum_tag_type(IrPrint *irp, IrInstructionTagType *instructi
991 fprintf(irp->f, ")");978 fprintf(irp->f, ")");
992}979}
993980
981static void ir_print_export(IrPrint *irp, IrInstructionExport *instruction) {
982 if (instruction->linkage == nullptr) {
983 fprintf(irp->f, "@export(");
984 ir_print_other_instruction(irp, instruction->name);
985 fprintf(irp->f, ",");
986 ir_print_other_instruction(irp, instruction->target);
987 fprintf(irp->f, ")");
988 } else {
989 fprintf(irp->f, "@exportWithLinkage(");
990 ir_print_other_instruction(irp, instruction->name);
991 fprintf(irp->f, ",");
992 ir_print_other_instruction(irp, instruction->target);
993 fprintf(irp->f, ",");
994 ir_print_other_instruction(irp, instruction->linkage);
995 fprintf(irp->f, ")");
996 }
997}
998
994999
995static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {1000static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
996 ir_print_prefix(irp, instruction);1001 ir_print_prefix(irp, instruction);
...@@ -1267,12 +1272,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1267,12 +1272,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1267 case IrInstructionIdPtrTypeOf:1272 case IrInstructionIdPtrTypeOf:
1268 ir_print_ptr_type_of(irp, (IrInstructionPtrTypeOf *)instruction);1273 ir_print_ptr_type_of(irp, (IrInstructionPtrTypeOf *)instruction);
1269 break;1274 break;
1270 case IrInstructionIdSetGlobalSection:
1271 ir_print_set_global_section(irp, (IrInstructionSetGlobalSection *)instruction);
1272 break;
1273 case IrInstructionIdSetGlobalLinkage:
1274 ir_print_set_global_linkage(irp, (IrInstructionSetGlobalLinkage *)instruction);
1275 break;
1276 case IrInstructionIdDeclRef:1275 case IrInstructionIdDeclRef:
1277 ir_print_decl_ref(irp, (IrInstructionDeclRef *)instruction);1276 ir_print_decl_ref(irp, (IrInstructionDeclRef *)instruction);
1278 break;1277 break;
...@@ -1306,6 +1305,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1306,6 +1305,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1306 case IrInstructionIdTagType:1305 case IrInstructionIdTagType:
1307 ir_print_enum_tag_type(irp, (IrInstructionTagType *)instruction);1306 ir_print_enum_tag_type(irp, (IrInstructionTagType *)instruction);
1308 break;1307 break;
1308 case IrInstructionIdExport:
1309 ir_print_export(irp, (IrInstructionExport *)instruction);
1310 break;
1309 }1311 }
1310 fprintf(irp->f, "\n");1312 fprintf(irp->f, "\n");
1311}1313}
src/parser.cpp+20-8
...@@ -1600,6 +1600,14 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to...@@ -1600,6 +1600,14 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
1600 next_token = &pc->tokens->at(*token_index);1600 next_token = &pc->tokens->at(*token_index);
1601 }1601 }
16021602
1603 if (next_token->id == TokenIdKeywordSection) {
1604 *token_index += 1;
1605 ast_eat_token(pc, token_index, TokenIdLParen);
1606 node->data.variable_declaration.section_expr = ast_parse_expression(pc, token_index, true);
1607 ast_eat_token(pc, token_index, TokenIdRParen);
1608 next_token = &pc->tokens->at(*token_index);
1609 }
1610
1603 if (next_token->id == TokenIdEq) {1611 if (next_token->id == TokenIdEq) {
1604 *token_index += 1;1612 *token_index += 1;
1605 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);1613 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
...@@ -2144,7 +2152,7 @@ static bool statement_terminates_without_semicolon(AstNode *node) {...@@ -2144,7 +2152,7 @@ static bool statement_terminates_without_semicolon(AstNode *node) {
21442152
2145/*2153/*
2146Block = "{" many(Statement) option(Expression) "}"2154Block = "{" many(Statement) option(Expression) "}"
2147Statement = Label | VariableDeclaration ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"2155Statement = Label | VariableDeclaration ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";" | ExportDecl
2148*/2156*/
2149static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mandatory) {2157static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mandatory) {
2150 Token *last_token = &pc->tokens->at(*token_index);2158 Token *last_token = &pc->tokens->at(*token_index);
...@@ -2205,7 +2213,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand...@@ -2205,7 +2213,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
2205}2213}
22062214
2207/*2215/*
2208FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("->" TypeExpr)2216FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("-&gt;" TypeExpr)
2209*/2217*/
2210static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {2218static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
2211 Token *first_token = &pc->tokens->at(*token_index);2219 Token *first_token = &pc->tokens->at(*token_index);
...@@ -2259,6 +2267,14 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m...@@ -2259,6 +2267,14 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
2259 ast_eat_token(pc, token_index, TokenIdRParen);2267 ast_eat_token(pc, token_index, TokenIdRParen);
2260 next_token = &pc->tokens->at(*token_index);2268 next_token = &pc->tokens->at(*token_index);
2261 }2269 }
2270 if (next_token->id == TokenIdKeywordSection) {
2271 *token_index += 1;
2272 ast_eat_token(pc, token_index, TokenIdLParen);
2273
2274 node->data.fn_proto.section_expr = ast_parse_expression(pc, token_index, true);
2275 ast_eat_token(pc, token_index, TokenIdRParen);
2276 next_token = &pc->tokens->at(*token_index);
2277 }
2262 if (next_token->id == TokenIdArrow) {2278 if (next_token->id == TokenIdArrow) {
2263 *token_index += 1;2279 *token_index += 1;
2264 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, false);2280 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, false);
...@@ -2447,9 +2463,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,...@@ -2447,9 +2463,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
2447 if (visib_tok->id == TokenIdKeywordPub) {2463 if (visib_tok->id == TokenIdKeywordPub) {
2448 *token_index += 1;2464 *token_index += 1;
2449 visib_mod = VisibModPub;2465 visib_mod = VisibModPub;
2450 } else if (visib_tok->id == TokenIdKeywordExport) {
2451 *token_index += 1;
2452 visib_mod = VisibModExport;
2453 } else {2466 } else {
2454 visib_mod = VisibModPrivate;2467 visib_mod = VisibModPrivate;
2455 }2468 }
...@@ -2580,9 +2593,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig...@@ -2580,9 +2593,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig
2580 if (visib_tok->id == TokenIdKeywordPub) {2593 if (visib_tok->id == TokenIdKeywordPub) {
2581 *token_index += 1;2594 *token_index += 1;
2582 visib_mod = VisibModPub;2595 visib_mod = VisibModPub;
2583 } else if (visib_tok->id == TokenIdKeywordExport) {
2584 *token_index += 1;
2585 visib_mod = VisibModExport;
2586 } else {2596 } else {
2587 visib_mod = VisibModPrivate;2597 visib_mod = VisibModPrivate;
2588 }2598 }
...@@ -2669,6 +2679,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2669,6 +2679,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2669 visit_field(&node->data.fn_proto.return_type, visit, context);2679 visit_field(&node->data.fn_proto.return_type, visit, context);
2670 visit_node_list(&node->data.fn_proto.params, visit, context);2680 visit_node_list(&node->data.fn_proto.params, visit, context);
2671 visit_field(&node->data.fn_proto.align_expr, visit, context);2681 visit_field(&node->data.fn_proto.align_expr, visit, context);
2682 visit_field(&node->data.fn_proto.section_expr, visit, context);
2672 break;2683 break;
2673 case NodeTypeFnDef:2684 case NodeTypeFnDef:
2674 visit_field(&node->data.fn_def.fn_proto, visit, context);2685 visit_field(&node->data.fn_def.fn_proto, visit, context);
...@@ -2696,6 +2707,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2696,6 +2707,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2696 visit_field(&node->data.variable_declaration.type, visit, context);2707 visit_field(&node->data.variable_declaration.type, visit, context);
2697 visit_field(&node->data.variable_declaration.expr, visit, context);2708 visit_field(&node->data.variable_declaration.expr, visit, context);
2698 visit_field(&node->data.variable_declaration.align_expr, visit, context);2709 visit_field(&node->data.variable_declaration.align_expr, visit, context);
2710 visit_field(&node->data.variable_declaration.section_expr, visit, context);
2699 break;2711 break;
2700 case NodeTypeErrorValueDecl:2712 case NodeTypeErrorValueDecl:
2701 // none2713 // none
src/tokenizer.cpp+2-2
...@@ -119,7 +119,6 @@ static const struct ZigKeyword zig_keywords[] = {...@@ -119,7 +119,6 @@ static const struct ZigKeyword zig_keywords[] = {
119 {"else", TokenIdKeywordElse},119 {"else", TokenIdKeywordElse},
120 {"enum", TokenIdKeywordEnum},120 {"enum", TokenIdKeywordEnum},
121 {"error", TokenIdKeywordError},121 {"error", TokenIdKeywordError},
122 {"export", TokenIdKeywordExport},
123 {"extern", TokenIdKeywordExtern},122 {"extern", TokenIdKeywordExtern},
124 {"false", TokenIdKeywordFalse},123 {"false", TokenIdKeywordFalse},
125 {"fn", TokenIdKeywordFn},124 {"fn", TokenIdKeywordFn},
...@@ -134,6 +133,7 @@ static const struct ZigKeyword zig_keywords[] = {...@@ -134,6 +133,7 @@ static const struct ZigKeyword zig_keywords[] = {
134 {"packed", TokenIdKeywordPacked},133 {"packed", TokenIdKeywordPacked},
135 {"pub", TokenIdKeywordPub},134 {"pub", TokenIdKeywordPub},
136 {"return", TokenIdKeywordReturn},135 {"return", TokenIdKeywordReturn},
136 {"section", TokenIdKeywordSection},
137 {"stdcallcc", TokenIdKeywordStdcallCC},137 {"stdcallcc", TokenIdKeywordStdcallCC},
138 {"struct", TokenIdKeywordStruct},138 {"struct", TokenIdKeywordStruct},
139 {"switch", TokenIdKeywordSwitch},139 {"switch", TokenIdKeywordSwitch},
...@@ -1518,7 +1518,6 @@ const char * token_name(TokenId id) {...@@ -1518,7 +1518,6 @@ const char * token_name(TokenId id) {
1518 case TokenIdKeywordElse: return "else";1518 case TokenIdKeywordElse: return "else";
1519 case TokenIdKeywordEnum: return "enum";1519 case TokenIdKeywordEnum: return "enum";
1520 case TokenIdKeywordError: return "error";1520 case TokenIdKeywordError: return "error";
1521 case TokenIdKeywordExport: return "export";
1522 case TokenIdKeywordExtern: return "extern";1521 case TokenIdKeywordExtern: return "extern";
1523 case TokenIdKeywordFalse: return "false";1522 case TokenIdKeywordFalse: return "false";
1524 case TokenIdKeywordFn: return "fn";1523 case TokenIdKeywordFn: return "fn";
...@@ -1533,6 +1532,7 @@ const char * token_name(TokenId id) {...@@ -1533,6 +1532,7 @@ const char * token_name(TokenId id) {
1533 case TokenIdKeywordPacked: return "packed";1532 case TokenIdKeywordPacked: return "packed";
1534 case TokenIdKeywordPub: return "pub";1533 case TokenIdKeywordPub: return "pub";
1535 case TokenIdKeywordReturn: return "return";1534 case TokenIdKeywordReturn: return "return";
1535 case TokenIdKeywordSection: return "section";
1536 case TokenIdKeywordStdcallCC: return "stdcallcc";1536 case TokenIdKeywordStdcallCC: return "stdcallcc";
1537 case TokenIdKeywordStruct: return "struct";1537 case TokenIdKeywordStruct: return "struct";
1538 case TokenIdKeywordSwitch: return "switch";1538 case TokenIdKeywordSwitch: return "switch";
src/tokenizer.hpp+1-1
...@@ -47,6 +47,7 @@ enum TokenId {...@@ -47,6 +47,7 @@ enum TokenId {
47 TokenIdFloatLiteral,47 TokenIdFloatLiteral,
48 TokenIdIntLiteral,48 TokenIdIntLiteral,
49 TokenIdKeywordAlign,49 TokenIdKeywordAlign,
50 TokenIdKeywordSection,
50 TokenIdKeywordAnd,51 TokenIdKeywordAnd,
51 TokenIdKeywordAsm,52 TokenIdKeywordAsm,
52 TokenIdKeywordBreak,53 TokenIdKeywordBreak,
...@@ -58,7 +59,6 @@ enum TokenId {...@@ -58,7 +59,6 @@ enum TokenId {
58 TokenIdKeywordElse,59 TokenIdKeywordElse,
59 TokenIdKeywordEnum,60 TokenIdKeywordEnum,
60 TokenIdKeywordError,61 TokenIdKeywordError,
61 TokenIdKeywordExport,
62 TokenIdKeywordExtern,62 TokenIdKeywordExtern,
63 TokenIdKeywordFalse,63 TokenIdKeywordFalse,
64 TokenIdKeywordFn,64 TokenIdKeywordFn,
src/translate_c.cpp+2-4
...@@ -73,7 +73,6 @@ struct Context {...@@ -73,7 +73,6 @@ struct Context {
73 ImportTableEntry *import;73 ImportTableEntry *import;
74 ZigList<ErrorMsg *> *errors;74 ZigList<ErrorMsg *> *errors;
75 VisibMod visib_mod;75 VisibMod visib_mod;
76 VisibMod export_visib_mod;
77 AstNode *root;76 AstNode *root;
78 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;77 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
79 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;78 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
...@@ -3251,7 +3250,8 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -3251,7 +3250,8 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
32513250
3252 StorageClass sc = fn_decl->getStorageClass();3251 StorageClass sc = fn_decl->getStorageClass();
3253 if (sc == SC_None) {3252 if (sc == SC_None) {
3254 proto_node->data.fn_proto.visib_mod = fn_decl->hasBody() ? c->export_visib_mod : c->visib_mod;3253 // TODO add export decl
3254 proto_node->data.fn_proto.visib_mod = c->visib_mod;
3255 } else if (sc == SC_Extern || sc == SC_Static) {3255 } else if (sc == SC_Extern || sc == SC_Static) {
3256 proto_node->data.fn_proto.visib_mod = c->visib_mod;3256 proto_node->data.fn_proto.visib_mod = c->visib_mod;
3257 } else if (sc == SC_PrivateExtern) {3257 } else if (sc == SC_PrivateExtern) {
...@@ -4274,10 +4274,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch...@@ -4274,10 +4274,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
4274 c->errors = errors;4274 c->errors = errors;
4275 if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) {4275 if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) {
4276 c->visib_mod = VisibModPub;4276 c->visib_mod = VisibModPub;
4277 c->export_visib_mod = VisibModPub;
4278 } else {4277 } else {
4279 c->visib_mod = VisibModPub;4278 c->visib_mod = VisibModPub;
4280 c->export_visib_mod = VisibModExport;
4281 }4279 }
4282 c->decl_table.init(8);4280 c->decl_table.init(8);
4283 c->macro_table.init(8);4281 c->macro_table.init(8);
std/debug.zig-2
...@@ -96,8 +96,6 @@ const WHITE = "\x1b[37;1m";...@@ -96,8 +96,6 @@ const WHITE = "\x1b[37;1m";
96const DIM = "\x1b[2m";96const DIM = "\x1b[2m";
97const RESET = "\x1b[0m";97const RESET = "\x1b[0m";
9898
99pub var user_main_fn: ?fn() -> %void = null;
100
101error PathNotFound;99error PathNotFound;
102error InvalidDebugInfo;100error InvalidDebugInfo;
103101
std/elf.zig+31-31
...@@ -188,39 +188,39 @@ pub const Elf = struct {...@@ -188,39 +188,39 @@ pub const Elf = struct {
188 if (elf.is_64) {188 if (elf.is_64) {
189 if (sh_entry_size != 64) return error.InvalidFormat;189 if (sh_entry_size != 64) return error.InvalidFormat;
190190
191 for (elf.section_headers) |*section| {191 for (elf.section_headers) |*elf_section| {
192 section.name = %return in.readInt(elf.endian, u32);192 elf_section.name = %return in.readInt(elf.endian, u32);
193 section.sh_type = %return in.readInt(elf.endian, u32);193 elf_section.sh_type = %return in.readInt(elf.endian, u32);
194 section.flags = %return in.readInt(elf.endian, u64);194 elf_section.flags = %return in.readInt(elf.endian, u64);
195 section.addr = %return in.readInt(elf.endian, u64);195 elf_section.addr = %return in.readInt(elf.endian, u64);
196 section.offset = %return in.readInt(elf.endian, u64);196 elf_section.offset = %return in.readInt(elf.endian, u64);
197 section.size = %return in.readInt(elf.endian, u64);197 elf_section.size = %return in.readInt(elf.endian, u64);
198 section.link = %return in.readInt(elf.endian, u32);198 elf_section.link = %return in.readInt(elf.endian, u32);
199 section.info = %return in.readInt(elf.endian, u32);199 elf_section.info = %return in.readInt(elf.endian, u32);
200 section.addr_align = %return in.readInt(elf.endian, u64);200 elf_section.addr_align = %return in.readInt(elf.endian, u64);
201 section.ent_size = %return in.readInt(elf.endian, u64);201 elf_section.ent_size = %return in.readInt(elf.endian, u64);
202 }202 }
203 } else {203 } else {
204 if (sh_entry_size != 40) return error.InvalidFormat;204 if (sh_entry_size != 40) return error.InvalidFormat;
205205
206 for (elf.section_headers) |*section| {206 for (elf.section_headers) |*elf_section| {
207 // TODO (multiple occurences) allow implicit cast from %u32 -> %u64 ?207 // TODO (multiple occurences) allow implicit cast from %u32 -> %u64 ?
208 section.name = %return in.readInt(elf.endian, u32);208 elf_section.name = %return in.readInt(elf.endian, u32);
209 section.sh_type = %return in.readInt(elf.endian, u32);209 elf_section.sh_type = %return in.readInt(elf.endian, u32);
210 section.flags = u64(%return in.readInt(elf.endian, u32));210 elf_section.flags = u64(%return in.readInt(elf.endian, u32));
211 section.addr = u64(%return in.readInt(elf.endian, u32));211 elf_section.addr = u64(%return in.readInt(elf.endian, u32));
212 section.offset = u64(%return in.readInt(elf.endian, u32));212 elf_section.offset = u64(%return in.readInt(elf.endian, u32));
213 section.size = u64(%return in.readInt(elf.endian, u32));213 elf_section.size = u64(%return in.readInt(elf.endian, u32));
214 section.link = %return in.readInt(elf.endian, u32);214 elf_section.link = %return in.readInt(elf.endian, u32);
215 section.info = %return in.readInt(elf.endian, u32);215 elf_section.info = %return in.readInt(elf.endian, u32);
216 section.addr_align = u64(%return in.readInt(elf.endian, u32));216 elf_section.addr_align = u64(%return in.readInt(elf.endian, u32));
217 section.ent_size = u64(%return in.readInt(elf.endian, u32));217 elf_section.ent_size = u64(%return in.readInt(elf.endian, u32));
218 }218 }
219 }219 }
220220
221 for (elf.section_headers) |*section| {221 for (elf.section_headers) |*elf_section| {
222 if (section.sh_type != SHT_NOBITS) {222 if (elf_section.sh_type != SHT_NOBITS) {
223 const file_end_offset = %return math.add(u64, section.offset, section.size);223 const file_end_offset = %return math.add(u64, elf_section.offset, elf_section.size);
224 if (stream_end < file_end_offset) return error.InvalidFormat;224 if (stream_end < file_end_offset) return error.InvalidFormat;
225 }225 }
226 }226 }
...@@ -243,10 +243,10 @@ pub const Elf = struct {...@@ -243,10 +243,10 @@ pub const Elf = struct {
243 var file_stream = io.FileInStream.init(elf.in_file);243 var file_stream = io.FileInStream.init(elf.in_file);
244 const in = &file_stream.stream;244 const in = &file_stream.stream;
245245
246 for (elf.section_headers) |*section| {246 for (elf.section_headers) |*elf_section| {
247 if (section.sh_type == SHT_NULL) continue;247 if (elf_section.sh_type == SHT_NULL) continue;
248248
249 const name_offset = elf.string_section.offset + section.name;249 const name_offset = elf.string_section.offset + elf_section.name;
250 %return elf.in_file.seekTo(name_offset);250 %return elf.in_file.seekTo(name_offset);
251251
252 for (name) |expected_c| {252 for (name) |expected_c| {
...@@ -256,7 +256,7 @@ pub const Elf = struct {...@@ -256,7 +256,7 @@ pub const Elf = struct {
256256
257 {257 {
258 const null_byte = %return in.readByte();258 const null_byte = %return in.readByte();
259 if (null_byte == 0) return section;259 if (null_byte == 0) return elf_section;
260 }260 }
261261
262 next_section:262 next_section:
...@@ -265,7 +265,7 @@ pub const Elf = struct {...@@ -265,7 +265,7 @@ pub const Elf = struct {
265 return null;265 return null;
266 }266 }
267267
268 pub fn seekToSection(elf: &Elf, section: &SectionHeader) -> %void {268 pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) -> %void {
269 %return elf.in_file.seekTo(section.offset);269 %return elf.in_file.seekTo(elf_section.offset);
270 }270 }
271};271};
std/mem.zig+1
...@@ -4,6 +4,7 @@ const math = @import("math/index.zig");...@@ -4,6 +4,7 @@ const math = @import("math/index.zig");
4const builtin = @import("builtin");4const builtin = @import("builtin");
55
6pub const Cmp = math.Cmp;6pub const Cmp = math.Cmp;
7error OutOfMemory;
78
8pub const Allocator = struct {9pub const Allocator = struct {
9 /// Allocate byte_count bytes and return them in a slice, with the10 /// Allocate byte_count bytes and return them in a slice, with the
std/os/linux.zig-22
...@@ -651,28 +651,6 @@ pub const iovec = extern struct {...@@ -651,28 +651,6 @@ pub const iovec = extern struct {
651 iov_len: usize,651 iov_len: usize,
652};652};
653653
654//
655//const IF_NAMESIZE = 16;
656//
657//export struct ifreq {
658// ifrn_name: [IF_NAMESIZE]u8,
659// union {
660// ifru_addr: sockaddr,
661// ifru_dstaddr: sockaddr,
662// ifru_broadaddr: sockaddr,
663// ifru_netmask: sockaddr,
664// ifru_hwaddr: sockaddr,
665// ifru_flags: i16,
666// ifru_ivalue: i32,
667// ifru_mtu: i32,
668// ifru_map: ifmap,
669// ifru_slave: [IF_NAMESIZE]u8,
670// ifru_newname: [IF_NAMESIZE]u8,
671// ifru_data: &u8,
672// } ifr_ifru;
673//}
674//
675
676pub fn getsockname(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize {654pub fn getsockname(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize {
677 arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len))655 arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len))
678}656}
std/os/linux_i386.zig-10
...@@ -502,13 +502,3 @@ pub nakedcc fn restore_rt() {...@@ -502,13 +502,3 @@ pub nakedcc fn restore_rt() {
502 : [number] "{eax}" (usize(SYS_rt_sigreturn))502 : [number] "{eax}" (usize(SYS_rt_sigreturn))
503 : "rcx", "r11")503 : "rcx", "r11")
504}504}
505
506export struct msghdr {
507 msg_name: &u8,
508 msg_namelen: socklen_t,
509 msg_iov: &iovec,
510 msg_iovlen: i32,
511 msg_control: &u8,
512 msg_controllen: socklen_t,
513 msg_flags: i32,
514}
std/special/bootstrap.zig+11-24
...@@ -5,20 +5,19 @@ const root = @import("@root");...@@ -5,20 +5,19 @@ const root = @import("@root");
5const std = @import("std");5const std = @import("std");
6const builtin = @import("builtin");6const builtin = @import("builtin");
77
8const is_windows = builtin.os == builtin.Os.windows;
9const want_main_symbol = builtin.link_libc;
10const want_start_symbol = !want_main_symbol and !is_windows;
11const want_WinMainCRTStartup = is_windows and !builtin.link_libc;
12
13var argc_ptr: &usize = undefined;8var argc_ptr: &usize = undefined;
149
1510comptime {
16export nakedcc fn _start() -> noreturn {11 if (builtin.link_libc) {
17 if (!want_start_symbol) {12 @export("main", main);
18 @setGlobalLinkage(_start, builtin.GlobalLinkage.Internal);13 } else if (builtin.os == builtin.Os.windows) {
19 unreachable;14 @export("WinMainCRTStartup", WinMainCRTStartup);
15 } else {
16 @export("_start", _start);
20 }17 }
18}
2119
20nakedcc fn _start() -> noreturn {
22 switch (builtin.arch) {21 switch (builtin.arch) {
23 builtin.Arch.x86_64 => {22 builtin.Arch.x86_64 => {
24 argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize));23 argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize));
...@@ -33,14 +32,9 @@ export nakedcc fn _start() -> noreturn {...@@ -33,14 +32,9 @@ export nakedcc fn _start() -> noreturn {
33 @noInlineCall(posixCallMainAndExit);32 @noInlineCall(posixCallMainAndExit);
34}33}
3534
36export fn WinMainCRTStartup() -> noreturn {35extern fn WinMainCRTStartup() -> noreturn {
37 if (!want_WinMainCRTStartup) {
38 @setGlobalLinkage(WinMainCRTStartup, builtin.GlobalLinkage.Internal);
39 unreachable;
40 }
41 @setAlignStack(16);36 @setAlignStack(16);
4237
43 std.debug.user_main_fn = root.main;
44 root.main() %% std.os.windows.ExitProcess(1);38 root.main() %% std.os.windows.ExitProcess(1);
45 std.os.windows.ExitProcess(0);39 std.os.windows.ExitProcess(0);
46}40}
...@@ -60,17 +54,10 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void {...@@ -60,17 +54,10 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void {
60 while (envp[env_count] != null) : (env_count += 1) {}54 while (envp[env_count] != null) : (env_count += 1) {}
61 std.os.posix_environ_raw = @ptrCast(&&u8, envp)[0..env_count];55 std.os.posix_environ_raw = @ptrCast(&&u8, envp)[0..env_count];
6256
63 std.debug.user_main_fn = root.main;
64
65 return root.main();57 return root.main();
66}58}
6759
68export fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 {60extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 {
69 if (!want_main_symbol) {
70 @setGlobalLinkage(main, builtin.GlobalLinkage.Internal);
71 unreachable;
72 }
73
74 callMain(usize(c_argc), c_argv, c_envp) %% return 1;61 callMain(usize(c_argc), c_argv, c_envp) %% return 1;
75 return 0;62 return 0;
76}63}
std/special/bootstrap_lib.zig+5-1
...@@ -2,7 +2,11 @@...@@ -2,7 +2,11 @@
22
3const std = @import("std");3const std = @import("std");
44
5export stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD,5comptime {
6 @export("_DllMainCRTStartup", _DllMainCRTStartup);
7}
8
9stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD,
6 lpReserved: std.os.windows.LPVOID) -> std.os.windows.BOOL10 lpReserved: std.os.windows.LPVOID) -> std.os.windows.BOOL
7{11{
8 return std.os.windows.TRUE;12 return std.os.windows.TRUE;
std/special/builtin.zig+23-13
...@@ -13,10 +13,24 @@ pub coldcc fn panic(msg: []const u8) -> noreturn {...@@ -13,10 +13,24 @@ pub coldcc fn panic(msg: []const u8) -> noreturn {
13 }13 }
14}14}
1515
16comptime {
17 @export("memset", memset);
18 @export("memcpy", memcpy);
19 @export("fmodf", fmodf);
20 @export("fmod", fmod);
21 @export("floorf", floorf);
22 @export("ceilf", ceilf);
23 @export("floor", floor);
24 @export("ceil", ceil);
25 if (builtin.mode != builtin.Mode.ReleaseFast and builtin.os != builtin.Os.windows) {
26 @export("__stack_chk_fail", __stack_chk_fail);
27 }
28}
29
16// Note that memset does not return `dest`, like the libc API.30// Note that memset does not return `dest`, like the libc API.
17// The semantics of memset is dictated by the corresponding31// The semantics of memset is dictated by the corresponding
18// LLVM intrinsics, not by the libc API.32// LLVM intrinsics, not by the libc API.
19export fn memset(dest: ?&u8, c: u8, n: usize) {33extern fn memset(dest: ?&u8, c: u8, n: usize) {
20 @setDebugSafety(this, false);34 @setDebugSafety(this, false);
2135
22 var index: usize = 0;36 var index: usize = 0;
...@@ -27,7 +41,7 @@ export fn memset(dest: ?&u8, c: u8, n: usize) {...@@ -27,7 +41,7 @@ export fn memset(dest: ?&u8, c: u8, n: usize) {
27// Note that memcpy does not return `dest`, like the libc API.41// Note that memcpy does not return `dest`, like the libc API.
28// The semantics of memcpy is dictated by the corresponding42// The semantics of memcpy is dictated by the corresponding
29// LLVM intrinsics, not by the libc API.43// LLVM intrinsics, not by the libc API.
30export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {44extern fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {
31 @setDebugSafety(this, false);45 @setDebugSafety(this, false);
3246
33 var index: usize = 0;47 var index: usize = 0;
...@@ -35,25 +49,21 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {...@@ -35,25 +49,21 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {
35 (??dest)[index] = (??src)[index];49 (??dest)[index] = (??src)[index];
36}50}
3751
38export fn __stack_chk_fail() -> noreturn {52extern fn __stack_chk_fail() -> noreturn {
39 if (builtin.mode == builtin.Mode.ReleaseFast or builtin.os == builtin.Os.windows) {
40 @setGlobalLinkage(__stack_chk_fail, builtin.GlobalLinkage.Internal);
41 unreachable;
42 }
43 @panic("stack smashing detected");53 @panic("stack smashing detected");
44}54}
4555
46const math = @import("../math/index.zig");56const math = @import("../math/index.zig");
4757
48export fn fmodf(x: f32, y: f32) -> f32 { generic_fmod(f32, x, y) }58extern fn fmodf(x: f32, y: f32) -> f32 { generic_fmod(f32, x, y) }
49export fn fmod(x: f64, y: f64) -> f64 { generic_fmod(f64, x, y) }59extern fn fmod(x: f64, y: f64) -> f64 { generic_fmod(f64, x, y) }
5060
51// TODO add intrinsics for these (and probably the double version too)61// TODO add intrinsics for these (and probably the double version too)
52// and have the math stuff use the intrinsic. same as @mod and @rem62// and have the math stuff use the intrinsic. same as @mod and @rem
53export fn floorf(x: f32) -> f32 { math.floor(x) }63extern fn floorf(x: f32) -> f32 { math.floor(x) }
54export fn ceilf(x: f32) -> f32 { math.ceil(x) }64extern fn ceilf(x: f32) -> f32 { math.ceil(x) }
55export fn floor(x: f64) -> f64 { math.floor(x) }65extern fn floor(x: f64) -> f64 { math.floor(x) }
56export fn ceil(x: f64) -> f64 { math.ceil(x) }66extern fn ceil(x: f64) -> f64 { math.ceil(x) }
5767
58fn generic_fmod(comptime T: type, x: T, y: T) -> T {68fn generic_fmod(comptime T: type, x: T, y: T) -> T {
59 @setDebugSafety(this, false);69 @setDebugSafety(this, false);
std/special/compiler_rt/aulldiv.zig+54-65
...@@ -1,66 +1,55 @@...@@ -1,66 +1,55 @@
1const builtin = @import("builtin");1pub nakedcc fn _aulldiv() {
2const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;2 @setDebugSafety(this, false);
3const is_win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386;3 asm volatile (
44 \\.intel_syntax noprefix
5export nakedcc fn _aulldiv() {5 \\
6 if (is_win32) {6 \\ push ebx
7 @setDebugSafety(this, false);7 \\ push esi
8 @setGlobalLinkage(_aulldiv, linkage);8 \\ mov eax,dword ptr [esp+18h]
9 asm volatile (9 \\ or eax,eax
10 \\.intel_syntax noprefix10 \\ jne L1
11 \\11 \\ mov ecx,dword ptr [esp+14h]
12 \\ push ebx12 \\ mov eax,dword ptr [esp+10h]
13 \\ push esi13 \\ xor edx,edx
14 \\ mov eax,dword ptr [esp+18h]14 \\ div ecx
15 \\ or eax,eax15 \\ mov ebx,eax
16 \\ jne L116 \\ mov eax,dword ptr [esp+0Ch]
17 \\ mov ecx,dword ptr [esp+14h]17 \\ div ecx
18 \\ mov eax,dword ptr [esp+10h]18 \\ mov edx,ebx
19 \\ xor edx,edx19 \\ jmp L2
20 \\ div ecx20 \\ L1:
21 \\ mov ebx,eax21 \\ mov ecx,eax
22 \\ mov eax,dword ptr [esp+0Ch]22 \\ mov ebx,dword ptr [esp+14h]
23 \\ div ecx23 \\ mov edx,dword ptr [esp+10h]
24 \\ mov edx,ebx24 \\ mov eax,dword ptr [esp+0Ch]
25 \\ jmp L225 \\ L3:
26 \\ L1:26 \\ shr ecx,1
27 \\ mov ecx,eax27 \\ rcr ebx,1
28 \\ mov ebx,dword ptr [esp+14h]28 \\ shr edx,1
29 \\ mov edx,dword ptr [esp+10h]29 \\ rcr eax,1
30 \\ mov eax,dword ptr [esp+0Ch]30 \\ or ecx,ecx
31 \\ L3:31 \\ jne L3
32 \\ shr ecx,132 \\ div ebx
33 \\ rcr ebx,133 \\ mov esi,eax
34 \\ shr edx,134 \\ mul dword ptr [esp+18h]
35 \\ rcr eax,135 \\ mov ecx,eax
36 \\ or ecx,ecx36 \\ mov eax,dword ptr [esp+14h]
37 \\ jne L337 \\ mul esi
38 \\ div ebx38 \\ add edx,ecx
39 \\ mov esi,eax39 \\ jb L4
40 \\ mul dword ptr [esp+18h]40 \\ cmp edx,dword ptr [esp+10h]
41 \\ mov ecx,eax41 \\ ja L4
42 \\ mov eax,dword ptr [esp+14h]42 \\ jb L5
43 \\ mul esi43 \\ cmp eax,dword ptr [esp+0Ch]
44 \\ add edx,ecx44 \\ jbe L5
45 \\ jb L445 \\ L4:
46 \\ cmp edx,dword ptr [esp+10h]46 \\ dec esi
47 \\ ja L447 \\ L5:
48 \\ jb L548 \\ xor edx,edx
49 \\ cmp eax,dword ptr [esp+0Ch]49 \\ mov eax,esi
50 \\ jbe L550 \\ L2:
51 \\ L4:51 \\ pop esi
52 \\ dec esi52 \\ pop ebx
53 \\ L5:53 \\ ret 10h
54 \\ xor edx,edx54 );
55 \\ mov eax,esi
56 \\ L2:
57 \\ pop esi
58 \\ pop ebx
59 \\ ret 10h
60 );
61 unreachable;
62 }
63
64 @setGlobalLinkage(_aulldiv, builtin.GlobalLinkage.Internal);
65 unreachable;
66}55}
std/special/compiler_rt/aullrem.zig+55-66
...@@ -1,67 +1,56 @@...@@ -1,67 +1,56 @@
1const builtin = @import("builtin");1pub nakedcc fn _aullrem() {
2const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;2 @setDebugSafety(this, false);
3const is_win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386;3 asm volatile (
44 \\.intel_syntax noprefix
5export nakedcc fn _aullrem() {5 \\
6 if (is_win32) {6 \\ push ebx
7 @setDebugSafety(this, false);7 \\ mov eax,dword ptr [esp+14h]
8 @setGlobalLinkage(_aullrem, linkage);8 \\ or eax,eax
9 asm volatile (9 \\ jne L1a
10 \\.intel_syntax noprefix10 \\ mov ecx,dword ptr [esp+10h]
11 \\11 \\ mov eax,dword ptr [esp+0Ch]
12 \\ push ebx12 \\ xor edx,edx
13 \\ mov eax,dword ptr [esp+14h]13 \\ div ecx
14 \\ or eax,eax14 \\ mov eax,dword ptr [esp+8]
15 \\ jne L1a15 \\ div ecx
16 \\ mov ecx,dword ptr [esp+10h]16 \\ mov eax,edx
17 \\ mov eax,dword ptr [esp+0Ch]17 \\ xor edx,edx
18 \\ xor edx,edx18 \\ jmp L2a
19 \\ div ecx19 \\ L1a:
20 \\ mov eax,dword ptr [esp+8]20 \\ mov ecx,eax
21 \\ div ecx21 \\ mov ebx,dword ptr [esp+10h]
22 \\ mov eax,edx22 \\ mov edx,dword ptr [esp+0Ch]
23 \\ xor edx,edx23 \\ mov eax,dword ptr [esp+8]
24 \\ jmp L2a24 \\ L3a:
25 \\ L1a:25 \\ shr ecx,1
26 \\ mov ecx,eax26 \\ rcr ebx,1
27 \\ mov ebx,dword ptr [esp+10h]27 \\ shr edx,1
28 \\ mov edx,dword ptr [esp+0Ch]28 \\ rcr eax,1
29 \\ mov eax,dword ptr [esp+8]29 \\ or ecx,ecx
30 \\ L3a:30 \\ jne L3a
31 \\ shr ecx,131 \\ div ebx
32 \\ rcr ebx,132 \\ mov ecx,eax
33 \\ shr edx,133 \\ mul dword ptr [esp+14h]
34 \\ rcr eax,134 \\ xchg eax,ecx
35 \\ or ecx,ecx35 \\ mul dword ptr [esp+10h]
36 \\ jne L3a36 \\ add edx,ecx
37 \\ div ebx37 \\ jb L4a
38 \\ mov ecx,eax38 \\ cmp edx,dword ptr [esp+0Ch]
39 \\ mul dword ptr [esp+14h]39 \\ ja L4a
40 \\ xchg eax,ecx40 \\ jb L5a
41 \\ mul dword ptr [esp+10h]41 \\ cmp eax,dword ptr [esp+8]
42 \\ add edx,ecx42 \\ jbe L5a
43 \\ jb L4a43 \\ L4a:
44 \\ cmp edx,dword ptr [esp+0Ch]44 \\ sub eax,dword ptr [esp+10h]
45 \\ ja L4a45 \\ sbb edx,dword ptr [esp+14h]
46 \\ jb L5a46 \\ L5a:
47 \\ cmp eax,dword ptr [esp+8]47 \\ sub eax,dword ptr [esp+8]
48 \\ jbe L5a48 \\ sbb edx,dword ptr [esp+0Ch]
49 \\ L4a:49 \\ neg edx
50 \\ sub eax,dword ptr [esp+10h]50 \\ neg eax
51 \\ sbb edx,dword ptr [esp+14h]51 \\ sbb edx,0
52 \\ L5a:52 \\ L2a:
53 \\ sub eax,dword ptr [esp+8]53 \\ pop ebx
54 \\ sbb edx,dword ptr [esp+0Ch]54 \\ ret 10h
55 \\ neg edx55 );
56 \\ neg eax
57 \\ sbb edx,0
58 \\ L2a:
59 \\ pop ebx
60 \\ ret 10h
61 );
62 unreachable;
63 }
64
65 @setGlobalLinkage(_aullrem, builtin.GlobalLinkage.Internal);
66 unreachable;
67}56}
std/special/compiler_rt/comparetf2.zig+3-42
...@@ -20,11 +20,9 @@ const infRep = exponentMask;...@@ -20,11 +20,9 @@ const infRep = exponentMask;
2020
21const builtin = @import("builtin");21const builtin = @import("builtin");
22const is_test = builtin.is_test;22const is_test = builtin.is_test;
23const linkage = @import("index.zig").linkage;
2423
25export fn __letf2(a: f128, b: f128) -> c_int {24pub extern fn __letf2(a: f128, b: f128) -> c_int {
26 @setDebugSafety(this, is_test);25 @setDebugSafety(this, is_test);
27 @setGlobalLinkage(__letf2, linkage);
2826
29 const aInt = @bitCast(rep_t, a);27 const aInt = @bitCast(rep_t, a);
30 const bInt = @bitCast(rep_t, b);28 const bInt = @bitCast(rep_t, b);
...@@ -63,14 +61,6 @@ export fn __letf2(a: f128, b: f128) -> c_int {...@@ -63,14 +61,6 @@ export fn __letf2(a: f128, b: f128) -> c_int {
63 };61 };
64}62}
6563
66// Alias for libgcc compatibility
67// TODO https://github.com/zig-lang/zig/issues/420
68export fn __cmptf2(a: f128, b: f128) -> c_int {
69 @setGlobalLinkage(__cmptf2, linkage);
70 @setDebugSafety(this, is_test);
71 return __letf2(a, b);
72}
73
74// TODO https://github.com/zig-lang/zig/issues/30564// TODO https://github.com/zig-lang/zig/issues/305
75// and then make the return types of some of these functions the enum instead of c_int65// and then make the return types of some of these functions the enum instead of c_int
76const GE_LESS = c_int(-1);66const GE_LESS = c_int(-1);
...@@ -78,8 +68,7 @@ const GE_EQUAL = c_int(0);...@@ -78,8 +68,7 @@ const GE_EQUAL = c_int(0);
78const GE_GREATER = c_int(1);68const GE_GREATER = c_int(1);
79const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED69const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
8070
81export fn __getf2(a: f128, b: f128) -> c_int {71pub extern fn __getf2(a: f128, b: f128) -> c_int {
82 @setGlobalLinkage(__getf2, linkage);
83 @setDebugSafety(this, is_test);72 @setDebugSafety(this, is_test);
8473
85 const aInt = @bitCast(srep_t, a);74 const aInt = @bitCast(srep_t, a);
...@@ -108,38 +97,10 @@ export fn __getf2(a: f128, b: f128) -> c_int {...@@ -108,38 +97,10 @@ export fn __getf2(a: f128, b: f128) -> c_int {
108 };97 };
109}98}
11099
111export fn __unordtf2(a: f128, b: f128) -> c_int {100pub extern fn __unordtf2(a: f128, b: f128) -> c_int {
112 @setGlobalLinkage(__unordtf2, linkage);
113 @setDebugSafety(this, is_test);101 @setDebugSafety(this, is_test);
114102
115 const aAbs = @bitCast(rep_t, a) & absMask;103 const aAbs = @bitCast(rep_t, a) & absMask;
116 const bAbs = @bitCast(rep_t, b) & absMask;104 const bAbs = @bitCast(rep_t, b) & absMask;
117 return c_int(aAbs > infRep or bAbs > infRep);105 return c_int(aAbs > infRep or bAbs > infRep);
118}106}
119
120// The following are alternative names for the preceding routines.
121// TODO use aliases https://github.com/zig-lang/zig/issues/462
122
123export fn __eqtf2(a: f128, b: f128) -> c_int {
124 @setGlobalLinkage(__eqtf2, linkage);
125 @setDebugSafety(this, is_test);
126 return __letf2(a, b);
127}
128
129export fn __lttf2(a: f128, b: f128) -> c_int {
130 @setGlobalLinkage(__lttf2, linkage);
131 @setDebugSafety(this, is_test);
132 return __letf2(a, b);
133}
134
135export fn __netf2(a: f128, b: f128) -> c_int {
136 @setGlobalLinkage(__netf2, linkage);
137 @setDebugSafety(this, is_test);
138 return __letf2(a, b);
139}
140
141export fn __gttf2(a: f128, b: f128) -> c_int {
142 @setGlobalLinkage(__gttf2, linkage);
143 @setDebugSafety(this, is_test);
144 return __getf2(a, b);
145}
std/special/compiler_rt/fixunsdfdi.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunsdfdi(a: f64) -> u64 {4pub extern fn __fixunsdfdi(a: f64) -> u64 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunsdfdi, linkage);
8 return fixuint(f64, u64, a);6 return fixuint(f64, u64, a);
9}7}
108
std/special/compiler_rt/fixunsdfsi.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunsdfsi(a: f64) -> u32 {4pub extern fn __fixunsdfsi(a: f64) -> u32 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunsdfsi, linkage);
8 return fixuint(f64, u32, a);6 return fixuint(f64, u32, a);
9}7}
108
std/special/compiler_rt/fixunsdfti.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunsdfti(a: f64) -> u128 {4pub extern fn __fixunsdfti(a: f64) -> u128 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunsdfti, linkage);
8 return fixuint(f64, u128, a);6 return fixuint(f64, u128, a);
9}7}
108
std/special/compiler_rt/fixunssfdi.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunssfdi(a: f32) -> u64 {4pub extern fn __fixunssfdi(a: f32) -> u64 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunssfdi, linkage);
8 return fixuint(f32, u64, a);6 return fixuint(f32, u64, a);
9}7}
108
std/special/compiler_rt/fixunssfsi.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunssfsi(a: f32) -> u32 {4pub extern fn __fixunssfsi(a: f32) -> u32 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunssfsi, linkage);
8 return fixuint(f32, u32, a);6 return fixuint(f32, u32, a);
9}7}
108
std/special/compiler_rt/fixunssfti.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunssfti(a: f32) -> u128 {4pub extern fn __fixunssfti(a: f32) -> u128 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunssfti, linkage);
8 return fixuint(f32, u128, a);6 return fixuint(f32, u128, a);
9}7}
108
std/special/compiler_rt/fixunstfdi.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunstfdi(a: f128) -> u64 {4pub extern fn __fixunstfdi(a: f128) -> u64 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunstfdi, linkage);
8 return fixuint(f128, u64, a);6 return fixuint(f128, u64, a);
9}7}
108
std/special/compiler_rt/fixunstfsi.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunstfsi(a: f128) -> u32 {4pub extern fn __fixunstfsi(a: f128) -> u32 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunstfsi, linkage);
8 return fixuint(f128, u32, a);6 return fixuint(f128, u32, a);
9}7}
108
std/special/compiler_rt/fixunstfti.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunstfti(a: f128) -> u128 {4pub extern fn __fixunstfti(a: f128) -> u128 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunstfti, linkage);
8 return fixuint(f128, u128, a);6 return fixuint(f128, u128, a);
9}7}
108
std/special/compiler_rt/index.zig+165-176
...@@ -1,33 +1,74 @@...@@ -1,33 +1,74 @@
1comptime {
2 _ = @import("comparetf2.zig");
3 _ = @import("fixunsdfdi.zig");
4 _ = @import("fixunsdfsi.zig");
5 _ = @import("fixunsdfti.zig");
6 _ = @import("fixunssfdi.zig");
7 _ = @import("fixunssfsi.zig");
8 _ = @import("fixunssfti.zig");
9 _ = @import("fixunstfdi.zig");
10 _ = @import("fixunstfsi.zig");
11 _ = @import("fixunstfti.zig");
12 _ = @import("udivmoddi4.zig");
13 _ = @import("udivmodti4.zig");
14 _ = @import("udivti3.zig");
15 _ = @import("umodti3.zig");
16 _ = @import("aulldiv.zig");
17 _ = @import("aullrem.zig");
18}
19
20const builtin = @import("builtin");1const builtin = @import("builtin");
21const is_test = builtin.is_test;2const is_test = builtin.is_test;
22const assert = @import("../../debug.zig").assert;
233
4comptime {
5 const linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak;
6 const strong_linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;
7
8 @exportWithLinkage("__letf2", @import("comparetf2.zig").__letf2, linkage);
9 @exportWithLinkage("__getf2", @import("comparetf2.zig").__getf2, linkage);
10
11 if (!is_test) {
12 // only create these aliases when not testing
13 @exportWithLinkage("__cmptf2", @import("comparetf2.zig").__letf2, linkage);
14 @exportWithLinkage("__eqtf2", @import("comparetf2.zig").__letf2, linkage);
15 @exportWithLinkage("__lttf2", @import("comparetf2.zig").__letf2, linkage);
16 @exportWithLinkage("__netf2", @import("comparetf2.zig").__letf2, linkage);
17 @exportWithLinkage("__gttf2", @import("comparetf2.zig").__getf2, linkage);
18 }
19
20 @exportWithLinkage("__unordtf2", @import("comparetf2.zig").__unordtf2, linkage);
21
22 @exportWithLinkage("__fixunssfsi", @import("fixunssfsi.zig").__fixunssfsi, linkage);
23 @exportWithLinkage("__fixunssfdi", @import("fixunssfdi.zig").__fixunssfdi, linkage);
24 @exportWithLinkage("__fixunssfti", @import("fixunssfti.zig").__fixunssfti, linkage);
25
26 @exportWithLinkage("__fixunsdfsi", @import("fixunsdfsi.zig").__fixunsdfsi, linkage);
27 @exportWithLinkage("__fixunsdfdi", @import("fixunsdfdi.zig").__fixunsdfdi, linkage);
28 @exportWithLinkage("__fixunsdfti", @import("fixunsdfti.zig").__fixunsdfti, linkage);
29
30 @exportWithLinkage("__fixunstfsi", @import("fixunstfsi.zig").__fixunstfsi, linkage);
31 @exportWithLinkage("__fixunstfdi", @import("fixunstfdi.zig").__fixunstfdi, linkage);
32 @exportWithLinkage("__fixunstfti", @import("fixunstfti.zig").__fixunstfti, linkage);
33
34 @exportWithLinkage("__udivmoddi4", @import("udivmoddi4.zig").__udivmoddi4, linkage);
35 @exportWithLinkage("__udivmodti4", @import("udivmodti4.zig").__udivmodti4, linkage);
2436
25const win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386;37 @exportWithLinkage("__udivti3", @import("udivti3.zig").__udivti3, linkage);
26const win64 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.x86_64;38 @exportWithLinkage("__umodti3", @import("umodti3.zig").__umodti3, linkage);
27const win32_nocrt = win32 and !builtin.link_libc;39
28const win64_nocrt = win64 and !builtin.link_libc;40 @exportWithLinkage("__udivsi3", __udivsi3, linkage);
29pub const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak;41 @exportWithLinkage("__udivdi3", __udivdi3, linkage);
30const strong_linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;42 @exportWithLinkage("__umoddi3", __umoddi3, linkage);
43 @exportWithLinkage("__udivmodsi4", __udivmodsi4, linkage);
44
45 if (isArmArch()) {
46 @exportWithLinkage("__aeabi_uldivmod", __aeabi_uldivmod, linkage);
47 @exportWithLinkage("__aeabi_uidivmod", __aeabi_uidivmod, linkage);
48 @exportWithLinkage("__aeabi_uidiv", __udivsi3, linkage);
49 }
50 if (builtin.os == builtin.Os.windows) {
51 switch (builtin.arch) {
52 builtin.Arch.i386 => {
53 if (!builtin.link_libc) {
54 @exportWithLinkage("_chkstk", _chkstk, strong_linkage);
55 @exportWithLinkage("__chkstk_ms", __chkstk_ms, linkage);
56 }
57 @exportWithLinkage("_aulldiv", @import("aulldiv.zig")._aulldiv, strong_linkage);
58 @exportWithLinkage("_aullrem", @import("aullrem.zig")._aullrem, strong_linkage);
59 },
60 builtin.Arch.x86_64 => {
61 if (!builtin.link_libc) {
62 @exportWithLinkage("__chkstk", __chkstk, strong_linkage);
63 @exportWithLinkage("___chkstk_ms", ___chkstk_ms, linkage);
64 }
65 },
66 else => {},
67 }
68 }
69}
70
71const assert = @import("../../debug.zig").assert;
3172
32const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;73const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
3374
...@@ -41,15 +82,13 @@ pub coldcc fn panic(msg: []const u8) -> noreturn {...@@ -41,15 +82,13 @@ pub coldcc fn panic(msg: []const u8) -> noreturn {
41 }82 }
42}83}
4384
44export fn __udivdi3(a: u64, b: u64) -> u64 {85extern fn __udivdi3(a: u64, b: u64) -> u64 {
45 @setDebugSafety(this, is_test);86 @setDebugSafety(this, is_test);
46 @setGlobalLinkage(__udivdi3, linkage);
47 return __udivmoddi4(a, b, null);87 return __udivmoddi4(a, b, null);
48}88}
4989
50export fn __umoddi3(a: u64, b: u64) -> u64 {90extern fn __umoddi3(a: u64, b: u64) -> u64 {
51 @setDebugSafety(this, is_test);91 @setDebugSafety(this, is_test);
52 @setGlobalLinkage(__umoddi3, linkage);
5392
54 var r: u64 = undefined;93 var r: u64 = undefined;
55 _ = __udivmoddi4(a, b, &r);94 _ = __udivmoddi4(a, b, &r);
...@@ -60,17 +99,11 @@ const AeabiUlDivModResult = extern struct {...@@ -60,17 +99,11 @@ const AeabiUlDivModResult = extern struct {
60 quot: u64,99 quot: u64,
61 rem: u64,100 rem: u64,
62};101};
63export fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult {102extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult {
64 @setDebugSafety(this, is_test);103 @setDebugSafety(this, is_test);
65 if (comptime isArmArch()) {104 var result: AeabiUlDivModResult = undefined;
66 @setGlobalLinkage(__aeabi_uldivmod, linkage);105 result.quot = __udivmoddi4(numerator, denominator, &result.rem);
67 var result: AeabiUlDivModResult = undefined;106 return result;
68 result.quot = __udivmoddi4(numerator, denominator, &result.rem);
69 return result;
70 }
71
72 @setGlobalLinkage(__aeabi_uldivmod, builtin.GlobalLinkage.Internal);
73 unreachable;
74}107}
75108
76fn isArmArch() -> bool {109fn isArmArch() -> bool {
...@@ -98,156 +131,124 @@ fn isArmArch() -> bool {...@@ -98,156 +131,124 @@ fn isArmArch() -> bool {
98 };131 };
99}132}
100133
101export nakedcc fn __aeabi_uidivmod() {134nakedcc fn __aeabi_uidivmod() {
102 @setDebugSafety(this, false);135 @setDebugSafety(this, false);
103136 asm volatile (
104 if (comptime isArmArch()) {137 \\ push { lr }
105 @setGlobalLinkage(__aeabi_uidivmod, linkage);138 \\ sub sp, sp, #4
106 asm volatile (139 \\ mov r2, sp
107 \\ push { lr }140 \\ bl __udivmodsi4
108 \\ sub sp, sp, #4141 \\ ldr r1, [sp]
109 \\ mov r2, sp142 \\ add sp, sp, #4
110 \\ bl __udivmodsi4143 \\ pop { pc }
111 \\ ldr r1, [sp]144 ::: "r2", "r1");
112 \\ add sp, sp, #4
113 \\ pop { pc }
114 ::: "r2", "r1");
115 unreachable;
116 }
117
118 @setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.Internal);
119}145}
120146
121// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,147// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,
122// then decrement %esp by %eax. Preserves all registers except %esp and flags.148// then decrement %esp by %eax. Preserves all registers except %esp and flags.
123// This routine is windows specific149// This routine is windows specific
124// http://msdn.microsoft.com/en-us/library/ms648426.aspx150// http://msdn.microsoft.com/en-us/library/ms648426.aspx
125export nakedcc fn _chkstk() align(4) {151nakedcc fn _chkstk() align(4) {
126 @setDebugSafety(this, false);152 @setDebugSafety(this, false);
127153
128 if (win32_nocrt) {154 asm volatile (
129 @setGlobalLinkage(_chkstk, strong_linkage);155 \\ push %%ecx
130 asm volatile (156 \\ push %%eax
131 \\ push %%ecx157 \\ cmp $0x1000,%%eax
132 \\ push %%eax158 \\ lea 12(%%esp),%%ecx
133 \\ cmp $0x1000,%%eax159 \\ jb 1f
134 \\ lea 12(%%esp),%%ecx160 \\ 2:
135 \\ jb 1f161 \\ sub $0x1000,%%ecx
136 \\ 2:162 \\ test %%ecx,(%%ecx)
137 \\ sub $0x1000,%%ecx163 \\ sub $0x1000,%%eax
138 \\ test %%ecx,(%%ecx)164 \\ cmp $0x1000,%%eax
139 \\ sub $0x1000,%%eax165 \\ ja 2b
140 \\ cmp $0x1000,%%eax166 \\ 1:
141 \\ ja 2b167 \\ sub %%eax,%%ecx
142 \\ 1:168 \\ test %%ecx,(%%ecx)
143 \\ sub %%eax,%%ecx169 \\ pop %%eax
144 \\ test %%ecx,(%%ecx)170 \\ pop %%ecx
145 \\ pop %%eax171 \\ ret
146 \\ pop %%ecx172 );
147 \\ ret
148 );
149 unreachable;
150 }
151
152 @setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal);
153}173}
154174
155export nakedcc fn __chkstk() align(4) {175nakedcc fn __chkstk() align(4) {
156 @setDebugSafety(this, false);176 @setDebugSafety(this, false);
157177
158 if (win64_nocrt) {178 asm volatile (
159 @setGlobalLinkage(__chkstk, strong_linkage);179 \\ push %%rcx
160 asm volatile (180 \\ push %%rax
161 \\ push %%rcx181 \\ cmp $0x1000,%%rax
162 \\ push %%rax182 \\ lea 24(%%rsp),%%rcx
163 \\ cmp $0x1000,%%rax183 \\ jb 1f
164 \\ lea 24(%%rsp),%%rcx184 \\2:
165 \\ jb 1f185 \\ sub $0x1000,%%rcx
166 \\2:186 \\ test %%rcx,(%%rcx)
167 \\ sub $0x1000,%%rcx187 \\ sub $0x1000,%%rax
168 \\ test %%rcx,(%%rcx)188 \\ cmp $0x1000,%%rax
169 \\ sub $0x1000,%%rax189 \\ ja 2b
170 \\ cmp $0x1000,%%rax190 \\1:
171 \\ ja 2b191 \\ sub %%rax,%%rcx
172 \\1:192 \\ test %%rcx,(%%rcx)
173 \\ sub %%rax,%%rcx193 \\ pop %%rax
174 \\ test %%rcx,(%%rcx)194 \\ pop %%rcx
175 \\ pop %%rax195 \\ ret
176 \\ pop %%rcx196 );
177 \\ ret
178 );
179 unreachable;
180 }
181
182 @setGlobalLinkage(__chkstk, builtin.GlobalLinkage.Internal);
183}197}
184198
185// _chkstk routine199// _chkstk routine
186// This routine is windows specific200// This routine is windows specific
187// http://msdn.microsoft.com/en-us/library/ms648426.aspx201// http://msdn.microsoft.com/en-us/library/ms648426.aspx
188export nakedcc fn __chkstk_ms() align(4) {202nakedcc fn __chkstk_ms() align(4) {
189 @setDebugSafety(this, false);203 @setDebugSafety(this, false);
190204
191 if (win32_nocrt) {205 asm volatile (
192 @setGlobalLinkage(__chkstk_ms, linkage);206 \\ push %%ecx
193 asm volatile (207 \\ push %%eax
194 \\ push %%ecx208 \\ cmp $0x1000,%%eax
195 \\ push %%eax209 \\ lea 12(%%esp),%%ecx
196 \\ cmp $0x1000,%%eax210 \\ jb 1f
197 \\ lea 12(%%esp),%%ecx211 \\ 2:
198 \\ jb 1f212 \\ sub $0x1000,%%ecx
199 \\ 2:213 \\ test %%ecx,(%%ecx)
200 \\ sub $0x1000,%%ecx214 \\ sub $0x1000,%%eax
201 \\ test %%ecx,(%%ecx)215 \\ cmp $0x1000,%%eax
202 \\ sub $0x1000,%%eax216 \\ ja 2b
203 \\ cmp $0x1000,%%eax217 \\ 1:
204 \\ ja 2b218 \\ sub %%eax,%%ecx
205 \\ 1:219 \\ test %%ecx,(%%ecx)
206 \\ sub %%eax,%%ecx220 \\ pop %%eax
207 \\ test %%ecx,(%%ecx)221 \\ pop %%ecx
208 \\ pop %%eax222 \\ ret
209 \\ pop %%ecx223 );
210 \\ ret
211 );
212 unreachable;
213 }
214
215 @setGlobalLinkage(__chkstk_ms, builtin.GlobalLinkage.Internal);
216}224}
217225
218export nakedcc fn ___chkstk_ms() align(4) {226nakedcc fn ___chkstk_ms() align(4) {
219 @setDebugSafety(this, false);227 @setDebugSafety(this, false);
220228
221 if (win64_nocrt) {229 asm volatile (
222 @setGlobalLinkage(___chkstk_ms, linkage);230 \\ push %%rcx
223 asm volatile (231 \\ push %%rax
224 \\ push %%rcx232 \\ cmp $0x1000,%%rax
225 \\ push %%rax233 \\ lea 24(%%rsp),%%rcx
226 \\ cmp $0x1000,%%rax234 \\ jb 1f
227 \\ lea 24(%%rsp),%%rcx235 \\2:
228 \\ jb 1f236 \\ sub $0x1000,%%rcx
229 \\2:237 \\ test %%rcx,(%%rcx)
230 \\ sub $0x1000,%%rcx238 \\ sub $0x1000,%%rax
231 \\ test %%rcx,(%%rcx)239 \\ cmp $0x1000,%%rax
232 \\ sub $0x1000,%%rax240 \\ ja 2b
233 \\ cmp $0x1000,%%rax241 \\1:
234 \\ ja 2b242 \\ sub %%rax,%%rcx
235 \\1:243 \\ test %%rcx,(%%rcx)
236 \\ sub %%rax,%%rcx244 \\ pop %%rax
237 \\ test %%rcx,(%%rcx)245 \\ pop %%rcx
238 \\ pop %%rax246 \\ ret
239 \\ pop %%rcx247 );
240 \\ ret
241 );
242 unreachable;
243 }
244
245 @setGlobalLinkage(___chkstk_ms, builtin.GlobalLinkage.Internal);
246}248}
247249
248export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {250extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
249 @setDebugSafety(this, is_test);251 @setDebugSafety(this, is_test);
250 @setGlobalLinkage(__udivmodsi4, linkage);
251252
252 const d = __udivsi3(a, b);253 const d = __udivsi3(a, b);
253 *rem = u32(i32(a) -% (i32(d) * i32(b)));254 *rem = u32(i32(a) -% (i32(d) * i32(b)));
...@@ -255,19 +256,8 @@ export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {...@@ -255,19 +256,8 @@ export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
255}256}
256257
257258
258// TODO make this an alias instead of an extra function call259extern fn __udivsi3(n: u32, d: u32) -> u32 {
259// https://github.com/andrewrk/zig/issues/256
260
261export fn __aeabi_uidiv(n: u32, d: u32) -> u32 {
262 @setDebugSafety(this, is_test);260 @setDebugSafety(this, is_test);
263 @setGlobalLinkage(__aeabi_uidiv, linkage);
264
265 return __udivsi3(n, d);
266}
267
268export fn __udivsi3(n: u32, d: u32) -> u32 {
269 @setDebugSafety(this, is_test);
270 @setGlobalLinkage(__udivsi3, linkage);
271261
272 const n_uword_bits: c_uint = u32.bit_count;262 const n_uword_bits: c_uint = u32.bit_count;
273 // special cases263 // special cases
...@@ -463,4 +453,3 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) {...@@ -463,4 +453,3 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) {
463 const q: u32 = __udivsi3(a, b);453 const q: u32 = __udivsi3(a, b);
464 assert(q == expected_q);454 assert(q == expected_q);
465}455}
466
std/special/compiler_rt/udivmoddi4.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const udivmod = @import("udivmod.zig").udivmod;1const udivmod = @import("udivmod.zig").udivmod;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 {4pub extern fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__udivmoddi4, linkage);
8 return udivmod(u64, a, b, maybe_rem);6 return udivmod(u64, a, b, maybe_rem);
9}7}
108
std/special/compiler_rt/udivmodti4.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const udivmod = @import("udivmod.zig").udivmod;1const udivmod = @import("udivmod.zig").udivmod;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 {4pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__udivmodti4, linkage);
8 return udivmod(u128, a, b, maybe_rem);6 return udivmod(u128, a, b, maybe_rem);
9}7}
108
std/special/compiler_rt/udivti3.zig+1-3
...@@ -1,9 +1,7 @@...@@ -1,9 +1,7 @@
1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __udivti3(a: u128, b: u128) -> u128 {4pub extern fn __udivti3(a: u128, b: u128) -> u128 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__udivti3, linkage);
8 return __udivmodti4(a, b, null);6 return __udivmodti4(a, b, null);
9}7}
std/special/compiler_rt/umodti3.zig+1-3
...@@ -1,10 +1,8 @@...@@ -1,10 +1,8 @@
1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __umodti3(a: u128, b: u128) -> u128 {4pub extern fn __umodti3(a: u128, b: u128) -> u128 {
6 @setDebugSafety(this, builtin.is_test);5 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__umodti3, linkage);
8 var r: u128 = undefined;6 var r: u128 = undefined;
9 _ = __udivmodti4(a, b, &r);7 _ = __udivmodti4(a, b, &r);
10 return r;8 return r;
test/cases/asm.zig+7-6
...@@ -2,23 +2,24 @@ const config = @import("builtin");...@@ -2,23 +2,24 @@ const config = @import("builtin");
2const assert = @import("std").debug.assert;2const assert = @import("std").debug.assert;
33
4comptime {4comptime {
5 @export("derp", derp);
5 if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {6 if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
6 asm volatile (7 asm volatile (
7 \\.globl aoeu;8 \\.globl my_aoeu_symbol_asdf;
8 \\.type aoeu, @function;9 \\.type my_aoeu_symbol_asdf, @function;
9 \\.set aoeu, derp;10 \\.set my_aoeu_symbol_asdf, derp;
10 );11 );
11 }12 }
12}13}
1314
14test "module level assembly" {15test "module level assembly" {
15 if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {16 if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
16 assert(aoeu() == 1234);17 assert(my_aoeu_symbol_asdf() == 1234);
17 }18 }
18}19}
1920
20extern fn aoeu() -> i32;21extern fn my_aoeu_symbol_asdf() -> i32;
2122
22export fn derp() -> i32 {23extern fn derp() -> i32 {
23 return 1234;24 return 1234;
24}25}
test/cases/misc.zig+20-3
...@@ -12,8 +12,10 @@ test "empty function with comments" {...@@ -12,8 +12,10 @@ test "empty function with comments" {
12 emptyFunctionWithComments();12 emptyFunctionWithComments();
13}13}
1414
15export fn disabledExternFn() {15comptime {
16 @setGlobalLinkage(disabledExternFn, builtin.GlobalLinkage.Internal);16 @exportWithLinkage("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal)
17}
18extern fn disabledExternFn() {
17}19}
1820
19test "call disabled extern fn" {21test "call disabled extern fn" {
...@@ -533,7 +535,10 @@ var global_ptr = &gdt[0];...@@ -533,7 +535,10 @@ var global_ptr = &gdt[0];
533// can't really run this test but we can make sure it has no compile error535// can't really run this test but we can make sure it has no compile error
534// and generates code536// and generates code
535const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000];537const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000];
536export fn writeToVRam() {538comptime {
539 @export("writeToVRam", writeToVRam);
540}
541extern fn writeToVRam() {
537 vram[0] = 'X';542 vram[0] = 'X';
538}543}
539544
...@@ -557,3 +562,15 @@ fn hereIsAnOpaqueType(ptr: &OpaqueA) -> &OpaqueA {...@@ -557,3 +562,15 @@ fn hereIsAnOpaqueType(ptr: &OpaqueA) -> &OpaqueA {
557 var a = ptr;562 var a = ptr;
558 return a;563 return a;
559}564}
565
566test "function and variable in weird section" {
567 if (builtin.os == builtin.Os.linux or builtin.os == builtin.Os.windows) {
568 // macos can't handle this
569 assert(fnInWeirdSection() == 1234);
570 }
571}
572
573var varInWeirdSection: i32 section(".data2") = 1234;
574fn fnInWeirdSection() section(".text2") -> i32 {
575 return varInWeirdSection;
576}
test/compare_output.zig+11-5
...@@ -4,7 +4,8 @@ const tests = @import("tests.zig");...@@ -4,7 +4,8 @@ const tests = @import("tests.zig");
4pub fn addCases(cases: &tests.CompareOutputContext) {4pub fn addCases(cases: &tests.CompareOutputContext) {
5 cases.addC("hello world with libc",5 cases.addC("hello world with libc",
6 \\const c = @cImport(@cInclude("stdio.h"));6 \\const c = @cImport(@cInclude("stdio.h"));
7 \\export fn main(argc: c_int, argv: &&u8) -> c_int {7 \\comptime { @export("main", main); }
8 \\extern fn main(argc: c_int, argv: &&u8) -> c_int {
8 \\ _ = c.puts(c"Hello, world!");9 \\ _ = c.puts(c"Hello, world!");
9 \\ return 0;10 \\ return 0;
10 \\}11 \\}
...@@ -137,7 +138,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -137,7 +138,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
137 \\ @cInclude("stdio.h");138 \\ @cInclude("stdio.h");
138 \\});139 \\});
139 \\140 \\
140 \\export fn main(argc: c_int, argv: &&u8) -> c_int {141 \\comptime { @export("main", main); }
142 \\extern fn main(argc: c_int, argv: &&u8) -> c_int {
141 \\ if (is_windows) {143 \\ if (is_windows) {
142 \\ // we want actual \n, not \r\n144 \\ // we want actual \n, not \r\n
143 \\ _ = c._setmode(1, c._O_BINARY);145 \\ _ = c._setmode(1, c._O_BINARY);
...@@ -282,7 +284,10 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -282,7 +284,10 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
282 cases.addC("expose function pointer to C land",284 cases.addC("expose function pointer to C land",
283 \\const c = @cImport(@cInclude("stdlib.h"));285 \\const c = @cImport(@cInclude("stdlib.h"));
284 \\286 \\
285 \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {287 \\comptime {
288 \\ @export("main", main);
289 \\}
290 \\extern fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {
286 \\ const a_int = @ptrCast(&align(1) i32, a ?? unreachable);291 \\ const a_int = @ptrCast(&align(1) i32, a ?? unreachable);
287 \\ const b_int = @ptrCast(&align(1) i32, b ?? unreachable);292 \\ const b_int = @ptrCast(&align(1) i32, b ?? unreachable);
288 \\ if (*a_int < *b_int) {293 \\ if (*a_int < *b_int) {
...@@ -294,7 +299,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -294,7 +299,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
294 \\ }299 \\ }
295 \\}300 \\}
296 \\301 \\
297 \\export fn main() -> c_int {302 \\extern fn main() -> c_int {
298 \\ var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };303 \\ var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
299 \\304 \\
300 \\ c.qsort(@ptrCast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn);305 \\ c.qsort(@ptrCast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn);
...@@ -322,7 +327,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -322,7 +327,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
322 \\ @cInclude("stdio.h");327 \\ @cInclude("stdio.h");
323 \\});328 \\});
324 \\329 \\
325 \\export fn main(argc: c_int, argv: &&u8) -> c_int {330 \\comptime { @export("main", main); }
331 \\extern fn main(argc: c_int, argv: &&u8) -> c_int {
326 \\ if (is_windows) {332 \\ if (is_windows) {
327 \\ // we want actual \n, not \r\n333 \\ // we want actual \n, not \r\n
328 \\ _ = c._setmode(1, c._O_BINARY);334 \\ _ = c._setmode(1, c._O_BINARY);
test/compile_errors.zig+535-287
...@@ -1,253 +1,328 @@...@@ -1,253 +1,328 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: &tests.CompileErrorContext) {3pub fn addCases(cases: &tests.CompileErrorContext) {
4 cases.add("wrong return type for main",
5 \\pub fn main() { }
6 , ".tmp_source.zig:1:15: error: expected return type of main to be '%void', instead is 'void'");
7
8 cases.add("double ?? on main return value",
9 \\pub fn main() -> ??void {
10 \\}
11 , ".tmp_source.zig:1:18: error: expected return type of main to be '%void', instead is '??void'");
12
13 cases.add("setting a section on an extern variable",
14 \\extern var foo: i32 section(".text2");
15 \\extern fn entry() -> i32 {
16 \\ return foo;
17 \\}
18 \\comptime { @export("entry", entry); }
19 ,
20 ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'");
21
22 cases.add("setting a section on a local variable",
23 \\extern fn entry() -> i32 {
24 \\ var foo: i32 section(".text2") = 1234;
25 \\ return foo;
26 \\}
27 \\comptime { @export("entry", entry); }
28 ,
29 ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'");
30
31 cases.add("setting a section on an extern fn",
32 \\extern fn foo() section(".text2");
33 \\extern fn entry() {
34 \\ foo();
35 \\}
36 \\comptime { @export("entry", entry); }
37 ,
38 ".tmp_source.zig:1:25: error: cannot set section of external function 'foo'");
39
40 cases.add("wrong types given to exportWithLinkage",
41 \\extern fn entry() { }
42 \\comptime {
43 \\ @exportWithLinkage("entry", entry, u32(1234));
44 \\}
45 ,
46 ".tmp_source.zig:3:43: error: expected type 'GlobalLinkage', found 'u32'");
47
4 cases.add("implicit semicolon - block statement",48 cases.add("implicit semicolon - block statement",
5 \\export fn entry() {49 \\extern fn entry() {
6 \\ {}50 \\ {}
7 \\ var good = {};51 \\ var good = {};
8 \\ ({})52 \\ ({})
9 \\ var bad = {};53 \\ var bad = {};
10 \\}54 \\}
55 \\comptime {@export("entry", entry);}
11 , ".tmp_source.zig:5:5: error: invalid token: 'var'");56 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
1257
13 cases.add("implicit semicolon - block expr",58 cases.add("implicit semicolon - block expr",
14 \\export fn entry() {59 \\extern fn entry() {
15 \\ _ = {};60 \\ _ = {};
16 \\ var good = {};61 \\ var good = {};
17 \\ _ = {}62 \\ _ = {}
18 \\ var bad = {};63 \\ var bad = {};
19 \\}64 \\}
65 \\comptime {@export("entry", entry);}
20 , ".tmp_source.zig:5:5: error: invalid token: 'var'");66 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
2167
22 cases.add("implicit semicolon - comptime statement",68 cases.add("implicit semicolon - comptime statement",
23 \\export fn entry() {69 \\extern fn entry() {
24 \\ comptime {}70 \\ comptime {}
25 \\ var good = {};71 \\ var good = {};
26 \\ comptime ({})72 \\ comptime ({})
27 \\ var bad = {};73 \\ var bad = {};
28 \\}74 \\}
75 \\comptime {@export("entry", entry);}
29 , ".tmp_source.zig:5:5: error: invalid token: 'var'");76 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
3077
31 cases.add("implicit semicolon - comptime expression",78 cases.add("implicit semicolon - comptime expression",
32 \\export fn entry() {79 \\extern fn entry() {
33 \\ _ = comptime {};80 \\ _ = comptime {};
34 \\ var good = {};81 \\ var good = {};
35 \\ _ = comptime {}82 \\ _ = comptime {}
36 \\ var bad = {};83 \\ var bad = {};
37 \\}84 \\}
85 \\comptime {@export("entry", entry);}
38 , ".tmp_source.zig:5:5: error: invalid token: 'var'");86 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
3987
40 cases.add("implicit semicolon - defer",88 cases.add("implicit semicolon - defer",
41 \\export fn entry() {89 \\extern fn entry() {
42 \\ defer {}90 \\ defer {}
43 \\ var good = {};91 \\ var good = {};
44 \\ defer ({})92 \\ defer ({})
45 \\ var bad = {};93 \\ var bad = {};
46 \\}94 \\}
95 \\comptime {@export("entry", entry);}
47 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");96 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
4897
49 cases.add("implicit semicolon - if statement",98 cases.add("implicit semicolon - if statement",
50 \\export fn entry() {99 \\extern fn entry() {
51 \\ if(true) {}100 \\ if(true) {}
52 \\ var good = {};101 \\ var good = {};
53 \\ if(true) ({})102 \\ if(true) ({})
54 \\ var bad = {};103 \\ var bad = {};
55 \\}104 \\}
105 \\comptime {@export("entry", entry);}
56 , ".tmp_source.zig:5:5: error: invalid token: 'var'");106 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
57107
58 cases.add("implicit semicolon - if expression",108 cases.add("implicit semicolon - if expression",
59 \\export fn entry() {109 \\extern fn entry() {
60 \\ _ = if(true) {};110 \\ _ = if(true) {};
61 \\ var good = {};111 \\ var good = {};
62 \\ _ = if(true) {}112 \\ _ = if(true) {}
63 \\ var bad = {};113 \\ var bad = {};
64 \\}114 \\}
115 \\comptime {@export("entry", entry);}
65 , ".tmp_source.zig:5:5: error: invalid token: 'var'");116 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
66117
67 cases.add("implicit semicolon - if-else statement",118 cases.add("implicit semicolon - if-else statement",
68 \\export fn entry() {119 \\extern fn entry() {
69 \\ if(true) {} else {}120 \\ if(true) {} else {}
70 \\ var good = {};121 \\ var good = {};
71 \\ if(true) ({}) else ({})122 \\ if(true) ({}) else ({})
72 \\ var bad = {};123 \\ var bad = {};
73 \\}124 \\}
125 \\comptime {@export("entry", entry);}
74 , ".tmp_source.zig:5:5: error: invalid token: 'var'");126 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
75127
76 cases.add("implicit semicolon - if-else expression",128 cases.add("implicit semicolon - if-else expression",
77 \\export fn entry() {129 \\extern fn entry() {
78 \\ _ = if(true) {} else {};130 \\ _ = if(true) {} else {};
79 \\ var good = {};131 \\ var good = {};
80 \\ _ = if(true) {} else {}132 \\ _ = if(true) {} else {}
81 \\ var bad = {};133 \\ var bad = {};
82 \\}134 \\}
135 \\comptime {@export("entry", entry);}
83 , ".tmp_source.zig:5:5: error: invalid token: 'var'");136 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
84137
85 cases.add("implicit semicolon - if-else-if statement",138 cases.add("implicit semicolon - if-else-if statement",
86 \\export fn entry() {139 \\extern fn entry() {
87 \\ if(true) {} else if(true) {}140 \\ if(true) {} else if(true) {}
88 \\ var good = {};141 \\ var good = {};
89 \\ if(true) ({}) else if(true) ({})142 \\ if(true) ({}) else if(true) ({})
90 \\ var bad = {};143 \\ var bad = {};
91 \\}144 \\}
145 \\comptime {@export("entry", entry);}
92 , ".tmp_source.zig:5:5: error: invalid token: 'var'");146 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
93147
94 cases.add("implicit semicolon - if-else-if expression",148 cases.add("implicit semicolon - if-else-if expression",
95 \\export fn entry() {149 \\extern fn entry() {
96 \\ _ = if(true) {} else if(true) {};150 \\ _ = if(true) {} else if(true) {};
97 \\ var good = {};151 \\ var good = {};
98 \\ _ = if(true) {} else if(true) {}152 \\ _ = if(true) {} else if(true) {}
99 \\ var bad = {};153 \\ var bad = {};
100 \\}154 \\}
155 \\comptime {@export("entry", entry);}
101 , ".tmp_source.zig:5:5: error: invalid token: 'var'");156 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
102157
103 cases.add("implicit semicolon - if-else-if-else statement",158 cases.add("implicit semicolon - if-else-if-else statement",
104 \\export fn entry() {159 \\extern fn entry() {
105 \\ if(true) {} else if(true) {} else {}160 \\ if(true) {} else if(true) {} else {}
106 \\ var good = {};161 \\ var good = {};
107 \\ if(true) ({}) else if(true) ({}) else ({})162 \\ if(true) ({}) else if(true) ({}) else ({})
108 \\ var bad = {};163 \\ var bad = {};
109 \\}164 \\}
165 \\comptime {@export("entry", entry);}
110 , ".tmp_source.zig:5:5: error: invalid token: 'var'");166 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
111167
112 cases.add("implicit semicolon - if-else-if-else expression",168 cases.add("implicit semicolon - if-else-if-else expression",
113 \\export fn entry() {169 \\extern fn entry() {
114 \\ _ = if(true) {} else if(true) {} else {};170 \\ _ = if(true) {} else if(true) {} else {};
115 \\ var good = {};171 \\ var good = {};
116 \\ _ = if(true) {} else if(true) {} else {}172 \\ _ = if(true) {} else if(true) {} else {}
117 \\ var bad = {};173 \\ var bad = {};
118 \\}174 \\}
175 \\comptime {@export("entry", entry);}
119 , ".tmp_source.zig:5:5: error: invalid token: 'var'");176 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
120177
121 cases.add("implicit semicolon - test statement",178 cases.add("implicit semicolon - test statement",
122 \\export fn entry() {179 \\extern fn entry() {
123 \\ if (foo()) |_| {}180 \\ if (foo()) |_| {}
124 \\ var good = {};181 \\ var good = {};
125 \\ if (foo()) |_| ({})182 \\ if (foo()) |_| ({})
126 \\ var bad = {};183 \\ var bad = {};
127 \\}184 \\}
185 \\comptime {@export("entry", entry);}
128 , ".tmp_source.zig:5:5: error: invalid token: 'var'");186 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
129187
130 cases.add("implicit semicolon - test expression",188 cases.add("implicit semicolon - test expression",
131 \\export fn entry() {189 \\extern fn entry() {
132 \\ _ = if (foo()) |_| {};190 \\ _ = if (foo()) |_| {};
133 \\ var good = {};191 \\ var good = {};
134 \\ _ = if (foo()) |_| {}192 \\ _ = if (foo()) |_| {}
135 \\ var bad = {};193 \\ var bad = {};
136 \\}194 \\}
195 \\comptime {@export("entry", entry);}
137 , ".tmp_source.zig:5:5: error: invalid token: 'var'");196 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
138197
139 cases.add("implicit semicolon - while statement",198 cases.add("implicit semicolon - while statement",
140 \\export fn entry() {199 \\extern fn entry() {
141 \\ while(true) {}200 \\ while(true) {}
142 \\ var good = {};201 \\ var good = {};
143 \\ while(true) ({})202 \\ while(true) ({})
144 \\ var bad = {};203 \\ var bad = {};
145 \\}204 \\}
205 \\comptime {@export("entry", entry);}
146 , ".tmp_source.zig:5:5: error: invalid token: 'var'");206 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
147207
148 cases.add("implicit semicolon - while expression",208 cases.add("implicit semicolon - while expression",
149 \\export fn entry() {209 \\extern fn entry() {
150 \\ _ = while(true) {};210 \\ _ = while(true) {};
151 \\ var good = {};211 \\ var good = {};
152 \\ _ = while(true) {}212 \\ _ = while(true) {}
153 \\ var bad = {};213 \\ var bad = {};
154 \\}214 \\}
215 \\comptime {@export("entry", entry);}
155 , ".tmp_source.zig:5:5: error: invalid token: 'var'");216 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
156217
157 cases.add("implicit semicolon - while-continue statement",218 cases.add("implicit semicolon - while-continue statement",
158 \\export fn entry() {219 \\extern fn entry() {
159 \\ while(true):({}) {}220 \\ while(true):({}) {}
160 \\ var good = {};221 \\ var good = {};
161 \\ while(true):({}) ({})222 \\ while(true):({}) ({})
162 \\ var bad = {};223 \\ var bad = {};
163 \\}224 \\}
225 \\comptime {@export("entry", entry);}
164 , ".tmp_source.zig:5:5: error: invalid token: 'var'");226 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
165227
166 cases.add("implicit semicolon - while-continue expression",228 cases.add("implicit semicolon - while-continue expression",
167 \\export fn entry() {229 \\extern fn entry() {
168 \\ _ = while(true):({}) {};230 \\ _ = while(true):({}) {};
169 \\ var good = {};231 \\ var good = {};
170 \\ _ = while(true):({}) {}232 \\ _ = while(true):({}) {}
171 \\ var bad = {};233 \\ var bad = {};
172 \\}234 \\}
235 \\comptime {@export("entry", entry);}
173 , ".tmp_source.zig:5:5: error: invalid token: 'var'");236 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
174237
175 cases.add("implicit semicolon - for statement",238 cases.add("implicit semicolon - for statement",
176 \\export fn entry() {239 \\extern fn entry() {
177 \\ for(foo()) {}240 \\ for(foo()) {}
178 \\ var good = {};241 \\ var good = {};
179 \\ for(foo()) ({})242 \\ for(foo()) ({})
180 \\ var bad = {};243 \\ var bad = {};
181 \\}244 \\}
245 \\comptime {@export("entry", entry);}
182 , ".tmp_source.zig:5:5: error: invalid token: 'var'");246 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
183247
184 cases.add("implicit semicolon - for expression",248 cases.add("implicit semicolon - for expression",
185 \\export fn entry() {249 \\extern fn entry() {
186 \\ _ = for(foo()) {};250 \\ _ = for(foo()) {};
187 \\ var good = {};251 \\ var good = {};
188 \\ _ = for(foo()) {}252 \\ _ = for(foo()) {}
189 \\ var bad = {};253 \\ var bad = {};
190 \\}254 \\}
255 \\comptime {@export("entry", entry);}
191 , ".tmp_source.zig:5:5: error: invalid token: 'var'");256 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
192257
193 cases.add("multiple function definitions",258 cases.add("multiple function definitions",
194 \\fn a() {}259 \\fn a() {}
195 \\fn a() {}260 \\fn a() {}
196 \\export fn entry() { a(); }261 \\comptime {@export("entry", entry);}
262 \\extern fn entry() { a(); }
197 , ".tmp_source.zig:2:1: error: redefinition of 'a'");263 , ".tmp_source.zig:2:1: error: redefinition of 'a'");
198264
199 cases.add("unreachable with return",265 cases.add("unreachable with return",
200 \\fn a() -> noreturn {return;}266 \\fn a() -> noreturn {return;}
201 \\export fn entry() { a(); }267 \\comptime {@export("entry", entry);}
268 \\extern fn entry() { a(); }
202 , ".tmp_source.zig:1:21: error: expected type 'noreturn', found 'void'");269 , ".tmp_source.zig:1:21: error: expected type 'noreturn', found 'void'");
203270
204 cases.add("control reaches end of non-void function",271 cases.add("control reaches end of non-void function",
205 \\fn a() -> i32 {}272 \\fn a() -> i32 {}
206 \\export fn entry() { _ = a(); }273 \\comptime {@export("entry", entry);}
274 \\extern fn entry() { _ = a(); }
207 , ".tmp_source.zig:1:15: error: expected type 'i32', found 'void'");275 , ".tmp_source.zig:1:15: error: expected type 'i32', found 'void'");
208276
209 cases.add("undefined function call",277 cases.add("undefined function call",
210 \\export fn a() {278 \\extern fn a() {
211 \\ b();279 \\ b();
212 \\}280 \\}
281 \\comptime {@export("a", a);}
213 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");282 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
214283
215 cases.add("wrong number of arguments",284 cases.add("wrong number of arguments",
216 \\export fn a() {285 \\extern fn a() {
217 \\ b(1);286 \\ b(1);
218 \\}287 \\}
219 \\fn b(a: i32, b: i32, c: i32) { }288 \\fn b(a: i32, b: i32, c: i32) { }
289 \\comptime {@export("a", a);}
220 , ".tmp_source.zig:2:6: error: expected 3 arguments, found 1");290 , ".tmp_source.zig:2:6: error: expected 3 arguments, found 1");
221291
222 cases.add("invalid type",292 cases.add("invalid type",
223 \\fn a() -> bogus {}293 \\fn a() -> bogus {}
224 \\export fn entry() { _ = a(); }294 \\comptime {@export("entry", entry);}
295 \\extern fn entry() { _ = a(); }
225 , ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'");296 , ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'");
226297
227 cases.add("pointer to unreachable",298 cases.add("pointer to unreachable",
228 \\fn a() -> &noreturn {}299 \\fn a() -> &noreturn {}
229 \\export fn entry() { _ = a(); }300 \\comptime {@export("entry", entry);}
301 \\extern fn entry() { _ = a(); }
230 , ".tmp_source.zig:1:12: error: pointer to unreachable not allowed");302 , ".tmp_source.zig:1:12: error: pointer to unreachable not allowed");
231303
232 cases.add("unreachable code",304 cases.add("unreachable code",
233 \\export fn a() {305 \\extern fn a() {
234 \\ return;306 \\ return;
235 \\ b();307 \\ b();
236 \\}308 \\}
237 \\309 \\
238 \\fn b() {}310 \\fn b() {}
311 \\comptime {@export("a", a);}
239 , ".tmp_source.zig:3:5: error: unreachable code");312 , ".tmp_source.zig:3:5: error: unreachable code");
240313
241 cases.add("bad import",314 cases.add("bad import",
242 \\const bogus = @import("bogus-does-not-exist.zig");315 \\const bogus = @import("bogus-does-not-exist.zig");
243 \\export fn entry() { bogus.bogo(); }316 \\comptime {@export("entry", entry);}
317 \\extern fn entry() { bogus.bogo(); }
244 , ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'");318 , ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'");
245319
246 cases.add("undeclared identifier",320 cases.add("undeclared identifier",
247 \\export fn a() {321 \\extern fn a() {
248 \\ b +322 \\ b +
249 \\ c323 \\ c
250 \\}324 \\}
325 \\comptime {@export("a", a);}
251 ,326 ,
252 ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'",327 ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'",
253 ".tmp_source.zig:3:5: error: use of undeclared identifier 'c'");328 ".tmp_source.zig:3:5: error: use of undeclared identifier 'c'");
...@@ -255,99 +330,114 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -255,99 +330,114 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
255 cases.add("parameter redeclaration",330 cases.add("parameter redeclaration",
256 \\fn f(a : i32, a : i32) {331 \\fn f(a : i32, a : i32) {
257 \\}332 \\}
258 \\export fn entry() { f(1, 2); }333 \\comptime {@export("entry", entry);}
334 \\extern fn entry() { f(1, 2); }
259 , ".tmp_source.zig:1:15: error: redeclaration of variable 'a'");335 , ".tmp_source.zig:1:15: error: redeclaration of variable 'a'");
260336
261 cases.add("local variable redeclaration",337 cases.add("local variable redeclaration",
262 \\export fn f() {338 \\extern fn f() {
263 \\ const a : i32 = 0;339 \\ const a : i32 = 0;
264 \\ const a = 0;340 \\ const a = 0;
265 \\}341 \\}
342 \\comptime {@export("f", f);}
266 , ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");343 , ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
267344
268 cases.add("local variable redeclares parameter",345 cases.add("local variable redeclares parameter",
269 \\fn f(a : i32) {346 \\fn f(a : i32) {
270 \\ const a = 0;347 \\ const a = 0;
271 \\}348 \\}
272 \\export fn entry() { f(1); }349 \\comptime {@export("entry", entry);}
350 \\extern fn entry() { f(1); }
273 , ".tmp_source.zig:2:5: error: redeclaration of variable 'a'");351 , ".tmp_source.zig:2:5: error: redeclaration of variable 'a'");
274352
275 cases.add("variable has wrong type",353 cases.add("variable has wrong type",
276 \\export fn f() -> i32 {354 \\extern fn f() -> i32 {
277 \\ const a = c"a";355 \\ const a = c"a";
278 \\ a356 \\ a
279 \\}357 \\}
358 \\comptime {@export("f", f);}
280 , ".tmp_source.zig:3:5: error: expected type 'i32', found '&const u8'");359 , ".tmp_source.zig:3:5: error: expected type 'i32', found '&const u8'");
281360
282 cases.add("if condition is bool, not int",361 cases.add("if condition is bool, not int",
283 \\export fn f() {362 \\extern fn f() {
284 \\ if (0) {}363 \\ if (0) {}
285 \\}364 \\}
365 \\comptime {@export("f", f);}
286 , ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'");366 , ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'");
287367
288 cases.add("assign unreachable",368 cases.add("assign unreachable",
289 \\export fn f() {369 \\extern fn f() {
290 \\ const a = return;370 \\ const a = return;
291 \\}371 \\}
372 \\comptime {@export("f", f);}
292 , ".tmp_source.zig:2:5: error: unreachable code");373 , ".tmp_source.zig:2:5: error: unreachable code");
293374
294 cases.add("unreachable variable",375 cases.add("unreachable variable",
295 \\export fn f() {376 \\extern fn f() {
296 \\ const a: noreturn = {};377 \\ const a: noreturn = {};
297 \\}378 \\}
379 \\comptime {@export("f", f);}
298 , ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed");380 , ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed");
299381
300 cases.add("unreachable parameter",382 cases.add("unreachable parameter",
301 \\fn f(a: noreturn) {}383 \\fn f(a: noreturn) {}
302 \\export fn entry() { f(); }384 \\comptime {@export("entry", entry);}
385 \\extern fn entry() { f(); }
303 , ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed");386 , ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed");
304387
305 cases.add("bad assignment target",388 cases.add("bad assignment target",
306 \\export fn f() {389 \\extern fn f() {
307 \\ 3 = 3;390 \\ 3 = 3;
308 \\}391 \\}
392 \\comptime {@export("f", f);}
309 , ".tmp_source.zig:2:7: error: cannot assign to constant");393 , ".tmp_source.zig:2:7: error: cannot assign to constant");
310394
311 cases.add("assign to constant variable",395 cases.add("assign to constant variable",
312 \\export fn f() {396 \\extern fn f() {
313 \\ const a = 3;397 \\ const a = 3;
314 \\ a = 4;398 \\ a = 4;
315 \\}399 \\}
400 \\comptime {@export("f", f);}
316 , ".tmp_source.zig:3:7: error: cannot assign to constant");401 , ".tmp_source.zig:3:7: error: cannot assign to constant");
317402
318 cases.add("use of undeclared identifier",403 cases.add("use of undeclared identifier",
319 \\export fn f() {404 \\extern fn f() {
320 \\ b = 3;405 \\ b = 3;
321 \\}406 \\}
407 \\comptime {@export("f", f);}
322 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");408 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
323409
324 cases.add("const is a statement, not an expression",410 cases.add("const is a statement, not an expression",
325 \\export fn f() {411 \\extern fn f() {
326 \\ (const a = 0);412 \\ (const a = 0);
327 \\}413 \\}
414 \\comptime {@export("f", f);}
328 , ".tmp_source.zig:2:6: error: invalid token: 'const'");415 , ".tmp_source.zig:2:6: error: invalid token: 'const'");
329416
330 cases.add("array access of undeclared identifier",417 cases.add("array access of undeclared identifier",
331 \\export fn f() {418 \\extern fn f() {
332 \\ i[i] = i[i];419 \\ i[i] = i[i];
333 \\}420 \\}
421 \\comptime {@export("f", f);}
334 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",422 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",
335 ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'");423 ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'");
336424
337 cases.add("array access of non array",425 cases.add("array access of non array",
338 \\export fn f() {426 \\extern fn f() {
339 \\ var bad : bool = undefined;427 \\ var bad : bool = undefined;
340 \\ bad[bad] = bad[bad];428 \\ bad[bad] = bad[bad];
341 \\}429 \\}
430 \\comptime {@export("f", f);}
342 , ".tmp_source.zig:3:8: error: array access of non-array type 'bool'",431 , ".tmp_source.zig:3:8: error: array access of non-array type 'bool'",
343 ".tmp_source.zig:3:19: error: array access of non-array type 'bool'");432 ".tmp_source.zig:3:19: error: array access of non-array type 'bool'");
344433
345 cases.add("array access with non integer index",434 cases.add("array access with non integer index",
346 \\export fn f() {435 \\extern fn f() {
347 \\ var array = "aoeu";436 \\ var array = "aoeu";
348 \\ var bad = false;437 \\ var bad = false;
349 \\ array[bad] = array[bad];438 \\ array[bad] = array[bad];
350 \\}439 \\}
440 \\comptime {@export("f", f);}
351 , ".tmp_source.zig:4:11: error: expected type 'usize', found 'bool'",441 , ".tmp_source.zig:4:11: error: expected type 'usize', found 'bool'",
352 ".tmp_source.zig:4:24: error: expected type 'usize', found 'bool'");442 ".tmp_source.zig:4:24: error: expected type 'usize', found 'bool'");
353443
...@@ -356,7 +446,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -356,7 +446,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
356 \\fn f() {446 \\fn f() {
357 \\ x = 1;447 \\ x = 1;
358 \\}448 \\}
359 \\export fn entry() { f(); }449 \\extern fn entry() { f(); }
450 \\comptime {@export("entry", entry);}
360 , ".tmp_source.zig:3:7: error: cannot assign to constant");451 , ".tmp_source.zig:3:7: error: cannot assign to constant");
361452
362453
...@@ -365,29 +456,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -365,29 +456,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
365 \\ const x : i32 = if (b) { 1 };456 \\ const x : i32 = if (b) { 1 };
366 \\ const y = if (b) { i32(1) };457 \\ const y = if (b) { i32(1) };
367 \\}458 \\}
368 \\export fn entry() { f(true); }459 \\extern fn entry() { f(true); }
460 \\comptime {@export("entry", entry);}
369 , ".tmp_source.zig:2:30: error: integer value 1 cannot be implicitly casted to type 'void'",461 , ".tmp_source.zig:2:30: error: integer value 1 cannot be implicitly casted to type 'void'",
370 ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'");462 ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'");
371463
372 cases.add("direct struct loop",464 cases.add("direct struct loop",
373 \\const A = struct { a : A, };465 \\const A = struct { a : A, };
374 \\export fn entry() -> usize { @sizeOf(A) }466 \\extern fn entry() -> usize { @sizeOf(A) }
467 \\comptime {@export("entry", entry);}
375 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");468 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
376469
377 cases.add("indirect struct loop",470 cases.add("indirect struct loop",
378 \\const A = struct { b : B, };471 \\const A = struct { b : B, };
379 \\const B = struct { c : C, };472 \\const B = struct { c : C, };
380 \\const C = struct { a : A, };473 \\const C = struct { a : A, };
381 \\export fn entry() -> usize { @sizeOf(A) }474 \\extern fn entry() -> usize { @sizeOf(A) }
475 \\comptime {@export("entry", entry);}
382 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");476 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
383477
384 cases.add("invalid struct field",478 cases.add("invalid struct field",
385 \\const A = struct { x : i32, };479 \\const A = struct { x : i32, };
386 \\export fn f() {480 \\extern fn f() {
387 \\ var a : A = undefined;481 \\ var a : A = undefined;
388 \\ a.foo = 1;482 \\ a.foo = 1;
389 \\ const y = a.bar;483 \\ const y = a.bar;
390 \\}484 \\}
485 \\comptime {@export("f", f);}
391 ,486 ,
392 ".tmp_source.zig:4:6: error: no member named 'foo' in struct 'A'",487 ".tmp_source.zig:4:6: error: no member named 'foo' in struct 'A'",
393 ".tmp_source.zig:5:16: error: no member named 'bar' in struct 'A'");488 ".tmp_source.zig:5:16: error: no member named 'bar' in struct 'A'");
...@@ -415,7 +510,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -415,7 +510,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
415 \\ y : i32,510 \\ y : i32,
416 \\ z : i32,511 \\ z : i32,
417 \\};512 \\};
418 \\export fn f() {513 \\extern fn f() {
419 \\ const a = A {514 \\ const a = A {
420 \\ .z = 1,515 \\ .z = 1,
421 \\ .y = 2,516 \\ .y = 2,
...@@ -423,6 +518,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -423,6 +518,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
423 \\ .z = 4,518 \\ .z = 4,
424 \\ };519 \\ };
425 \\}520 \\}
521 \\comptime {@export("f", f);}
426 , ".tmp_source.zig:11:9: error: duplicate field");522 , ".tmp_source.zig:11:9: error: duplicate field");
427523
428 cases.add("missing field in struct value expression",524 cases.add("missing field in struct value expression",
...@@ -431,7 +527,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -431,7 +527,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
431 \\ y : i32,527 \\ y : i32,
432 \\ z : i32,528 \\ z : i32,
433 \\};529 \\};
434 \\export fn f() {530 \\extern fn f() {
435 \\ // we want the error on the '{' not the 'A' because531 \\ // we want the error on the '{' not the 'A' because
436 \\ // the A could be a complicated expression532 \\ // the A could be a complicated expression
437 \\ const a = A {533 \\ const a = A {
...@@ -439,6 +535,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -439,6 +535,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
439 \\ .y = 2,535 \\ .y = 2,
440 \\ };536 \\ };
441 \\}537 \\}
538 \\comptime {@export("f", f);}
442 , ".tmp_source.zig:9:17: error: missing field: 'x'");539 , ".tmp_source.zig:9:17: error: missing field: 'x'");
443540
444 cases.add("invalid field in struct value expression",541 cases.add("invalid field in struct value expression",
...@@ -447,69 +544,79 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -447,69 +544,79 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
447 \\ y : i32,544 \\ y : i32,
448 \\ z : i32,545 \\ z : i32,
449 \\};546 \\};
450 \\export fn f() {547 \\extern fn f() {
451 \\ const a = A {548 \\ const a = A {
452 \\ .z = 4,549 \\ .z = 4,
453 \\ .y = 2,550 \\ .y = 2,
454 \\ .foo = 42,551 \\ .foo = 42,
455 \\ };552 \\ };
456 \\}553 \\}
554 \\comptime {@export("f", f);}
457 , ".tmp_source.zig:10:9: error: no member named 'foo' in struct 'A'");555 , ".tmp_source.zig:10:9: error: no member named 'foo' in struct 'A'");
458556
459 cases.add("invalid break expression",557 cases.add("invalid break expression",
460 \\export fn f() {558 \\extern fn f() {
461 \\ break;559 \\ break;
462 \\}560 \\}
561 \\comptime {@export("f", f);}
463 , ".tmp_source.zig:2:5: error: break expression outside loop");562 , ".tmp_source.zig:2:5: error: break expression outside loop");
464563
465 cases.add("invalid continue expression",564 cases.add("invalid continue expression",
466 \\export fn f() {565 \\extern fn f() {
467 \\ continue;566 \\ continue;
468 \\}567 \\}
568 \\comptime {@export("f", f);}
469 , ".tmp_source.zig:2:5: error: continue expression outside loop");569 , ".tmp_source.zig:2:5: error: continue expression outside loop");
470570
471 cases.add("invalid maybe type",571 cases.add("invalid maybe type",
472 \\export fn f() {572 \\extern fn f() {
473 \\ if (true) |x| { }573 \\ if (true) |x| { }
474 \\}574 \\}
575 \\comptime {@export("f", f);}
475 , ".tmp_source.zig:2:9: error: expected nullable type, found 'bool'");576 , ".tmp_source.zig:2:9: error: expected nullable type, found 'bool'");
476577
477 cases.add("cast unreachable",578 cases.add("cast unreachable",
478 \\fn f() -> i32 {579 \\fn f() -> i32 {
479 \\ i32(return 1)580 \\ i32(return 1)
480 \\}581 \\}
481 \\export fn entry() { _ = f(); }582 \\extern fn entry() { _ = f(); }
583 \\comptime {@export("entry", entry);}
482 , ".tmp_source.zig:2:8: error: unreachable code");584 , ".tmp_source.zig:2:8: error: unreachable code");
483585
484 cases.add("invalid builtin fn",586 cases.add("invalid builtin fn",
485 \\fn f() -> @bogus(foo) {587 \\fn f() -> @bogus(foo) {
486 \\}588 \\}
487 \\export fn entry() { _ = f(); }589 \\extern fn entry() { _ = f(); }
590 \\comptime {@export("entry", entry);}
488 , ".tmp_source.zig:1:11: error: invalid builtin function: 'bogus'");591 , ".tmp_source.zig:1:11: error: invalid builtin function: 'bogus'");
489592
490 cases.add("top level decl dependency loop",593 cases.add("top level decl dependency loop",
491 \\const a : @typeOf(b) = 0;594 \\const a : @typeOf(b) = 0;
492 \\const b : @typeOf(a) = 0;595 \\const b : @typeOf(a) = 0;
493 \\export fn entry() {596 \\extern fn entry() {
494 \\ const c = a + b;597 \\ const c = a + b;
495 \\}598 \\}
599 \\comptime {@export("entry", entry);}
496 , ".tmp_source.zig:1:1: error: 'a' depends on itself");600 , ".tmp_source.zig:1:1: error: 'a' depends on itself");
497601
498 cases.add("noalias on non pointer param",602 cases.add("noalias on non pointer param",
499 \\fn f(noalias x: i32) {}603 \\fn f(noalias x: i32) {}
500 \\export fn entry() { f(1234); }604 \\extern fn entry() { f(1234); }
605 \\comptime {@export("entry", entry);}
501 , ".tmp_source.zig:1:6: error: noalias on non-pointer parameter");606 , ".tmp_source.zig:1:6: error: noalias on non-pointer parameter");
502607
503 cases.add("struct init syntax for array",608 cases.add("struct init syntax for array",
504 \\const foo = []u16{.x = 1024,};609 \\const foo = []u16{.x = 1024,};
505 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }610 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
611 \\comptime {@export("entry", entry);}
506 , ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax");612 , ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax");
507613
508 cases.add("type variables must be constant",614 cases.add("type variables must be constant",
509 \\var foo = u8;615 \\var foo = u8;
510 \\export fn entry() -> foo {616 \\extern fn entry() -> foo {
511 \\ return 1;617 \\ return 1;
512 \\}618 \\}
619 \\comptime {@export("entry", entry);}
513 , ".tmp_source.zig:1:1: error: variable of type 'type' must be constant");620 , ".tmp_source.zig:1:1: error: variable of type 'type' must be constant");
514621
515622
...@@ -521,9 +628,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -521,9 +628,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
521 \\ var Bar : i32 = undefined;628 \\ var Bar : i32 = undefined;
522 \\}629 \\}
523 \\630 \\
524 \\export fn entry() {631 \\extern fn entry() {
525 \\ f(1234);632 \\ f(1234);
526 \\}633 \\}
634 \\comptime {@export("entry", entry);}
527 ,635 ,
528 ".tmp_source.zig:4:6: error: redefinition of 'Foo'",636 ".tmp_source.zig:4:6: error: redefinition of 'Foo'",
529 ".tmp_source.zig:1:1: note: previous definition is here",637 ".tmp_source.zig:1:1: note: previous definition is here",
...@@ -545,7 +653,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -545,7 +653,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
545 \\ }653 \\ }
546 \\}654 \\}
547 \\655 \\
548 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }656 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
657 \\comptime {@export("entry", entry);}
549 , ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch");658 , ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch");
550659
551 cases.add("switch expression - duplicate enumeration prong",660 cases.add("switch expression - duplicate enumeration prong",
...@@ -565,7 +674,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -565,7 +674,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
565 \\ }674 \\ }
566 \\}675 \\}
567 \\676 \\
568 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }677 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
678 \\comptime {@export("entry", entry);}
569 , ".tmp_source.zig:13:15: error: duplicate switch value",679 , ".tmp_source.zig:13:15: error: duplicate switch value",
570 ".tmp_source.zig:10:15: note: other value is here");680 ".tmp_source.zig:10:15: note: other value is here");
571681
...@@ -587,7 +697,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -587,7 +697,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
587 \\ }697 \\ }
588 \\}698 \\}
589 \\699 \\
590 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }700 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
701 \\comptime {@export("entry", entry);}
591 , ".tmp_source.zig:13:15: error: duplicate switch value",702 , ".tmp_source.zig:13:15: error: duplicate switch value",
592 ".tmp_source.zig:10:15: note: other value is here");703 ".tmp_source.zig:10:15: note: other value is here");
593704
...@@ -599,9 +710,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -599,9 +710,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
599 \\ else => true,710 \\ else => true,
600 \\ };711 \\ };
601 \\}712 \\}
602 \\export fn entry() {713 \\extern fn entry() {
603 \\ f(1234);714 \\ f(1234);
604 \\}715 \\}
716 \\comptime {@export("entry", entry);}
605 , ".tmp_source.zig:5:9: error: multiple else prongs in switch expression");717 , ".tmp_source.zig:5:9: error: multiple else prongs in switch expression");
606718
607 cases.add("switch expression - non exhaustive integer prongs",719 cases.add("switch expression - non exhaustive integer prongs",
...@@ -610,7 +722,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -610,7 +722,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
610 \\ 0 => {},722 \\ 0 => {},
611 \\ }723 \\ }
612 \\}724 \\}
613 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }725 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
726 \\comptime {@export("entry", entry);}
614 ,727 ,
615 ".tmp_source.zig:2:5: error: switch must handle all possibilities");728 ".tmp_source.zig:2:5: error: switch must handle all possibilities");
616729
...@@ -623,7 +736,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -623,7 +736,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
623 \\ 206 ... 255 => 3,736 \\ 206 ... 255 => 3,
624 \\ }737 \\ }
625 \\}738 \\}
626 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }739 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
740 \\comptime {@export("entry", entry);}
627 ,741 ,
628 ".tmp_source.zig:6:9: error: duplicate switch value",742 ".tmp_source.zig:6:9: error: duplicate switch value",
629 ".tmp_source.zig:5:14: note: previous value is here");743 ".tmp_source.zig:5:14: note: previous value is here");
...@@ -635,14 +749,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -635,14 +749,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
635 \\ }749 \\ }
636 \\}750 \\}
637 \\const y: u8 = 100;751 \\const y: u8 = 100;
638 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }752 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
753 \\comptime {@export("entry", entry);}
639 ,754 ,
640 ".tmp_source.zig:2:5: error: else prong required when switching on type '&u8'");755 ".tmp_source.zig:2:5: error: else prong required when switching on type '&u8'");
641756
642 cases.add("global variable initializer must be constant expression",757 cases.add("global variable initializer must be constant expression",
643 \\extern fn foo() -> i32;758 \\extern fn foo() -> i32;
644 \\const x = foo();759 \\const x = foo();
645 \\export fn entry() -> i32 { x }760 \\extern fn entry() -> i32 { x }
761 \\comptime {@export("entry", entry);}
646 , ".tmp_source.zig:2:11: error: unable to evaluate constant expression");762 , ".tmp_source.zig:2:11: error: unable to evaluate constant expression");
647763
648 cases.add("array concatenation with wrong type",764 cases.add("array concatenation with wrong type",
...@@ -650,7 +766,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -650,7 +766,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
650 \\const derp = usize(1234);766 \\const derp = usize(1234);
651 \\const a = derp ++ "foo";767 \\const a = derp ++ "foo";
652 \\768 \\
653 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }769 \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) }
770 \\comptime {@export("entry", entry);}
654 , ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'");771 , ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'");
655772
656 cases.add("non compile time array concatenation",773 cases.add("non compile time array concatenation",
...@@ -658,12 +775,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -658,12 +775,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
658 \\ s ++ "foo"775 \\ s ++ "foo"
659 \\}776 \\}
660 \\var s: [10]u8 = undefined;777 \\var s: [10]u8 = undefined;
661 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }778 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
779 \\comptime {@export("entry", entry);}
662 , ".tmp_source.zig:2:5: error: unable to evaluate constant expression");780 , ".tmp_source.zig:2:5: error: unable to evaluate constant expression");
663781
664 cases.add("@cImport with bogus include",782 cases.add("@cImport with bogus include",
665 \\const c = @cImport(@cInclude("bogus.h"));783 \\const c = @cImport(@cInclude("bogus.h"));
666 \\export fn entry() -> usize { @sizeOf(@typeOf(c.bogo)) }784 \\extern fn entry() -> usize { @sizeOf(@typeOf(c.bogo)) }
785 \\comptime {@export("entry", entry);}
667 , ".tmp_source.zig:1:11: error: C import failed",786 , ".tmp_source.zig:1:11: error: C import failed",
668 ".h:1:10: note: 'bogus.h' file not found");787 ".h:1:10: note: 'bogus.h' file not found");
669788
...@@ -671,17 +790,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -671,17 +790,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
671 \\const x = 3;790 \\const x = 3;
672 \\const y = &x;791 \\const y = &x;
673 \\fn foo() -> &const i32 { y }792 \\fn foo() -> &const i32 { y }
674 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }793 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
794 \\comptime {@export("entry", entry);}
675 , ".tmp_source.zig:3:26: error: expected type '&const i32', found '&const (integer literal)'");795 , ".tmp_source.zig:3:26: error: expected type '&const i32', found '&const (integer literal)'");
676796
677 cases.add("integer overflow error",797 cases.add("integer overflow error",
678 \\const x : u8 = 300;798 \\const x : u8 = 300;
679 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }799 \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) }
800 \\comptime {@export("entry", entry);}
680 , ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'");801 , ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'");
681802
682 cases.add("incompatible number literals",803 cases.add("incompatible number literals",
683 \\const x = 2 == 2.0;804 \\const x = 2 == 2.0;
684 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }805 \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) }
806 \\comptime {@export("entry", entry);}
685 , ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");807 , ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");
686808
687 cases.add("missing function call param",809 cases.add("missing function call param",
...@@ -707,13 +829,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -707,13 +829,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
707 \\ const result = members[index]();829 \\ const result = members[index]();
708 \\}830 \\}
709 \\831 \\
710 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }832 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
833 \\comptime {@export("entry", entry);}
711 , ".tmp_source.zig:20:34: error: expected 1 arguments, found 0");834 , ".tmp_source.zig:20:34: error: expected 1 arguments, found 0");
712835
713 cases.add("missing function name and param name",836 cases.add("missing function name and param name",
714 \\fn () {}837 \\fn () {}
715 \\fn f(i32) {}838 \\fn f(i32) {}
716 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }839 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
840 \\comptime {@export("entry", entry);}
717 ,841 ,
718 ".tmp_source.zig:1:1: error: missing function name",842 ".tmp_source.zig:1:1: error: missing function name",
719 ".tmp_source.zig:2:6: error: missing parameter name");843 ".tmp_source.zig:2:6: error: missing parameter name");
...@@ -723,16 +847,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -723,16 +847,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
723 \\fn a() -> i32 {0}847 \\fn a() -> i32 {0}
724 \\fn b() -> i32 {1}848 \\fn b() -> i32 {1}
725 \\fn c() -> i32 {2}849 \\fn c() -> i32 {2}
726 \\export fn entry() -> usize { @sizeOf(@typeOf(fns)) }850 \\extern fn entry() -> usize { @sizeOf(@typeOf(fns)) }
851 \\comptime {@export("entry", entry);}
727 , ".tmp_source.zig:1:21: error: expected type 'fn()', found 'fn() -> i32'");852 , ".tmp_source.zig:1:21: error: expected type 'fn()', found 'fn() -> i32'");
728853
729 cases.add("extern function pointer mismatch",854 cases.add("extern function pointer mismatch",
730 \\const fns = [](fn(i32)->i32){ a, b, c };855 \\const fns = [](fn(i32)->i32){ a, b, c };
731 \\pub fn a(x: i32) -> i32 {x + 0}856 \\pub fn a(x: i32) -> i32 {x + 0}
732 \\pub fn b(x: i32) -> i32 {x + 1}857 \\pub fn b(x: i32) -> i32 {x + 1}
733 \\export fn c(x: i32) -> i32 {x + 2}858 \\extern fn c(x: i32) -> i32 {x + 2}
859 \\
860 \\extern fn entry() -> usize { @sizeOf(@typeOf(fns)) }
734 \\861 \\
735 \\export fn entry() -> usize { @sizeOf(@typeOf(fns)) }862 \\comptime {@export("entry", entry);}
863 \\comptime {@export("c", c);}
736 , ".tmp_source.zig:1:37: error: expected type 'fn(i32) -> i32', found 'extern fn(i32) -> i32'");864 , ".tmp_source.zig:1:37: error: expected type 'fn(i32) -> i32', found 'extern fn(i32) -> i32'");
737865
738866
...@@ -740,14 +868,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -740,14 +868,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
740 \\const x : f64 = 1.0;868 \\const x : f64 = 1.0;
741 \\const y : f32 = x;869 \\const y : f32 = x;
742 \\870 \\
743 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }871 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
872 \\comptime {@export("entry", entry);}
744 , ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'");873 , ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'");
745874
746875
747 cases.add("colliding invalid top level functions",876 cases.add("colliding invalid top level functions",
748 \\fn func() -> bogus {}877 \\fn func() -> bogus {}
749 \\fn func() -> bogus {}878 \\fn func() -> bogus {}
750 \\export fn entry() -> usize { @sizeOf(@typeOf(func)) }879 \\extern fn entry() -> usize { @sizeOf(@typeOf(func)) }
880 \\comptime {@export("entry", entry);}
751 ,881 ,
752 ".tmp_source.zig:2:1: error: redefinition of 'func'",882 ".tmp_source.zig:2:1: error: redefinition of 'func'",
753 ".tmp_source.zig:1:14: error: use of undeclared identifier 'bogus'");883 ".tmp_source.zig:1:14: error: use of undeclared identifier 'bogus'");
...@@ -755,7 +885,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -755,7 +885,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
755885
756 cases.add("bogus compile var",886 cases.add("bogus compile var",
757 \\const x = @import("builtin").bogus;887 \\const x = @import("builtin").bogus;
758 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }888 \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) }
889 \\comptime {@export("entry", entry);}
759 , ".tmp_source.zig:1:29: error: no member named 'bogus' in '");890 , ".tmp_source.zig:1:29: error: no member named 'bogus' in '");
760891
761892
...@@ -766,7 +897,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -766,7 +897,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
766 \\var global_var: usize = 1;897 \\var global_var: usize = 1;
767 \\fn get() -> usize { global_var }898 \\fn get() -> usize { global_var }
768 \\899 \\
769 \\export fn entry() -> usize { @sizeOf(@typeOf(Foo)) }900 \\extern fn entry() -> usize { @sizeOf(@typeOf(Foo)) }
901 \\comptime {@export("entry", entry);}
770 ,902 ,
771 ".tmp_source.zig:5:21: error: unable to evaluate constant expression",903 ".tmp_source.zig:5:21: error: unable to evaluate constant expression",
772 ".tmp_source.zig:2:12: note: called from here",904 ".tmp_source.zig:2:12: note: called from here",
...@@ -779,7 +911,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -779,7 +911,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
779 \\};911 \\};
780 \\const x = Foo {.field = 1} + Foo {.field = 2};912 \\const x = Foo {.field = 1} + Foo {.field = 2};
781 \\913 \\
782 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }914 \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) }
915 \\comptime {@export("entry", entry);}
783 , ".tmp_source.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'");916 , ".tmp_source.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'");
784917
785918
...@@ -789,10 +922,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -789,10 +922,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
789 \\const int_x = u32(1) / u32(0);922 \\const int_x = u32(1) / u32(0);
790 \\const float_x = f32(1.0) / f32(0.0);923 \\const float_x = f32(1.0) / f32(0.0);
791 \\924 \\
792 \\export fn entry1() -> usize { @sizeOf(@typeOf(lit_int_x)) }925 \\extern fn entry1() -> usize { @sizeOf(@typeOf(lit_int_x)) }
793 \\export fn entry2() -> usize { @sizeOf(@typeOf(lit_float_x)) }926 \\extern fn entry2() -> usize { @sizeOf(@typeOf(lit_float_x)) }
794 \\export fn entry3() -> usize { @sizeOf(@typeOf(int_x)) }927 \\extern fn entry3() -> usize { @sizeOf(@typeOf(int_x)) }
795 \\export fn entry4() -> usize { @sizeOf(@typeOf(float_x)) }928 \\extern fn entry4() -> usize { @sizeOf(@typeOf(float_x)) }
929 \\comptime {@export("entry1", entry1);}
930 \\comptime {@export("entry2", entry2);}
931 \\comptime {@export("entry3", entry3);}
932 \\comptime {@export("entry4", entry4);}
796 ,933 ,
797 ".tmp_source.zig:1:21: error: division by zero is undefined",934 ".tmp_source.zig:1:21: error: division by zero is undefined",
798 ".tmp_source.zig:2:25: error: division by zero is undefined",935 ".tmp_source.zig:2:25: error: division by zero is undefined",
...@@ -804,14 +941,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -804,14 +941,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
804 \\const foo = "a941 \\const foo = "a
805 \\b";942 \\b";
806 \\943 \\
807 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }944 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
945 \\comptime {@export("entry", entry);}
808 , ".tmp_source.zig:1:13: error: newline not allowed in string literal");946 , ".tmp_source.zig:1:13: error: newline not allowed in string literal");
809947
810 cases.add("invalid comparison for function pointers",948 cases.add("invalid comparison for function pointers",
811 \\fn foo() {}949 \\fn foo() {}
812 \\const invalid = foo > foo;950 \\const invalid = foo > foo;
813 \\951 \\
814 \\export fn entry() -> usize { @sizeOf(@typeOf(invalid)) }952 \\extern fn entry() -> usize { @sizeOf(@typeOf(invalid)) }
953 \\comptime {@export("entry", entry);}
815 , ".tmp_source.zig:2:21: error: operator not allowed for type 'fn()'");954 , ".tmp_source.zig:2:21: error: operator not allowed for type 'fn()'");
816955
817 cases.add("generic function instance with non-constant expression",956 cases.add("generic function instance with non-constant expression",
...@@ -820,16 +959,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -820,16 +959,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
820 \\ return foo(a, b);959 \\ return foo(a, b);
821 \\}960 \\}
822 \\961 \\
823 \\export fn entry() -> usize { @sizeOf(@typeOf(test1)) }962 \\extern fn entry() -> usize { @sizeOf(@typeOf(test1)) }
963 \\comptime {@export("entry", entry);}
824 , ".tmp_source.zig:3:16: error: unable to evaluate constant expression");964 , ".tmp_source.zig:3:16: error: unable to evaluate constant expression");
825965
826 cases.add("goto jumping into block",966 cases.add("goto jumping into block",
827 \\export fn f() {967 \\extern fn f() {
828 \\ {968 \\ {
829 \\a_label:969 \\a_label:
830 \\ }970 \\ }
831 \\ goto a_label;971 \\ goto a_label;
832 \\}972 \\}
973 \\comptime {@export("f", f);}
833 , ".tmp_source.zig:5:5: error: no label in scope named 'a_label'");974 , ".tmp_source.zig:5:5: error: no label in scope named 'a_label'");
834975
835 cases.add("goto jumping past a defer",976 cases.add("goto jumping past a defer",
...@@ -840,20 +981,23 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -840,20 +981,23 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
840 \\}981 \\}
841 \\fn derp(){}982 \\fn derp(){}
842 \\983 \\
843 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }984 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
985 \\comptime {@export("entry", entry);}
844 , ".tmp_source.zig:2:12: error: no label in scope named 'label'");986 , ".tmp_source.zig:2:12: error: no label in scope named 'label'");
845987
846 cases.add("assign null to non-nullable pointer",988 cases.add("assign null to non-nullable pointer",
847 \\const a: &u8 = null;989 \\const a: &u8 = null;
848 \\990 \\
849 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }991 \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) }
992 \\comptime {@export("entry", entry);}
850 , ".tmp_source.zig:1:16: error: expected type '&u8', found '(null)'");993 , ".tmp_source.zig:1:16: error: expected type '&u8', found '(null)'");
851994
852 cases.add("indexing an array of size zero",995 cases.add("indexing an array of size zero",
853 \\const array = []u8{};996 \\const array = []u8{};
854 \\export fn foo() {997 \\extern fn foo() {
855 \\ const pointer = &array[0];998 \\ const pointer = &array[0];
856 \\}999 \\}
1000 \\comptime {@export("foo", foo);}
857 , ".tmp_source.zig:3:27: error: index 0 outside array of size 0");1001 , ".tmp_source.zig:3:27: error: index 0 outside array of size 0");
8581002
859 cases.add("compile time division by zero",1003 cases.add("compile time division by zero",
...@@ -862,7 +1006,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -862,7 +1006,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
862 \\ 1 / x1006 \\ 1 / x
863 \\}1007 \\}
864 \\1008 \\
865 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }1009 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
1010 \\comptime {@export("entry", entry);}
866 ,1011 ,
867 ".tmp_source.zig:3:7: error: division by zero is undefined",1012 ".tmp_source.zig:3:7: error: division by zero is undefined",
868 ".tmp_source.zig:1:14: note: called from here");1013 ".tmp_source.zig:1:14: note: called from here");
...@@ -870,7 +1015,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -870,7 +1015,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
870 cases.add("branch on undefined value",1015 cases.add("branch on undefined value",
871 \\const x = if (undefined) true else false;1016 \\const x = if (undefined) true else false;
872 \\1017 \\
873 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }1018 \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) }
1019 \\comptime {@export("entry", entry);}
874 , ".tmp_source.zig:1:15: error: use of undefined value");1020 , ".tmp_source.zig:1:15: error: use of undefined value");
8751021
8761022
...@@ -880,7 +1026,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -880,7 +1026,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
880 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);1026 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);
881 \\}1027 \\}
882 \\1028 \\
883 \\export fn entry() -> usize { @sizeOf(@typeOf(seventh_fib_number)) }1029 \\comptime {@export("entry", entry);}
1030 \\extern fn entry() -> usize { @sizeOf(@typeOf(seventh_fib_number)) }
884 ,1031 ,
885 ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches",1032 ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches",
886 ".tmp_source.zig:3:21: note: called from here");1033 ".tmp_source.zig:3:21: note: called from here");
...@@ -888,7 +1035,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -888,7 +1035,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
888 cases.add("@embedFile with bogus file",1035 cases.add("@embedFile with bogus file",
889 \\const resource = @embedFile("bogus.txt");1036 \\const resource = @embedFile("bogus.txt");
890 \\1037 \\
891 \\export fn entry() -> usize { @sizeOf(@typeOf(resource)) }1038 \\comptime {@export("entry", entry);}
1039 \\extern fn entry() -> usize { @sizeOf(@typeOf(resource)) }
892 , ".tmp_source.zig:1:29: error: unable to find '", "bogus.txt'");1040 , ".tmp_source.zig:1:29: error: unable to find '", "bogus.txt'");
8931041
894 cases.add("non-const expression in struct literal outside function",1042 cases.add("non-const expression in struct literal outside function",
...@@ -898,7 +1046,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -898,7 +1046,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
898 \\const a = Foo {.x = get_it()};1046 \\const a = Foo {.x = get_it()};
899 \\extern fn get_it() -> i32;1047 \\extern fn get_it() -> i32;
900 \\1048 \\
901 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }1049 \\comptime {@export("entry", entry);}
1050 \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) }
902 , ".tmp_source.zig:4:21: error: unable to evaluate constant expression");1051 , ".tmp_source.zig:4:21: error: unable to evaluate constant expression");
9031052
904 cases.add("non-const expression function call with struct return value outside function",1053 cases.add("non-const expression function call with struct return value outside function",
...@@ -912,18 +1061,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -912,18 +1061,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
912 \\}1061 \\}
913 \\var global_side_effect = false;1062 \\var global_side_effect = false;
914 \\1063 \\
915 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }1064 \\comptime {@export("entry", entry);}
1065 \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) }
916 ,1066 ,
917 ".tmp_source.zig:6:24: error: unable to evaluate constant expression",1067 ".tmp_source.zig:6:24: error: unable to evaluate constant expression",
918 ".tmp_source.zig:4:17: note: called from here");1068 ".tmp_source.zig:4:17: note: called from here");
9191069
920 cases.add("undeclared identifier error should mark fn as impure",1070 cases.add("undeclared identifier error should mark fn as impure",
921 \\export fn foo() {1071 \\extern fn foo() {
922 \\ test_a_thing();1072 \\ test_a_thing();
923 \\}1073 \\}
924 \\fn test_a_thing() {1074 \\fn test_a_thing() {
925 \\ bad_fn_call();1075 \\ bad_fn_call();
926 \\}1076 \\}
1077 \\comptime {@export("foo", foo);}
927 , ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'");1078 , ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'");
9281079
929 cases.add("illegal comparison of types",1080 cases.add("illegal comparison of types",
...@@ -938,14 +1089,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -938,14 +1089,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
938 \\ *a == *b1089 \\ *a == *b
939 \\}1090 \\}
940 \\1091 \\
941 \\export fn entry1() -> usize { @sizeOf(@typeOf(bad_eql_1)) }1092 \\extern fn entry1() -> usize { @sizeOf(@typeOf(bad_eql_1)) }
942 \\export fn entry2() -> usize { @sizeOf(@typeOf(bad_eql_2)) }1093 \\extern fn entry2() -> usize { @sizeOf(@typeOf(bad_eql_2)) }
1094 \\comptime {@export("entry1", entry1);}
1095 \\comptime {@export("entry2", entry2);}
943 ,1096 ,
944 ".tmp_source.zig:2:7: error: operator not allowed for type '[]u8'",1097 ".tmp_source.zig:2:7: error: operator not allowed for type '[]u8'",
945 ".tmp_source.zig:9:8: error: operator not allowed for type 'EnumWithData'");1098 ".tmp_source.zig:9:8: error: operator not allowed for type 'EnumWithData'");
9461099
947 cases.add("non-const switch number literal",1100 cases.add("non-const switch number literal",
948 \\export fn foo() {1101 \\extern fn foo() {
949 \\ const x = switch (bar()) {1102 \\ const x = switch (bar()) {
950 \\ 1, 2 => 1,1103 \\ 1, 2 => 1,
951 \\ 3, 4 => 2,1104 \\ 3, 4 => 2,
...@@ -955,22 +1108,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -955,22 +1108,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
955 \\fn bar() -> i32 {1108 \\fn bar() -> i32 {
956 \\ 21109 \\ 2
957 \\}1110 \\}
1111 \\comptime {@export("foo", foo);}
958 , ".tmp_source.zig:2:15: error: unable to infer expression type");1112 , ".tmp_source.zig:2:15: error: unable to infer expression type");
9591113
960 cases.add("atomic orderings of cmpxchg - failure stricter than success",1114 cases.add("atomic orderings of cmpxchg - failure stricter than success",
961 \\const AtomicOrder = @import("builtin").AtomicOrder;1115 \\const AtomicOrder = @import("builtin").AtomicOrder;
962 \\export fn f() {1116 \\extern fn f() {
963 \\ var x: i32 = 1234;1117 \\ var x: i32 = 1234;
964 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}1118 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}
965 \\}1119 \\}
1120 \\comptime {@export("f", f);}
966 , ".tmp_source.zig:4:72: error: failure atomic ordering must be no stricter than success");1121 , ".tmp_source.zig:4:72: error: failure atomic ordering must be no stricter than success");
9671122
968 cases.add("atomic orderings of cmpxchg - success Monotonic or stricter",1123 cases.add("atomic orderings of cmpxchg - success Monotonic or stricter",
969 \\const AtomicOrder = @import("builtin").AtomicOrder;1124 \\const AtomicOrder = @import("builtin").AtomicOrder;
970 \\export fn f() {1125 \\extern fn f() {
971 \\ var x: i32 = 1234;1126 \\ var x: i32 = 1234;
972 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}1127 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}
973 \\}1128 \\}
1129 \\comptime {@export("f", f);}
974 , ".tmp_source.zig:4:49: error: success atomic ordering must be Monotonic or stricter");1130 , ".tmp_source.zig:4:49: error: success atomic ordering must be Monotonic or stricter");
9751131
976 cases.add("negation overflow in function evaluation",1132 cases.add("negation overflow in function evaluation",
...@@ -979,7 +1135,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -979,7 +1135,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
979 \\ -x1135 \\ -x
980 \\}1136 \\}
981 \\1137 \\
982 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }1138 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
1139 \\comptime {@export("entry", entry);}
983 ,1140 ,
984 ".tmp_source.zig:3:5: error: negation caused overflow",1141 ".tmp_source.zig:3:5: error: negation caused overflow",
985 ".tmp_source.zig:1:14: note: called from here");1142 ".tmp_source.zig:1:14: note: called from here");
...@@ -990,7 +1147,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -990,7 +1147,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
990 \\ a + b1147 \\ a + b
991 \\}1148 \\}
992 \\1149 \\
993 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }1150 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
1151 \\comptime {@export("entry", entry);}
994 ,1152 ,
995 ".tmp_source.zig:3:7: error: operation caused overflow",1153 ".tmp_source.zig:3:7: error: operation caused overflow",
996 ".tmp_source.zig:1:14: note: called from here");1154 ".tmp_source.zig:1:14: note: called from here");
...@@ -1002,7 +1160,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1002,7 +1160,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1002 \\ a - b1160 \\ a - b
1003 \\}1161 \\}
1004 \\1162 \\
1005 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }1163 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
1164 \\comptime {@export("entry", entry);}
1006 ,1165 ,
1007 ".tmp_source.zig:3:7: error: operation caused overflow",1166 ".tmp_source.zig:3:7: error: operation caused overflow",
1008 ".tmp_source.zig:1:14: note: called from here");1167 ".tmp_source.zig:1:14: note: called from here");
...@@ -1013,7 +1172,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1013,7 +1172,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1013 \\ a * b1172 \\ a * b
1014 \\}1173 \\}
1015 \\1174 \\
1016 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }1175 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
1176 \\comptime {@export("entry", entry);}
1017 ,1177 ,
1018 ".tmp_source.zig:3:7: error: operation caused overflow",1178 ".tmp_source.zig:3:7: error: operation caused overflow",
1019 ".tmp_source.zig:1:14: note: called from here");1179 ".tmp_source.zig:1:14: note: called from here");
...@@ -1024,40 +1184,35 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1024,40 +1184,35 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1024 \\ @truncate(i8, x)1184 \\ @truncate(i8, x)
1025 \\}1185 \\}
1026 \\1186 \\
1027 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }1187 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
1188 \\comptime {@export("entry", entry);}
1028 , ".tmp_source.zig:3:19: error: expected signed integer type, found 'u32'");1189 , ".tmp_source.zig:3:19: error: expected signed integer type, found 'u32'");
10291190
1030 cases.add("%return in function with non error return type",1191 cases.add("%return in function with non error return type",
1031 \\export fn f() {1192 \\extern fn f() {
1032 \\ %return something();1193 \\ %return something();
1033 \\}1194 \\}
1034 \\fn something() -> %void { }1195 \\fn something() -> %void { }
1196 \\comptime {@export("f", f);}
1035 ,1197 ,
1036 ".tmp_source.zig:2:5: error: expected type 'void', found 'error'");1198 ".tmp_source.zig:2:5: error: expected type 'void', found 'error'");
10371199
1038 cases.add("wrong return type for main",
1039 \\pub fn main() { }
1040 , ".tmp_source.zig:1:15: error: expected return type of main to be '%void', instead is 'void'");
1041
1042 cases.add("double ?? on main return value",
1043 \\pub fn main() -> ??void {
1044 \\}
1045 , ".tmp_source.zig:1:18: error: expected return type of main to be '%void', instead is '??void'");
1046
1047 cases.add("invalid pointer for var type",1200 cases.add("invalid pointer for var type",
1048 \\extern fn ext() -> usize;1201 \\extern fn ext() -> usize;
1049 \\var bytes: [ext()]u8 = undefined;1202 \\var bytes: [ext()]u8 = undefined;
1050 \\export fn f() {1203 \\extern fn f() {
1051 \\ for (bytes) |*b, i| {1204 \\ for (bytes) |*b, i| {
1052 \\ *b = u8(i);1205 \\ *b = u8(i);
1053 \\ }1206 \\ }
1054 \\}1207 \\}
1208 \\comptime {@export("f", f);}
1055 , ".tmp_source.zig:2:13: error: unable to evaluate constant expression");1209 , ".tmp_source.zig:2:13: error: unable to evaluate constant expression");
10561210
1057 cases.add("export function with comptime parameter",1211 cases.add("export function with comptime parameter",
1058 \\export fn foo(comptime x: i32, y: i32) -> i32{1212 \\extern fn foo(comptime x: i32, y: i32) -> i32{
1059 \\ x + y1213 \\ x + y
1060 \\}1214 \\}
1215 \\comptime {@export("foo", foo);}
1061 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");1216 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");
10621217
1063 cases.add("extern function with comptime parameter",1218 cases.add("extern function with comptime parameter",
...@@ -1065,14 +1220,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1065,14 +1220,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1065 \\fn f() -> i32 {1220 \\fn f() -> i32 {
1066 \\ foo(1, 2)1221 \\ foo(1, 2)
1067 \\}1222 \\}
1068 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }1223 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
1224 \\comptime {@export("entry", entry);}
1069 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");1225 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");
10701226
1071 cases.add("convert fixed size array to slice with invalid size",1227 cases.add("convert fixed size array to slice with invalid size",
1072 \\export fn f() {1228 \\extern fn f() {
1073 \\ var array: [5]u8 = undefined;1229 \\ var array: [5]u8 = undefined;
1074 \\ var foo = ([]const u32)(array)[0];1230 \\ var foo = ([]const u32)(array)[0];
1075 \\}1231 \\}
1232 \\comptime {@export("f", f);}
1076 , ".tmp_source.zig:3:28: error: unable to convert [5]u8 to []const u32: size mismatch");1233 , ".tmp_source.zig:3:28: error: unable to convert [5]u8 to []const u32: size mismatch");
10771234
1078 cases.add("non-pure function returns type",1235 cases.add("non-pure function returns type",
...@@ -1090,10 +1247,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1090,10 +1247,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1090 \\ }1247 \\ }
1091 \\}1248 \\}
1092 \\1249 \\
1093 \\export fn function_with_return_type_type() {1250 \\extern fn function_with_return_type_type() {
1094 \\ var list: List(i32) = undefined;1251 \\ var list: List(i32) = undefined;
1095 \\ list.length = 10;1252 \\ list.length = 10;
1096 \\}1253 \\}
1254 \\comptime {@export("function_with_return_type_type", function_with_return_type_type);}
1097 , ".tmp_source.zig:3:7: error: unable to evaluate constant expression",1255 , ".tmp_source.zig:3:7: error: unable to evaluate constant expression",
1098 ".tmp_source.zig:16:19: note: called from here");1256 ".tmp_source.zig:16:19: note: called from here");
10991257
...@@ -1102,7 +1260,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1102,7 +1260,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1102 \\fn f(m: []const u8) {1260 \\fn f(m: []const u8) {
1103 \\ m.copy(u8, self[0..], m);1261 \\ m.copy(u8, self[0..], m);
1104 \\}1262 \\}
1105 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }1263 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
1264 \\comptime {@export("entry", entry);}
1106 , ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'");1265 , ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'");
11071266
1108 cases.add("wrong number of arguments for method fn call",1267 cases.add("wrong number of arguments for method fn call",
...@@ -1113,21 +1272,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1113,21 +1272,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1113 \\1272 \\
1114 \\ foo.method(1, 2);1273 \\ foo.method(1, 2);
1115 \\}1274 \\}
1116 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }1275 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
1276 \\comptime {@export("entry", entry);}
1117 , ".tmp_source.zig:6:15: error: expected 2 arguments, found 3");1277 , ".tmp_source.zig:6:15: error: expected 2 arguments, found 3");
11181278
1119 cases.add("assign through constant pointer",1279 cases.add("assign through constant pointer",
1120 \\export fn f() {1280 \\extern fn f() {
1121 \\ var cstr = c"Hat";1281 \\ var cstr = c"Hat";
1122 \\ cstr[0] = 'W';1282 \\ cstr[0] = 'W';
1123 \\}1283 \\}
1284 \\comptime {@export("f", f);}
1124 , ".tmp_source.zig:3:11: error: cannot assign to constant");1285 , ".tmp_source.zig:3:11: error: cannot assign to constant");
11251286
1126 cases.add("assign through constant slice",1287 cases.add("assign through constant slice",
1127 \\export fn f() {1288 \\extern fn f() {
1128 \\ var cstr: []const u8 = "Hat";1289 \\ var cstr: []const u8 = "Hat";
1129 \\ cstr[0] = 'W';1290 \\ cstr[0] = 'W';
1130 \\}1291 \\}
1292 \\comptime {@export("f", f);}
1131 , ".tmp_source.zig:3:11: error: cannot assign to constant");1293 , ".tmp_source.zig:3:11: error: cannot assign to constant");
11321294
1133 cases.add("main function with bogus args type",1295 cases.add("main function with bogus args type",
...@@ -1138,7 +1300,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1138,7 +1300,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1138 \\fn foo(blah: []u8) {1300 \\fn foo(blah: []u8) {
1139 \\ for (blah) { }1301 \\ for (blah) { }
1140 \\}1302 \\}
1141 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }1303 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1304 \\comptime {@export("entry", entry);}
1142 , ".tmp_source.zig:2:5: error: for loop expression missing element parameter");1305 , ".tmp_source.zig:2:5: error: for loop expression missing element parameter");
11431306
1144 cases.add("misspelled type with pointer only reference",1307 cases.add("misspelled type with pointer only reference",
...@@ -1171,7 +1334,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1171,7 +1334,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1171 \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };1334 \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };
1172 \\}1335 \\}
1173 \\1336 \\
1174 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }1337 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1338 \\comptime {@export("entry", entry);}
1175 , ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'");1339 , ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'");
11761340
1177 cases.add("method call with first arg type primitive",1341 cases.add("method call with first arg type primitive",
...@@ -1185,11 +1349,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1185,11 +1349,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1185 \\ }1349 \\ }
1186 \\};1350 \\};
1187 \\1351 \\
1188 \\export fn f() {1352 \\extern fn f() {
1189 \\ const derp = Foo.init(3);1353 \\ const derp = Foo.init(3);
1190 \\1354 \\
1191 \\ derp.init();1355 \\ derp.init();
1192 \\}1356 \\}
1357 \\comptime {@export("f", f);}
1193 , ".tmp_source.zig:14:5: error: expected type 'i32', found '&const Foo'");1358 , ".tmp_source.zig:14:5: error: expected type 'i32', found '&const Foo'");
11941359
1195 cases.add("method call with first arg type wrong container",1360 cases.add("method call with first arg type wrong container",
...@@ -1213,10 +1378,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1213,10 +1378,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1213 \\ field: i32,1378 \\ field: i32,
1214 \\};1379 \\};
1215 \\1380 \\
1216 \\export fn foo() {1381 \\extern fn foo() {
1217 \\ var x = List.init(&global_allocator);1382 \\ var x = List.init(&global_allocator);
1218 \\ x.init();1383 \\ x.init();
1219 \\}1384 \\}
1385 \\comptime {@export("foo", foo);}
1220 , ".tmp_source.zig:23:5: error: expected type '&Allocator', found '&List'");1386 , ".tmp_source.zig:23:5: error: expected type '&Allocator', found '&List'");
12211387
1222 cases.add("binary not on number literal",1388 cases.add("binary not on number literal",
...@@ -1224,16 +1390,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1224,16 +1390,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1224 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;1390 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
1225 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);1391 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
1226 \\1392 \\
1227 \\export fn entry() -> usize { @sizeOf(@typeOf(block_aligned_stuff)) }1393 \\extern fn entry() -> usize { @sizeOf(@typeOf(block_aligned_stuff)) }
1394 \\comptime {@export("entry", entry);}
1228 , ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'");1395 , ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'");
12291396
1230 cases.addCase({1397 cases.addCase({
1231 const tc = cases.create("multiple files with private function error",1398 const tc = cases.create("multiple files with private function error",
1232 \\const foo = @import("foo.zig");1399 \\const foo = @import("foo.zig");
1233 \\1400 \\
1234 \\export fn callPrivFunction() {1401 \\extern fn callPrivFunction() {
1235 \\ foo.privateFunction();1402 \\ foo.privateFunction();
1236 \\}1403 \\}
1404 \\comptime {@export("callPrivFunction", callPrivFunction);}
1237 ,1405 ,
1238 ".tmp_source.zig:4:8: error: 'privateFunction' is private",1406 ".tmp_source.zig:4:8: error: 'privateFunction' is private",
1239 "foo.zig:1:1: note: declared here");1407 "foo.zig:1:1: note: declared here");
...@@ -1249,17 +1417,19 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1249,17 +1417,19 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1249 \\const zero: i32 = 0;1417 \\const zero: i32 = 0;
1250 \\const a = zero{1};1418 \\const a = zero{1};
1251 \\1419 \\
1252 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }1420 \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) }
1421 \\comptime {@export("entry", entry);}
1253 , ".tmp_source.zig:2:11: error: expected type, found 'i32'");1422 , ".tmp_source.zig:2:11: error: expected type, found 'i32'");
12541423
1255 cases.add("assign to constant field",1424 cases.add("assign to constant field",
1256 \\const Foo = struct {1425 \\const Foo = struct {
1257 \\ field: i32,1426 \\ field: i32,
1258 \\};1427 \\};
1259 \\export fn derp() {1428 \\extern fn derp() {
1260 \\ const f = Foo {.field = 1234,};1429 \\ const f = Foo {.field = 1234,};
1261 \\ f.field = 0;1430 \\ f.field = 0;
1262 \\}1431 \\}
1432 \\comptime {@export("derp", derp);}
1263 , ".tmp_source.zig:6:13: error: cannot assign to constant");1433 , ".tmp_source.zig:6:13: error: cannot assign to constant");
12641434
1265 cases.add("return from defer expression",1435 cases.add("return from defer expression",
...@@ -1277,7 +1447,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1277,7 +1447,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1277 \\ return 0;1447 \\ return 0;
1278 \\}1448 \\}
1279 \\1449 \\
1280 \\export fn entry() -> usize { @sizeOf(@typeOf(testTrickyDefer)) }1450 \\extern fn entry() -> usize { @sizeOf(@typeOf(testTrickyDefer)) }
1451 \\comptime {@export("entry", entry);}
1281 , ".tmp_source.zig:4:11: error: cannot return from defer expression");1452 , ".tmp_source.zig:4:11: error: cannot return from defer expression");
12821453
1283 cases.add("attempt to access var args out of bounds",1454 cases.add("attempt to access var args out of bounds",
...@@ -1289,7 +1460,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1289,7 +1460,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1289 \\ add(i32(1234))1460 \\ add(i32(1234))
1290 \\}1461 \\}
1291 \\1462 \\
1292 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }1463 \\comptime {@export("entry", entry);}
1464 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1293 ,1465 ,
1294 ".tmp_source.zig:2:19: error: index 1 outside argument list of size 1",1466 ".tmp_source.zig:2:19: error: index 1 outside argument list of size 1",
1295 ".tmp_source.zig:6:8: note: called from here");1467 ".tmp_source.zig:6:8: note: called from here");
...@@ -1307,27 +1479,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1307,27 +1479,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1307 \\ add(1, 2, 3, 4)1479 \\ add(1, 2, 3, 4)
1308 \\}1480 \\}
1309 \\1481 \\
1310 \\export fn entry() -> usize { @sizeOf(@typeOf(bar)) }1482 \\comptime {@export("entry", entry);}
1483 \\extern fn entry() -> usize { @sizeOf(@typeOf(bar)) }
1311 , ".tmp_source.zig:10:9: error: parameter of type '(integer literal)' requires comptime");1484 , ".tmp_source.zig:10:9: error: parameter of type '(integer literal)' requires comptime");
13121485
1313 cases.add("assign too big number to u16",1486 cases.add("assign too big number to u16",
1314 \\export fn foo() {1487 \\extern fn foo() {
1315 \\ var vga_mem: u16 = 0xB8000;1488 \\ var vga_mem: u16 = 0xB8000;
1316 \\}1489 \\}
1490 \\comptime {@export("foo", foo);}
1317 , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");1491 , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");
13181492
1319 cases.add("global variable alignment non power of 2",1493 cases.add("global variable alignment non power of 2",
1320 \\const some_data: [100]u8 align(3) = undefined;1494 \\const some_data: [100]u8 align(3) = undefined;
1321 \\export fn entry() -> usize { @sizeOf(@typeOf(some_data)) }1495 \\extern fn entry() -> usize { @sizeOf(@typeOf(some_data)) }
1496 \\comptime {@export("entry", entry);}
1322 , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2");1497 , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2");
13231498
1324 cases.add("function alignment non power of 2",1499 cases.add("function alignment non power of 2",
1325 \\extern fn foo() align(3);1500 \\extern fn foo() align(3);
1326 \\export fn entry() { foo() }1501 \\extern fn entry() { foo() }
1502 \\comptime {@export("entry", entry);}
1327 , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2");1503 , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2");
13281504
1329 cases.add("compile log",1505 cases.add("compile log",
1330 \\export fn foo() {1506 \\extern fn foo() {
1331 \\ comptime bar(12, "hi");1507 \\ comptime bar(12, "hi");
1332 \\}1508 \\}
1333 \\fn bar(a: i32, b: []const u8) {1509 \\fn bar(a: i32, b: []const u8) {
...@@ -1335,6 +1511,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1335,6 +1511,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1335 \\ @compileLog("a", a, "b", b);1511 \\ @compileLog("a", a, "b", b);
1336 \\ @compileLog("end");1512 \\ @compileLog("end");
1337 \\}1513 \\}
1514 \\comptime {@export("foo", foo);}
1338 ,1515 ,
1339 ".tmp_source.zig:5:5: error: found compile log statement",1516 ".tmp_source.zig:5:5: error: found compile log statement",
1340 ".tmp_source.zig:2:17: note: called from here",1517 ".tmp_source.zig:2:17: note: called from here",
...@@ -1358,7 +1535,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1358,7 +1535,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1358 \\ return *x;1535 \\ return *x;
1359 \\}1536 \\}
1360 \\1537 \\
1361 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }1538 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1539 \\comptime {@export("entry", entry);}
1362 , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align(1:3:6) const u3'");1540 , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align(1:3:6) const u3'");
13631541
1364 cases.add("referring to a struct that is invalid",1542 cases.add("referring to a struct that is invalid",
...@@ -1366,19 +1544,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1366,19 +1544,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1366 \\ Type: u8,1544 \\ Type: u8,
1367 \\};1545 \\};
1368 \\1546 \\
1369 \\export fn foo() {1547 \\extern fn foo() {
1370 \\ comptime assert(@sizeOf(UsbDeviceRequest) == 0x8);1548 \\ comptime assert(@sizeOf(UsbDeviceRequest) == 0x8);
1371 \\}1549 \\}
1372 \\1550 \\
1373 \\fn assert(ok: bool) {1551 \\fn assert(ok: bool) {
1374 \\ if (!ok) unreachable;1552 \\ if (!ok) unreachable;
1375 \\}1553 \\}
1554 \\comptime {@export("foo", foo);}
1376 ,1555 ,
1377 ".tmp_source.zig:10:14: error: unable to evaluate constant expression",1556 ".tmp_source.zig:10:14: error: unable to evaluate constant expression",
1378 ".tmp_source.zig:6:20: note: called from here");1557 ".tmp_source.zig:6:20: note: called from here");
13791558
1380 cases.add("control flow uses comptime var at runtime",1559 cases.add("control flow uses comptime var at runtime",
1381 \\export fn foo() {1560 \\extern fn foo() {
1382 \\ comptime var i = 0;1561 \\ comptime var i = 0;
1383 \\ while (i < 5) : (i += 1) {1562 \\ while (i < 5) : (i += 1) {
1384 \\ bar();1563 \\ bar();
...@@ -1386,53 +1565,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1386,53 +1565,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1386 \\}1565 \\}
1387 \\1566 \\
1388 \\fn bar() { }1567 \\fn bar() { }
1568 \\comptime {@export("foo", foo);}
1389 ,1569 ,
1390 ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime",1570 ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime",
1391 ".tmp_source.zig:3:24: note: compile-time variable assigned here");1571 ".tmp_source.zig:3:24: note: compile-time variable assigned here");
13921572
1393 cases.add("ignored return value",1573 cases.add("ignored return value",
1394 \\export fn foo() {1574 \\extern fn foo() {
1395 \\ bar();1575 \\ bar();
1396 \\}1576 \\}
1397 \\fn bar() -> i32 { 0 }1577 \\fn bar() -> i32 { 0 }
1578 \\comptime {@export("foo", foo);}
1398 , ".tmp_source.zig:2:8: error: expression value is ignored");1579 , ".tmp_source.zig:2:8: error: expression value is ignored");
13991580
1400 cases.add("ignored assert-err-ok return value",1581 cases.add("ignored assert-err-ok return value",
1401 \\export fn foo() {1582 \\extern fn foo() {
1402 \\ %%bar();1583 \\ %%bar();
1403 \\}1584 \\}
1404 \\fn bar() -> %i32 { 0 }1585 \\fn bar() -> %i32 { 0 }
1586 \\comptime {@export("foo", foo);}
1405 , ".tmp_source.zig:2:5: error: expression value is ignored");1587 , ".tmp_source.zig:2:5: error: expression value is ignored");
14061588
1407 cases.add("ignored statement value",1589 cases.add("ignored statement value",
1408 \\export fn foo() {1590 \\extern fn foo() {
1409 \\ 1;1591 \\ 1;
1410 \\}1592 \\}
1593 \\comptime {@export("foo", foo);}
1411 , ".tmp_source.zig:2:5: error: expression value is ignored");1594 , ".tmp_source.zig:2:5: error: expression value is ignored");
14121595
1413 cases.add("ignored comptime statement value",1596 cases.add("ignored comptime statement value",
1414 \\export fn foo() {1597 \\extern fn foo() {
1415 \\ comptime {1;}1598 \\ comptime {1;}
1416 \\}1599 \\}
1600 \\comptime {@export("foo", foo);}
1417 , ".tmp_source.zig:2:15: error: expression value is ignored");1601 , ".tmp_source.zig:2:15: error: expression value is ignored");
14181602
1419 cases.add("ignored comptime value",1603 cases.add("ignored comptime value",
1420 \\export fn foo() {1604 \\extern fn foo() {
1421 \\ comptime 1;1605 \\ comptime 1;
1422 \\}1606 \\}
1607 \\comptime {@export("foo", foo);}
1423 , ".tmp_source.zig:2:5: error: expression value is ignored");1608 , ".tmp_source.zig:2:5: error: expression value is ignored");
14241609
1425 cases.add("ignored defered statement value",1610 cases.add("ignored defered statement value",
1426 \\export fn foo() {1611 \\extern fn foo() {
1427 \\ defer {1;}1612 \\ defer {1;}
1428 \\}1613 \\}
1614 \\comptime {@export("foo", foo);}
1429 , ".tmp_source.zig:2:12: error: expression value is ignored");1615 , ".tmp_source.zig:2:12: error: expression value is ignored");
14301616
1431 cases.add("ignored defered statement value",1617 cases.add("ignored defered statement value",
1432 \\export fn foo() {1618 \\extern fn foo() {
1433 \\ defer bar();1619 \\ defer bar();
1434 \\}1620 \\}
1435 \\fn bar() -> %i32 { 0 }1621 \\fn bar() -> %i32 { 0 }
1622 \\comptime {@export("foo", foo);}
1436 , ".tmp_source.zig:2:14: error: expression value is ignored");1623 , ".tmp_source.zig:2:14: error: expression value is ignored");
14371624
1438 cases.add("dereference an array",1625 cases.add("dereference an array",
...@@ -1443,7 +1630,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1443,7 +1630,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1443 \\ return (*out)[0..1];1630 \\ return (*out)[0..1];
1444 \\}1631 \\}
1445 \\1632 \\
1446 \\export fn entry() -> usize { @sizeOf(@typeOf(pass)) }1633 \\extern fn entry() -> usize { @sizeOf(@typeOf(pass)) }
1634 \\comptime {@export("entry", entry);}
1447 , ".tmp_source.zig:4:5: error: attempt to dereference non pointer type '[10]u8'");1635 , ".tmp_source.zig:4:5: error: attempt to dereference non pointer type '[10]u8'");
14481636
1449 cases.add("pass const ptr to mutable ptr fn",1637 cases.add("pass const ptr to mutable ptr fn",
...@@ -1456,46 +1644,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1456,46 +1644,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1456 \\ return true;1644 \\ return true;
1457 \\}1645 \\}
1458 \\1646 \\
1459 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }1647 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1648 \\comptime {@export("entry", entry);}
1460 , ".tmp_source.zig:4:19: error: expected type '&[]const u8', found '&const []const u8'");1649 , ".tmp_source.zig:4:19: error: expected type '&[]const u8', found '&const []const u8'");
14611650
1462 cases.addCase({
1463 const tc = cases.create("export collision",
1464 \\const foo = @import("foo.zig");
1465 \\
1466 \\export fn bar() -> usize {
1467 \\ return foo.baz;
1468 \\}
1469 ,
1470 "foo.zig:1:8: error: exported symbol collision: 'bar'",
1471 ".tmp_source.zig:3:8: note: other symbol is here");
1472
1473 tc.addSourceFile("foo.zig",
1474 \\export fn bar() {}
1475 \\pub const baz = 1234;
1476 );
1477
1478 tc
1479 });
1480
1481 cases.add("pass non-copyable type by value to function",1651 cases.add("pass non-copyable type by value to function",
1482 \\const Point = struct { x: i32, y: i32, };1652 \\const Point = struct { x: i32, y: i32, };
1483 \\fn foo(p: Point) { }1653 \\fn foo(p: Point) { }
1484 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }1654 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1655 \\comptime {@export("entry", entry);}
1485 , ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value");1656 , ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value");
14861657
1487 cases.add("implicit cast from array to mutable slice",1658 cases.add("implicit cast from array to mutable slice",
1488 \\var global_array: [10]i32 = undefined;1659 \\var global_array: [10]i32 = undefined;
1489 \\fn foo(param: []i32) {}1660 \\fn foo(param: []i32) {}
1490 \\export fn entry() {1661 \\extern fn entry() {
1491 \\ foo(global_array);1662 \\ foo(global_array);
1492 \\}1663 \\}
1664 \\comptime {@export("entry", entry);}
1493 , ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'");1665 , ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'");
14941666
1495 cases.add("ptrcast to non-pointer",1667 cases.add("ptrcast to non-pointer",
1496 \\export fn entry(a: &i32) -> usize {1668 \\extern fn entry(a: &i32) -> usize {
1497 \\ return @ptrCast(usize, a);1669 \\ return @ptrCast(usize, a);
1498 \\}1670 \\}
1671 \\comptime {@export("entry", entry);}
1499 , ".tmp_source.zig:2:21: error: expected pointer, found 'usize'");1672 , ".tmp_source.zig:2:21: error: expected pointer, found 'usize'");
15001673
1501 cases.add("too many error values to cast to small integer",1674 cases.add("too many error values to cast to small integer",
...@@ -1504,7 +1677,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1504,7 +1677,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1504 \\fn foo(e: error) -> u2 {1677 \\fn foo(e: error) -> u2 {
1505 \\ return u2(e);1678 \\ return u2(e);
1506 \\}1679 \\}
1507 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }1680 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1681 \\comptime {@export("entry", entry);}
1508 , ".tmp_source.zig:4:14: error: too many error values to fit in 'u2'");1682 , ".tmp_source.zig:4:14: error: too many error values to fit in 'u2'");
15091683
1510 cases.add("asm at compile time",1684 cases.add("asm at compile time",
...@@ -1523,41 +1697,46 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1523,41 +1697,46 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15231697
1524 cases.add("invalid member of builtin enum",1698 cases.add("invalid member of builtin enum",
1525 \\const builtin = @import("builtin");1699 \\const builtin = @import("builtin");
1526 \\export fn entry() {1700 \\extern fn entry() {
1527 \\ const foo = builtin.Arch.x86;1701 \\ const foo = builtin.Arch.x86;
1528 \\}1702 \\}
1703 \\comptime {@export("entry", entry);}
1529 , ".tmp_source.zig:3:29: error: container 'Arch' has no member called 'x86'");1704 , ".tmp_source.zig:3:29: error: container 'Arch' has no member called 'x86'");
15301705
1531 cases.add("int to ptr of 0 bits",1706 cases.add("int to ptr of 0 bits",
1532 \\export fn foo() {1707 \\extern fn foo() {
1533 \\ var x: usize = 0x1000;1708 \\ var x: usize = 0x1000;
1534 \\ var y: &void = @intToPtr(&void, x);1709 \\ var y: &void = @intToPtr(&void, x);
1535 \\}1710 \\}
1711 \\comptime {@export("foo", foo);}
1536 , ".tmp_source.zig:3:31: error: type '&void' has 0 bits and cannot store information");1712 , ".tmp_source.zig:3:31: error: type '&void' has 0 bits and cannot store information");
15371713
1538 cases.add("@fieldParentPtr - non struct",1714 cases.add("@fieldParentPtr - non struct",
1539 \\const Foo = i32;1715 \\const Foo = i32;
1540 \\export fn foo(a: &i32) -> &Foo {1716 \\extern fn foo(a: &i32) -> &Foo {
1541 \\ return @fieldParentPtr(Foo, "a", a);1717 \\ return @fieldParentPtr(Foo, "a", a);
1542 \\}1718 \\}
1719 \\comptime {@export("foo", foo);}
1543 , ".tmp_source.zig:3:28: error: expected struct type, found 'i32'");1720 , ".tmp_source.zig:3:28: error: expected struct type, found 'i32'");
15441721
1545 cases.add("@fieldParentPtr - bad field name",1722 cases.add("@fieldParentPtr - bad field name",
1546 \\const Foo = struct {1723 \\const Foo = struct {
1547 \\ derp: i32,1724 \\ derp: i32,
1548 \\};1725 \\};
1549 \\export fn foo(a: &i32) -> &Foo {1726 \\extern fn foo(a: &i32) -> &Foo {
1550 \\ return @fieldParentPtr(Foo, "a", a);1727 \\ return @fieldParentPtr(Foo, "a", a);
1551 \\}1728 \\}
1729 \\comptime {@export("foo", foo);}
1552 , ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'");1730 , ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'");
15531731
1554 cases.add("@fieldParentPtr - field pointer is not pointer",1732 cases.add("@fieldParentPtr - field pointer is not pointer",
1555 \\const Foo = struct {1733 \\const Foo = struct {
1556 \\ a: i32,1734 \\ a: i32,
1557 \\};1735 \\};
1558 \\export fn foo(a: i32) -> &Foo {1736 \\extern fn foo(a: i32) -> &Foo {
1559 \\ return @fieldParentPtr(Foo, "a", a);1737 \\ return @fieldParentPtr(Foo, "a", a);
1560 \\}1738 \\}
1739 \\comptime {@export("foo", foo);}
1561 , ".tmp_source.zig:5:38: error: expected pointer, found 'i32'");1740 , ".tmp_source.zig:5:38: error: expected pointer, found 'i32'");
15621741
1563 cases.add("@fieldParentPtr - comptime field ptr not based on struct",1742 cases.add("@fieldParentPtr - comptime field ptr not based on struct",
...@@ -1587,18 +1766,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1587,18 +1766,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15871766
1588 cases.add("@offsetOf - non struct",1767 cases.add("@offsetOf - non struct",
1589 \\const Foo = i32;1768 \\const Foo = i32;
1590 \\export fn foo() -> usize {1769 \\extern fn foo() -> usize {
1591 \\ return @offsetOf(Foo, "a");1770 \\ return @offsetOf(Foo, "a");
1592 \\}1771 \\}
1772 \\comptime {@export("foo", foo);}
1593 , ".tmp_source.zig:3:22: error: expected struct type, found 'i32'");1773 , ".tmp_source.zig:3:22: error: expected struct type, found 'i32'");
15941774
1595 cases.add("@offsetOf - bad field name",1775 cases.add("@offsetOf - bad field name",
1596 \\const Foo = struct {1776 \\const Foo = struct {
1597 \\ derp: i32,1777 \\ derp: i32,
1598 \\};1778 \\};
1599 \\export fn foo() -> usize {1779 \\extern fn foo() -> usize {
1600 \\ return @offsetOf(Foo, "a");1780 \\ return @offsetOf(Foo, "a");
1601 \\}1781 \\}
1782 \\comptime {@export("foo", foo);}
1602 , ".tmp_source.zig:5:27: error: struct 'Foo' has no field 'a'");1783 , ".tmp_source.zig:5:27: error: struct 'Foo' has no field 'a'");
16031784
1604 cases.addExe("missing main fn in executable",1785 cases.addExe("missing main fn in executable",
...@@ -1611,38 +1792,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1611,38 +1792,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1611 "error: 'main' is private",1792 "error: 'main' is private",
1612 ".tmp_source.zig:1:1: note: declared here");1793 ".tmp_source.zig:1:1: note: declared here");
16131794
1614 cases.add("@setGlobalSection extern variable",
1615 \\extern var foo: i32;
1616 \\comptime {
1617 \\ @setGlobalSection(foo, ".text2");
1618 \\}
1619 ,
1620 ".tmp_source.zig:3:5: error: cannot set section of external variable 'foo'",
1621 ".tmp_source.zig:1:8: note: declared here");
1622
1623 cases.add("@setGlobalSection extern fn",
1624 \\extern fn foo();
1625 \\comptime {
1626 \\ @setGlobalSection(foo, ".text2");
1627 \\}
1628 ,
1629 ".tmp_source.zig:3:5: error: cannot set section of external function 'foo'",
1630 ".tmp_source.zig:1:8: note: declared here");
1631
1632 cases.add("returning address of local variable - simple",1795 cases.add("returning address of local variable - simple",
1633 \\export fn foo() -> &i32 {1796 \\extern fn foo() -> &i32 {
1634 \\ var a: i32 = undefined;1797 \\ var a: i32 = undefined;
1635 \\ return &a;1798 \\ return &a;
1636 \\}1799 \\}
1800 \\comptime {@export("foo", foo);}
1637 ,1801 ,
1638 ".tmp_source.zig:3:13: error: function returns address of local variable");1802 ".tmp_source.zig:3:13: error: function returns address of local variable");
16391803
1640 cases.add("returning address of local variable - phi",1804 cases.add("returning address of local variable - phi",
1641 \\export fn foo(c: bool) -> &i32 {1805 \\extern fn foo(c: bool) -> &i32 {
1642 \\ var a: i32 = undefined;1806 \\ var a: i32 = undefined;
1643 \\ var b: i32 = undefined;1807 \\ var b: i32 = undefined;
1644 \\ return if (c) &a else &b;1808 \\ return if (c) &a else &b;
1645 \\}1809 \\}
1810 \\comptime {@export("foo", foo);}
1646 ,1811 ,
1647 ".tmp_source.zig:4:12: error: function returns address of local variable");1812 ".tmp_source.zig:4:12: error: function returns address of local variable");
16481813
...@@ -1671,55 +1836,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1671,55 +1836,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1671 ".tmp_source.zig:5:9: note: previous definition is here");1836 ".tmp_source.zig:5:9: note: previous definition is here");
16721837
1673 cases.add("while expected bool, got nullable",1838 cases.add("while expected bool, got nullable",
1674 \\export fn foo() {1839 \\extern fn foo() {
1675 \\ while (bar()) {}1840 \\ while (bar()) {}
1676 \\}1841 \\}
1677 \\fn bar() -> ?i32 { 1 }1842 \\fn bar() -> ?i32 { 1 }
1843 \\comptime {@export("foo", foo);}
1678 ,1844 ,
1679 ".tmp_source.zig:2:15: error: expected type 'bool', found '?i32'");1845 ".tmp_source.zig:2:15: error: expected type 'bool', found '?i32'");
16801846
1681 cases.add("while expected bool, got error union",1847 cases.add("while expected bool, got error union",
1682 \\export fn foo() {1848 \\extern fn foo() {
1683 \\ while (bar()) {}1849 \\ while (bar()) {}
1684 \\}1850 \\}
1685 \\fn bar() -> %i32 { 1 }1851 \\fn bar() -> %i32 { 1 }
1852 \\comptime {@export("foo", foo);}
1686 ,1853 ,
1687 ".tmp_source.zig:2:15: error: expected type 'bool', found '%i32'");1854 ".tmp_source.zig:2:15: error: expected type 'bool', found '%i32'");
16881855
1689 cases.add("while expected nullable, got bool",1856 cases.add("while expected nullable, got bool",
1690 \\export fn foo() {1857 \\extern fn foo() {
1691 \\ while (bar()) |x| {}1858 \\ while (bar()) |x| {}
1692 \\}1859 \\}
1693 \\fn bar() -> bool { true }1860 \\fn bar() -> bool { true }
1861 \\comptime {@export("foo", foo);}
1694 ,1862 ,
1695 ".tmp_source.zig:2:15: error: expected nullable type, found 'bool'");1863 ".tmp_source.zig:2:15: error: expected nullable type, found 'bool'");
16961864
1697 cases.add("while expected nullable, got error union",1865 cases.add("while expected nullable, got error union",
1698 \\export fn foo() {1866 \\extern fn foo() {
1699 \\ while (bar()) |x| {}1867 \\ while (bar()) |x| {}
1700 \\}1868 \\}
1701 \\fn bar() -> %i32 { 1 }1869 \\fn bar() -> %i32 { 1 }
1870 \\comptime {@export("foo", foo);}
1702 ,1871 ,
1703 ".tmp_source.zig:2:15: error: expected nullable type, found '%i32'");1872 ".tmp_source.zig:2:15: error: expected nullable type, found '%i32'");
17041873
1705 cases.add("while expected error union, got bool",1874 cases.add("while expected error union, got bool",
1706 \\export fn foo() {1875 \\extern fn foo() {
1707 \\ while (bar()) |x| {} else |err| {}1876 \\ while (bar()) |x| {} else |err| {}
1708 \\}1877 \\}
1709 \\fn bar() -> bool { true }1878 \\fn bar() -> bool { true }
1879 \\comptime {@export("foo", foo);}
1710 ,1880 ,
1711 ".tmp_source.zig:2:15: error: expected error union type, found 'bool'");1881 ".tmp_source.zig:2:15: error: expected error union type, found 'bool'");
17121882
1713 cases.add("while expected error union, got nullable",1883 cases.add("while expected error union, got nullable",
1714 \\export fn foo() {1884 \\extern fn foo() {
1715 \\ while (bar()) |x| {} else |err| {}1885 \\ while (bar()) |x| {} else |err| {}
1716 \\}1886 \\}
1717 \\fn bar() -> ?i32 { 1 }1887 \\fn bar() -> ?i32 { 1 }
1888 \\comptime {@export("foo", foo);}
1718 ,1889 ,
1719 ".tmp_source.zig:2:15: error: expected error union type, found '?i32'");1890 ".tmp_source.zig:2:15: error: expected error union type, found '?i32'");
17201891
1721 cases.add("inline fn calls itself indirectly",1892 cases.add("inline fn calls itself indirectly",
1722 \\export fn foo() {1893 \\extern fn foo() {
1723 \\ bar();1894 \\ bar();
1724 \\}1895 \\}
1725 \\inline fn bar() {1896 \\inline fn bar() {
...@@ -1731,29 +1902,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1731,29 +1902,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1731 \\ quux();1902 \\ quux();
1732 \\}1903 \\}
1733 \\extern fn quux();1904 \\extern fn quux();
1905 \\comptime {@export("foo", foo);}
1734 ,1906 ,
1735 ".tmp_source.zig:4:8: error: unable to inline function");1907 ".tmp_source.zig:4:8: error: unable to inline function");
17361908
1737 cases.add("save reference to inline function",1909 cases.add("save reference to inline function",
1738 \\export fn foo() {1910 \\extern fn foo() {
1739 \\ quux(@ptrToInt(bar));1911 \\ quux(@ptrToInt(bar));
1740 \\}1912 \\}
1741 \\inline fn bar() { }1913 \\inline fn bar() { }
1742 \\extern fn quux(usize);1914 \\extern fn quux(usize);
1915 \\comptime {@export("foo", foo);}
1743 ,1916 ,
1744 ".tmp_source.zig:4:8: error: unable to inline function");1917 ".tmp_source.zig:4:8: error: unable to inline function");
17451918
1746 cases.add("signed integer division",1919 cases.add("signed integer division",
1747 \\export fn foo(a: i32, b: i32) -> i32 {1920 \\extern fn foo(a: i32, b: i32) -> i32 {
1748 \\ a / b1921 \\ a / b
1749 \\}1922 \\}
1923 \\comptime {@export("foo", foo);}
1750 ,1924 ,
1751 ".tmp_source.zig:2:7: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact");1925 ".tmp_source.zig:2:7: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact");
17521926
1753 cases.add("signed integer remainder division",1927 cases.add("signed integer remainder division",
1754 \\export fn foo(a: i32, b: i32) -> i32 {1928 \\extern fn foo(a: i32, b: i32) -> i32 {
1755 \\ a % b1929 \\ a % b
1756 \\}1930 \\}
1931 \\comptime {@export("foo", foo);}
1757 ,1932 ,
1758 ".tmp_source.zig:2:7: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod");1933 ".tmp_source.zig:2:7: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod");
17591934
...@@ -1792,59 +1967,65 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1792,59 +1967,65 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1792 ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits");1967 ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits");
17931968
1794 cases.add("@setDebugSafety twice for same scope",1969 cases.add("@setDebugSafety twice for same scope",
1795 \\export fn foo() {1970 \\extern fn foo() {
1796 \\ @setDebugSafety(this, false);1971 \\ @setDebugSafety(this, false);
1797 \\ @setDebugSafety(this, false);1972 \\ @setDebugSafety(this, false);
1798 \\}1973 \\}
1974 \\comptime {@export("foo", foo);}
1799 ,1975 ,
1800 ".tmp_source.zig:3:5: error: debug safety set twice for same scope",1976 ".tmp_source.zig:3:5: error: debug safety set twice for same scope",
1801 ".tmp_source.zig:2:5: note: first set here");1977 ".tmp_source.zig:2:5: note: first set here");
18021978
1803 cases.add("@setFloatMode twice for same scope",1979 cases.add("@setFloatMode twice for same scope",
1804 \\export fn foo() {1980 \\extern fn foo() {
1805 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);1981 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
1806 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);1982 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
1807 \\}1983 \\}
1984 \\comptime {@export("foo", foo);}
1808 ,1985 ,
1809 ".tmp_source.zig:3:5: error: float mode set twice for same scope",1986 ".tmp_source.zig:3:5: error: float mode set twice for same scope",
1810 ".tmp_source.zig:2:5: note: first set here");1987 ".tmp_source.zig:2:5: note: first set here");
18111988
1812 cases.add("array access of type",1989 cases.add("array access of type",
1813 \\export fn foo() {1990 \\extern fn foo() {
1814 \\ var b: u8[40] = undefined;1991 \\ var b: u8[40] = undefined;
1815 \\}1992 \\}
1993 \\comptime {@export("foo", foo);}
1816 ,1994 ,
1817 ".tmp_source.zig:2:14: error: array access of non-array type 'type'");1995 ".tmp_source.zig:2:14: error: array access of non-array type 'type'");
18181996
1819 cases.add("cannot break out of defer expression",1997 cases.add("cannot break out of defer expression",
1820 \\export fn foo() {1998 \\extern fn foo() {
1821 \\ while (true) {1999 \\ while (true) {
1822 \\ defer {2000 \\ defer {
1823 \\ break;2001 \\ break;
1824 \\ }2002 \\ }
1825 \\ }2003 \\ }
1826 \\}2004 \\}
2005 \\comptime {@export("foo", foo);}
1827 ,2006 ,
1828 ".tmp_source.zig:4:13: error: cannot break out of defer expression");2007 ".tmp_source.zig:4:13: error: cannot break out of defer expression");
18292008
1830 cases.add("cannot continue out of defer expression",2009 cases.add("cannot continue out of defer expression",
1831 \\export fn foo() {2010 \\extern fn foo() {
1832 \\ while (true) {2011 \\ while (true) {
1833 \\ defer {2012 \\ defer {
1834 \\ continue;2013 \\ continue;
1835 \\ }2014 \\ }
1836 \\ }2015 \\ }
1837 \\}2016 \\}
2017 \\comptime {@export("foo", foo);}
1838 ,2018 ,
1839 ".tmp_source.zig:4:13: error: cannot continue out of defer expression");2019 ".tmp_source.zig:4:13: error: cannot continue out of defer expression");
18402020
1841 cases.add("cannot goto out of defer expression",2021 cases.add("cannot goto out of defer expression",
1842 \\export fn foo() {2022 \\extern fn foo() {
1843 \\ defer {2023 \\ defer {
1844 \\ goto label;2024 \\ goto label;
1845 \\ };2025 \\ };
1846 \\label:2026 \\label:
1847 \\}2027 \\}
2028 \\comptime {@export("foo", foo);}
1848 ,2029 ,
1849 ".tmp_source.zig:3:9: error: cannot goto out of defer expression");2030 ".tmp_source.zig:3:9: error: cannot goto out of defer expression");
18502031
...@@ -1878,9 +2059,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1878,9 +2059,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1878 \\const bar = baz + foo;2059 \\const bar = baz + foo;
1879 \\const baz = 1;2060 \\const baz = 1;
1880 \\2061 \\
1881 \\export fn entry() -> i32 {2062 \\extern fn entry() -> i32 {
1882 \\ return bar;2063 \\ return bar;
1883 \\}2064 \\}
2065 \\comptime {@export("entry", entry);}
1884 ,2066 ,
1885 ".tmp_source.zig:1:13: error: aoeu",2067 ".tmp_source.zig:1:13: error: aoeu",
1886 ".tmp_source.zig:3:19: note: referenced here",2068 ".tmp_source.zig:3:19: note: referenced here",
...@@ -1893,9 +2075,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1893,9 +2075,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1893 \\2075 \\
1894 \\var foo: Foo = undefined;2076 \\var foo: Foo = undefined;
1895 \\2077 \\
1896 \\export fn entry() -> usize {2078 \\extern fn entry() -> usize {
1897 \\ return @sizeOf(@typeOf(foo.x));2079 \\ return @sizeOf(@typeOf(foo.x));
1898 \\}2080 \\}
2081 \\comptime {@export("entry", entry);}
1899 ,2082 ,
1900 ".tmp_source.zig:1:13: error: struct 'Foo' contains itself");2083 ".tmp_source.zig:1:13: error: struct 'Foo' contains itself");
19012084
...@@ -1914,16 +2097,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1914,16 +2097,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1914 ".tmp_source.zig:2:15: error: float literal out of range of any type");2097 ".tmp_source.zig:2:15: error: float literal out of range of any type");
19152098
1916 cases.add("explicit cast float literal to integer when there is a fraction component",2099 cases.add("explicit cast float literal to integer when there is a fraction component",
1917 \\export fn entry() -> i32 {2100 \\extern fn entry() -> i32 {
1918 \\ i32(12.34)2101 \\ i32(12.34)
1919 \\}2102 \\}
2103 \\comptime {@export("entry", entry);}
1920 ,2104 ,
1921 ".tmp_source.zig:2:9: error: fractional component prevents float value 12.340000 from being casted to type 'i32'");2105 ".tmp_source.zig:2:9: error: fractional component prevents float value 12.340000 from being casted to type 'i32'");
19222106
1923 cases.add("non pointer given to @ptrToInt",2107 cases.add("non pointer given to @ptrToInt",
1924 \\export fn entry(x: i32) -> usize {2108 \\extern fn entry(x: i32) -> usize {
1925 \\ @ptrToInt(x)2109 \\ @ptrToInt(x)
1926 \\}2110 \\}
2111 \\comptime {@export("entry", entry);}
1927 ,2112 ,
1928 ".tmp_source.zig:2:15: error: expected pointer, found 'i32'");2113 ".tmp_source.zig:2:15: error: expected pointer, found 'i32'");
19292114
...@@ -1942,24 +2127,27 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1942,24 +2127,27 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1942 ".tmp_source.zig:2:15: error: exact shift shifted out 1 bits");2127 ".tmp_source.zig:2:15: error: exact shift shifted out 1 bits");
19432128
1944 cases.add("shifting without int type or comptime known",2129 cases.add("shifting without int type or comptime known",
1945 \\export fn entry(x: u8) -> u8 {2130 \\extern fn entry(x: u8) -> u8 {
1946 \\ return 0x11 << x;2131 \\ return 0x11 << x;
1947 \\}2132 \\}
2133 \\comptime {@export("entry", entry);}
1948 ,2134 ,
1949 ".tmp_source.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known");2135 ".tmp_source.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known");
19502136
1951 cases.add("shifting RHS is log2 of LHS int bit width",2137 cases.add("shifting RHS is log2 of LHS int bit width",
1952 \\export fn entry(x: u8, y: u8) -> u8 {2138 \\extern fn entry(x: u8, y: u8) -> u8 {
1953 \\ return x << y;2139 \\ return x << y;
1954 \\}2140 \\}
2141 \\comptime {@export("entry", entry);}
1955 ,2142 ,
1956 ".tmp_source.zig:2:17: error: expected type 'u3', found 'u8'");2143 ".tmp_source.zig:2:17: error: expected type 'u3', found 'u8'");
19572144
1958 cases.add("globally shadowing a primitive type",2145 cases.add("globally shadowing a primitive type",
1959 \\const u16 = @intType(false, 8);2146 \\const u16 = @intType(false, 8);
1960 \\export fn entry() {2147 \\extern fn entry() {
1961 \\ const a: u16 = 300;2148 \\ const a: u16 = 300;
1962 \\}2149 \\}
2150 \\comptime {@export("entry", entry);}
1963 ,2151 ,
1964 ".tmp_source.zig:1:1: error: declaration shadows type 'u16'");2152 ".tmp_source.zig:1:1: error: declaration shadows type 'u16'");
19652153
...@@ -1969,7 +2157,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1969,7 +2157,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1969 \\ b: u32,2157 \\ b: u32,
1970 \\};2158 \\};
1971 \\2159 \\
1972 \\export fn entry() {2160 \\extern fn entry() {
1973 \\ var foo = Foo { .a = 1, .b = 10 };2161 \\ var foo = Foo { .a = 1, .b = 10 };
1974 \\ bar(&foo.b);2162 \\ bar(&foo.b);
1975 \\}2163 \\}
...@@ -1977,6 +2165,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1977,6 +2165,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1977 \\fn bar(x: &u32) {2165 \\fn bar(x: &u32) {
1978 \\ *x += 1;2166 \\ *x += 1;
1979 \\}2167 \\}
2168 \\comptime {@export("entry", entry);}
1980 ,2169 ,
1981 ".tmp_source.zig:8:13: error: expected type '&u32', found '&align(1) u32'");2170 ".tmp_source.zig:8:13: error: expected type '&u32', found '&align(1) u32'");
19822171
...@@ -1986,7 +2175,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1986,7 +2175,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1986 \\ b: u32,2175 \\ b: u32,
1987 \\};2176 \\};
1988 \\2177 \\
1989 \\export fn entry() {2178 \\extern fn entry() {
1990 \\ var foo = Foo { .a = 1, .b = 10 };2179 \\ var foo = Foo { .a = 1, .b = 10 };
1991 \\ foo.b += 1;2180 \\ foo.b += 1;
1992 \\ bar((&foo.b)[0..1]);2181 \\ bar((&foo.b)[0..1]);
...@@ -1995,55 +2184,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1995,55 +2184,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1995 \\fn bar(x: []u32) {2184 \\fn bar(x: []u32) {
1996 \\ x[0] += 1;2185 \\ x[0] += 1;
1997 \\}2186 \\}
2187 \\comptime {@export("entry", entry);}
1998 ,2188 ,
1999 ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'");2189 ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'");
20002190
2001 cases.add("increase pointer alignment in @ptrCast",2191 cases.add("increase pointer alignment in @ptrCast",
2002 \\export fn entry() -> u32 {2192 \\extern fn entry() -> u32 {
2003 \\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04};2193 \\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04};
2004 \\ const ptr = @ptrCast(&u32, &bytes[0]);2194 \\ const ptr = @ptrCast(&u32, &bytes[0]);
2005 \\ return *ptr;2195 \\ return *ptr;
2006 \\}2196 \\}
2197 \\comptime {@export("entry", entry);}
2007 ,2198 ,
2008 ".tmp_source.zig:3:17: error: cast increases pointer alignment",2199 ".tmp_source.zig:3:17: error: cast increases pointer alignment",
2009 ".tmp_source.zig:3:38: note: '&u8' has alignment 1",2200 ".tmp_source.zig:3:38: note: '&u8' has alignment 1",
2010 ".tmp_source.zig:3:27: note: '&u32' has alignment 4");2201 ".tmp_source.zig:3:27: note: '&u32' has alignment 4");
20112202
2012 cases.add("increase pointer alignment in slice resize",2203 cases.add("increase pointer alignment in slice resize",
2013 \\export fn entry() -> u32 {2204 \\extern fn entry() -> u32 {
2014 \\ var bytes = []u8{0x01, 0x02, 0x03, 0x04};2205 \\ var bytes = []u8{0x01, 0x02, 0x03, 0x04};
2015 \\ return ([]u32)(bytes[0..])[0];2206 \\ return ([]u32)(bytes[0..])[0];
2016 \\}2207 \\}
2208 \\comptime {@export("entry", entry);}
2017 ,2209 ,
2018 ".tmp_source.zig:3:19: error: cast increases pointer alignment",2210 ".tmp_source.zig:3:19: error: cast increases pointer alignment",
2019 ".tmp_source.zig:3:19: note: '[]u8' has alignment 1",2211 ".tmp_source.zig:3:19: note: '[]u8' has alignment 1",
2020 ".tmp_source.zig:3:19: note: '[]u32' has alignment 4");2212 ".tmp_source.zig:3:19: note: '[]u32' has alignment 4");
20212213
2022 cases.add("@alignCast expects pointer or slice",2214 cases.add("@alignCast expects pointer or slice",
2023 \\export fn entry() {2215 \\extern fn entry() {
2024 \\ @alignCast(4, u32(3))2216 \\ @alignCast(4, u32(3))
2025 \\}2217 \\}
2218 \\comptime {@export("entry", entry);}
2026 ,2219 ,
2027 ".tmp_source.zig:2:22: error: expected pointer or slice, found 'u32'");2220 ".tmp_source.zig:2:22: error: expected pointer or slice, found 'u32'");
20282221
2029 cases.add("passing an under-aligned function pointer",2222 cases.add("passing an under-aligned function pointer",
2030 \\export fn entry() {2223 \\extern fn entry() {
2031 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);2224 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
2032 \\}2225 \\}
2033 \\fn testImplicitlyDecreaseFnAlign(ptr: fn () align(8) -> i32, answer: i32) {2226 \\fn testImplicitlyDecreaseFnAlign(ptr: fn () align(8) -> i32, answer: i32) {
2034 \\ if (ptr() != answer) unreachable;2227 \\ if (ptr() != answer) unreachable;
2035 \\}2228 \\}
2036 \\fn alignedSmall() align(4) -> i32 { 1234 }2229 \\fn alignedSmall() align(4) -> i32 { 1234 }
2230 \\comptime {@export("entry", entry);}
2037 ,2231 ,
2038 ".tmp_source.zig:2:35: error: expected type 'fn() align(8) -> i32', found 'fn() align(4) -> i32'");2232 ".tmp_source.zig:2:35: error: expected type 'fn() align(8) -> i32', found 'fn() align(4) -> i32'");
20392233
2040 cases.add("passing a not-aligned-enough pointer to cmpxchg",2234 cases.add("passing a not-aligned-enough pointer to cmpxchg",
2041 \\const AtomicOrder = @import("builtin").AtomicOrder;2235 \\const AtomicOrder = @import("builtin").AtomicOrder;
2042 \\export fn entry() -> bool {2236 \\extern fn entry() -> bool {
2043 \\ var x: i32 align(1) = 1234;2237 \\ var x: i32 align(1) = 1234;
2044 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}2238 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
2045 \\ return x == 5678;2239 \\ return x == 5678;
2046 \\}2240 \\}
2241 \\comptime {@export("entry", entry);}
2047 ,2242 ,
2048 ".tmp_source.zig:4:23: error: expected pointer alignment of at least 4, found 1");2243 ".tmp_source.zig:4:23: error: expected pointer alignment of at least 4, found 1");
20492244
...@@ -2069,17 +2264,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2069,17 +2264,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2069 cases.add("wrong pointer implicitly casted to pointer to @OpaqueType()",2264 cases.add("wrong pointer implicitly casted to pointer to @OpaqueType()",
2070 \\const Derp = @OpaqueType();2265 \\const Derp = @OpaqueType();
2071 \\extern fn bar(d: &Derp);2266 \\extern fn bar(d: &Derp);
2072 \\export fn foo() {2267 \\extern fn foo() {
2073 \\ const x = u8(1);2268 \\ const x = u8(1);
2074 \\ bar(@ptrCast(&c_void, &x));2269 \\ bar(@ptrCast(&c_void, &x));
2075 \\}2270 \\}
2271 \\comptime {@export("foo", foo);}
2076 ,2272 ,
2077 ".tmp_source.zig:5:9: error: expected type '&Derp', found '&c_void'");2273 ".tmp_source.zig:5:9: error: expected type '&Derp', found '&c_void'");
20782274
2079 cases.add("non-const variables of things that require const variables",2275 cases.add("non-const variables of things that require const variables",
2080 \\const Opaque = @OpaqueType();2276 \\const Opaque = @OpaqueType();
2081 \\2277 \\
2082 \\export fn entry(opaque: &Opaque) {2278 \\extern fn entry(opaque: &Opaque) {
2083 \\ var m2 = &2;2279 \\ var m2 = &2;
2084 \\ const y: u32 = *m2;2280 \\ const y: u32 = *m2;
2085 \\2281 \\
...@@ -2099,6 +2295,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2099,6 +2295,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2099 \\const Foo = struct {2295 \\const Foo = struct {
2100 \\ fn bar(self: &const Foo) {}2296 \\ fn bar(self: &const Foo) {}
2101 \\};2297 \\};
2298 \\comptime {@export("entry", entry);}
2102 ,2299 ,
2103 ".tmp_source.zig:4:4: error: variable of type '&const (integer literal)' must be const or comptime",2300 ".tmp_source.zig:4:4: error: variable of type '&const (integer literal)' must be const or comptime",
2104 ".tmp_source.zig:7:4: error: variable of type '(undefined)' must be const or comptime",2301 ".tmp_source.zig:7:4: error: variable of type '(undefined)' must be const or comptime",
...@@ -2113,20 +2310,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2113,20 +2310,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2113 ".tmp_source.zig:17:4: error: unreachable code");2310 ".tmp_source.zig:17:4: error: unreachable code");
21142311
2115 cases.add("wrong types given to atomic order args in cmpxchg",2312 cases.add("wrong types given to atomic order args in cmpxchg",
2116 \\export fn entry() {2313 \\extern fn entry() {
2117 \\ var x: i32 = 1234;2314 \\ var x: i32 = 1234;
2118 \\ while (!@cmpxchg(&x, 1234, 5678, u32(1234), u32(1234))) {}2315 \\ while (!@cmpxchg(&x, 1234, 5678, u32(1234), u32(1234))) {}
2119 \\}2316 \\}
2317 \\comptime {@export("entry", entry);}
2120 ,2318 ,
2121 ".tmp_source.zig:3:41: error: expected type 'AtomicOrder', found 'u32'");2319 ".tmp_source.zig:3:41: error: expected type 'AtomicOrder', found 'u32'");
21222320
2123 cases.add("wrong types given to setGlobalLinkage",
2124 \\export fn entry() {
2125 \\ @setGlobalLinkage(entry, u32(1234));
2126 \\}
2127 ,
2128 ".tmp_source.zig:2:33: error: expected type 'GlobalLinkage', found 'u32'");
2129
2130 cases.add("struct with invalid field",2321 cases.add("struct with invalid field",
2131 \\const std = @import("std");2322 \\const std = @import("std");
2132 \\const Allocator = std.mem.Allocator;2323 \\const Allocator = std.mem.Allocator;
...@@ -2145,12 +2336,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2145,12 +2336,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2145 \\ },2336 \\ },
2146 \\};2337 \\};
2147 \\2338 \\
2148 \\export fn entry() {2339 \\extern fn entry() {
2149 \\ const a = MdNode.Header {2340 \\ const a = MdNode.Header {
2150 \\ .text = MdText.init(&std.debug.global_allocator),2341 \\ .text = MdText.init(&std.debug.global_allocator),
2151 \\ .weight = HeaderWeight.H1,2342 \\ .weight = HeaderWeight.H1,
2152 \\ };2343 \\ };
2153 \\}2344 \\}
2345 \\comptime {@export("entry", entry);}
2154 ,2346 ,
2155 ".tmp_source.zig:14:17: error: use of undeclared identifier 'HeaderValue'");2347 ".tmp_source.zig:14:17: error: use of undeclared identifier 'HeaderValue'");
21562348
...@@ -2162,35 +2354,39 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2162,35 +2354,39 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2162 ".tmp_source.zig:2:5: error: @setAlignStack outside function");2354 ".tmp_source.zig:2:5: error: @setAlignStack outside function");
21632355
2164 cases.add("@setAlignStack in naked function",2356 cases.add("@setAlignStack in naked function",
2165 \\export nakedcc fn entry() {2357 \\nakedcc fn entry() {
2166 \\ @setAlignStack(16);2358 \\ @setAlignStack(16);
2167 \\}2359 \\}
2360 \\comptime {@export("entry", entry);}
2168 ,2361 ,
2169 ".tmp_source.zig:2:5: error: @setAlignStack in naked function");2362 ".tmp_source.zig:2:5: error: @setAlignStack in naked function");
21702363
2171 cases.add("@setAlignStack in inline function",2364 cases.add("@setAlignStack in inline function",
2172 \\export fn entry() {2365 \\extern fn entry() {
2173 \\ foo();2366 \\ foo();
2174 \\}2367 \\}
2175 \\inline fn foo() {2368 \\inline fn foo() {
2176 \\ @setAlignStack(16);2369 \\ @setAlignStack(16);
2177 \\}2370 \\}
2371 \\comptime {@export("entry", entry);}
2178 ,2372 ,
2179 ".tmp_source.zig:5:5: error: @setAlignStack in inline function");2373 ".tmp_source.zig:5:5: error: @setAlignStack in inline function");
21802374
2181 cases.add("@setAlignStack set twice",2375 cases.add("@setAlignStack set twice",
2182 \\export fn entry() {2376 \\extern fn entry() {
2183 \\ @setAlignStack(16);2377 \\ @setAlignStack(16);
2184 \\ @setAlignStack(16);2378 \\ @setAlignStack(16);
2185 \\}2379 \\}
2380 \\comptime {@export("entry", entry);}
2186 ,2381 ,
2187 ".tmp_source.zig:3:5: error: alignstack set twice",2382 ".tmp_source.zig:3:5: error: alignstack set twice",
2188 ".tmp_source.zig:2:5: note: first set here");2383 ".tmp_source.zig:2:5: note: first set here");
21892384
2190 cases.add("@setAlignStack too big",2385 cases.add("@setAlignStack too big",
2191 \\export fn entry() {2386 \\extern fn entry() {
2192 \\ @setAlignStack(511 + 1);2387 \\ @setAlignStack(511 + 1);
2193 \\}2388 \\}
2389 \\comptime {@export("entry", entry);}
2194 ,2390 ,
2195 ".tmp_source.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256");2391 ".tmp_source.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256");
21962392
...@@ -2221,7 +2417,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2221,7 +2417,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2221 \\ LinkLibC,2417 \\ LinkLibC,
2222 \\};2418 \\};
2223 \\2419 \\
2224 \\export fn entry() {2420 \\extern fn entry() {
2225 \\ const tests = []TestCase {2421 \\ const tests = []TestCase {
2226 \\ Free("001"),2422 \\ Free("001"),
2227 \\ Free("002"),2423 \\ Free("002"),
...@@ -2236,13 +2432,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2236,13 +2432,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2236 \\ }2432 \\ }
2237 \\ }2433 \\ }
2238 \\}2434 \\}
2435 \\comptime {@export("entry", entry);}
2239 ,2436 ,
2240 ".tmp_source.zig:37:16: error: cannot store runtime value in compile time variable");2437 ".tmp_source.zig:37:16: error: cannot store runtime value in compile time variable");
22412438
2242 cases.add("field access of opaque type",2439 cases.add("field access of opaque type",
2243 \\const MyType = @OpaqueType();2440 \\const MyType = @OpaqueType();
2244 \\2441 \\
2245 \\export fn entry() -> bool {2442 \\extern fn entry() -> bool {
2246 \\ var x: i32 = 1;2443 \\ var x: i32 = 1;
2247 \\ return bar(@ptrCast(&MyType, &x));2444 \\ return bar(@ptrCast(&MyType, &x));
2248 \\}2445 \\}
...@@ -2250,6 +2447,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2250,6 +2447,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2250 \\fn bar(x: &MyType) -> bool {2447 \\fn bar(x: &MyType) -> bool {
2251 \\ return x.blah;2448 \\ return x.blah;
2252 \\}2449 \\}
2450 \\comptime {@export("entry", entry);}
2253 ,2451 ,
2254 ".tmp_source.zig:9:13: error: type '&MyType' does not support field access");2452 ".tmp_source.zig:9:13: error: type '&MyType' does not support field access");
22552453
...@@ -2353,10 +2551,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2353,10 +2551,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2353 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");2551 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");
23542552
2355 cases.add("calling var args extern function, passing array instead of pointer",2553 cases.add("calling var args extern function, passing array instead of pointer",
2356 \\export fn entry() {2554 \\extern fn entry() {
2357 \\ foo("hello");2555 \\ foo("hello");
2358 \\}2556 \\}
2359 \\pub extern fn foo(format: &const u8, ...);2557 \\pub extern fn foo(format: &const u8, ...);
2558 \\comptime {@export("entry", entry);}
2360 ,2559 ,
2361 ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");2560 ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");
23622561
...@@ -2371,9 +2570,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2371,9 +2570,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2371 \\ }2570 \\ }
2372 \\}2571 \\}
2373 \\2572 \\
2374 \\export fn entry() {2573 \\extern fn entry() {
2375 \\ var allocator: ContextAllocator = undefined;2574 \\ var allocator: ContextAllocator = undefined;
2376 \\}2575 \\}
2576 \\comptime {@export("entry", entry);}
2377 ,2577 ,
2378 ".tmp_source.zig:4:25: error: aoeu",2578 ".tmp_source.zig:4:25: error: aoeu",
2379 ".tmp_source.zig:1:36: note: called from here",2579 ".tmp_source.zig:1:36: note: called from here",
...@@ -2388,9 +2588,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2388,9 +2588,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2388 \\ Five,2588 \\ Five,
2389 \\};2589 \\};
2390 \\2590 \\
2391 \\export fn entry() {2591 \\extern fn entry() {
2392 \\ var x = Small.One;2592 \\ var x = Small.One;
2393 \\}2593 \\}
2594 \\comptime {@export("entry", entry);}
2394 ,2595 ,
2395 ".tmp_source.zig:1:20: error: 'u2' too small to hold all bits; must be at least 'u3'");2596 ".tmp_source.zig:1:20: error: 'u2' too small to hold all bits; must be at least 'u3'");
23962597
...@@ -2401,9 +2602,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2401,9 +2602,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2401 \\ Three,2602 \\ Three,
2402 \\};2603 \\};
2403 \\2604 \\
2404 \\export fn entry() {2605 \\extern fn entry() {
2405 \\ var x = Small.One;2606 \\ var x = Small.One;
2406 \\}2607 \\}
2608 \\comptime {@export("entry", entry);}
2407 ,2609 ,
2408 ".tmp_source.zig:1:20: error: expected integer, found 'f32'");2610 ".tmp_source.zig:1:20: error: expected integer, found 'f32'");
24092611
...@@ -2415,9 +2617,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2415,9 +2617,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2415 \\ Four,2617 \\ Four,
2416 \\};2618 \\};
2417 \\2619 \\
2418 \\export fn entry() {2620 \\extern fn entry() {
2419 \\ var x: u2 = Small.Two;2621 \\ var x: u2 = Small.Two;
2420 \\}2622 \\}
2623 \\comptime {@export("entry", entry);}
2421 ,2624 ,
2422 ".tmp_source.zig:9:22: error: expected type 'u2', found 'Small'");2625 ".tmp_source.zig:9:22: error: expected type 'u2', found 'Small'");
24232626
...@@ -2429,9 +2632,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2429,9 +2632,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2429 \\ Four,2632 \\ Four,
2430 \\};2633 \\};
2431 \\2634 \\
2432 \\export fn entry() {2635 \\extern fn entry() {
2433 \\ var x = u3(Small.Two);2636 \\ var x = u3(Small.Two);
2434 \\}2637 \\}
2638 \\comptime {@export("entry", entry);}
2435 ,2639 ,
2436 ".tmp_source.zig:9:15: error: enum to integer cast to 'u3' instead of its tag type, 'u2'");2640 ".tmp_source.zig:9:15: error: enum to integer cast to 'u3' instead of its tag type, 'u2'");
24372641
...@@ -2443,10 +2647,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2443,10 +2647,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2443 \\ Four,2647 \\ Four,
2444 \\};2648 \\};
2445 \\2649 \\
2446 \\export fn entry() {2650 \\extern fn entry() {
2447 \\ var y = u3(3);2651 \\ var y = u3(3);
2448 \\ var x = Small(y);2652 \\ var x = Small(y);
2449 \\}2653 \\}
2654 \\comptime {@export("entry", entry);}
2450 ,2655 ,
2451 ".tmp_source.zig:10:18: error: integer to enum cast from 'u3' instead of its tag type, 'u2'");2656 ".tmp_source.zig:10:18: error: integer to enum cast from 'u3' instead of its tag type, 'u2'");
24522657
...@@ -2458,9 +2663,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2458,9 +2663,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2458 \\ Four,2663 \\ Four,
2459 \\};2664 \\};
2460 \\2665 \\
2461 \\export fn entry() {2666 \\extern fn entry() {
2462 \\ var y = Small.Two;2667 \\ var y = Small.Two;
2463 \\}2668 \\}
2669 \\comptime {@export("entry", entry);}
2464 ,2670 ,
2465 ".tmp_source.zig:1:19: error: expected unsigned integer, found 'i2'");2671 ".tmp_source.zig:1:19: error: expected unsigned integer, found 'i2'");
24662672
...@@ -2468,9 +2674,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2468,9 +2674,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2468 \\const MultipleChoice = struct {2674 \\const MultipleChoice = struct {
2469 \\ A: i32 = 20,2675 \\ A: i32 = 20,
2470 \\};2676 \\};
2471 \\export fn entry() {2677 \\extern fn entry() {
2472 \\ var x: MultipleChoice = undefined;2678 \\ var x: MultipleChoice = undefined;
2473 \\}2679 \\}
2680 \\comptime {@export("entry", entry);}
2474 ,2681 ,
2475 ".tmp_source.zig:2:14: error: enums, not structs, support field assignment");2682 ".tmp_source.zig:2:14: error: enums, not structs, support field assignment");
24762683
...@@ -2478,26 +2685,29 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2478,26 +2685,29 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2478 \\const MultipleChoice = union {2685 \\const MultipleChoice = union {
2479 \\ A: i32 = 20,2686 \\ A: i32 = 20,
2480 \\};2687 \\};
2481 \\export fn entry() {2688 \\extern fn entry() {
2482 \\ var x: MultipleChoice = undefined;2689 \\ var x: MultipleChoice = undefined;
2483 \\}2690 \\}
2691 \\comptime {@export("entry", entry);}
2484 ,2692 ,
2485 ".tmp_source.zig:2:14: error: non-enum union field assignment",2693 ".tmp_source.zig:2:14: error: non-enum union field assignment",
2486 ".tmp_source.zig:1:24: note: consider 'union(enum)' here");2694 ".tmp_source.zig:1:24: note: consider 'union(enum)' here");
24872695
2488 cases.add("enum with 0 fields",2696 cases.add("enum with 0 fields",
2489 \\const Foo = enum {};2697 \\const Foo = enum {};
2490 \\export fn entry() -> usize {2698 \\extern fn entry() -> usize {
2491 \\ return @sizeOf(Foo);2699 \\ return @sizeOf(Foo);
2492 \\}2700 \\}
2701 \\comptime {@export("entry", entry);}
2493 ,2702 ,
2494 ".tmp_source.zig:1:13: error: enums must have 1 or more fields");2703 ".tmp_source.zig:1:13: error: enums must have 1 or more fields");
24952704
2496 cases.add("union with 0 fields",2705 cases.add("union with 0 fields",
2497 \\const Foo = union {};2706 \\const Foo = union {};
2498 \\export fn entry() -> usize {2707 \\extern fn entry() -> usize {
2499 \\ return @sizeOf(Foo);2708 \\ return @sizeOf(Foo);
2500 \\}2709 \\}
2710 \\comptime {@export("entry", entry);}
2501 ,2711 ,
2502 ".tmp_source.zig:1:13: error: unions must have 1 or more fields");2712 ".tmp_source.zig:1:13: error: unions must have 1 or more fields");
25032713
...@@ -2509,9 +2719,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2509,9 +2719,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2509 \\ D = 1000,2719 \\ D = 1000,
2510 \\ E = 60,2720 \\ E = 60,
2511 \\};2721 \\};
2512 \\export fn entry() {2722 \\extern fn entry() {
2513 \\ var x = MultipleChoice.C;2723 \\ var x = MultipleChoice.C;
2514 \\}2724 \\}
2725 \\comptime {@export("entry", entry);}
2515 ,2726 ,
2516 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",2727 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",
2517 ".tmp_source.zig:4:9: note: other occurrence here");2728 ".tmp_source.zig:4:9: note: other occurrence here");
...@@ -2526,9 +2737,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2526,9 +2737,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2526 \\ A: i32,2737 \\ A: i32,
2527 \\ B: f64,2738 \\ B: f64,
2528 \\};2739 \\};
2529 \\export fn entry() -> usize {2740 \\extern fn entry() -> usize {
2530 \\ return @sizeOf(Payload);2741 \\ return @sizeOf(Payload);
2531 \\}2742 \\}
2743 \\comptime {@export("entry", entry);}
2532 ,2744 ,
2533 ".tmp_source.zig:6:17: error: enum field missing: 'C'",2745 ".tmp_source.zig:6:17: error: enum field missing: 'C'",
2534 ".tmp_source.zig:4:5: note: declared here");2746 ".tmp_source.zig:4:5: note: declared here");
...@@ -2537,9 +2749,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2537,9 +2749,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2537 \\const Foo = union {2749 \\const Foo = union {
2538 \\ A: i32,2750 \\ A: i32,
2539 \\};2751 \\};
2540 \\export fn entry() {2752 \\extern fn entry() {
2541 \\ const x = @TagType(Foo);2753 \\ const x = @TagType(Foo);
2542 \\}2754 \\}
2755 \\comptime {@export("entry", entry);}
2543 ,2756 ,
2544 ".tmp_source.zig:5:24: error: union 'Foo' has no tag",2757 ".tmp_source.zig:5:24: error: union 'Foo' has no tag",
2545 ".tmp_source.zig:1:13: note: consider 'union(enum)' here");2758 ".tmp_source.zig:1:13: note: consider 'union(enum)' here");
...@@ -2548,9 +2761,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2548,9 +2761,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2548 \\const Foo = union(enum(f32)) {2761 \\const Foo = union(enum(f32)) {
2549 \\ A: i32,2762 \\ A: i32,
2550 \\};2763 \\};
2551 \\export fn entry() {2764 \\extern fn entry() {
2552 \\ const x = @TagType(Foo);2765 \\ const x = @TagType(Foo);
2553 \\}2766 \\}
2767 \\comptime {@export("entry", entry);}
2554 ,2768 ,
2555 ".tmp_source.zig:1:23: error: expected integer tag type, found 'f32'");2769 ".tmp_source.zig:1:23: error: expected integer tag type, found 'f32'");
25562770
...@@ -2558,9 +2772,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2558,9 +2772,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2558 \\const Foo = union(u32) {2772 \\const Foo = union(u32) {
2559 \\ A: i32,2773 \\ A: i32,
2560 \\};2774 \\};
2561 \\export fn entry() {2775 \\extern fn entry() {
2562 \\ const x = @TagType(Foo);2776 \\ const x = @TagType(Foo);
2563 \\}2777 \\}
2778 \\comptime {@export("entry", entry);}
2564 ,2779 ,
2565 ".tmp_source.zig:1:18: error: expected enum tag type, found 'u32'");2780 ".tmp_source.zig:1:18: error: expected enum tag type, found 'u32'");
25662781
...@@ -2572,9 +2787,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2572,9 +2787,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2572 \\ D = 1000,2787 \\ D = 1000,
2573 \\ E = 60,2788 \\ E = 60,
2574 \\};2789 \\};
2575 \\export fn entry() {2790 \\extern fn entry() {
2576 \\ var x = MultipleChoice { .C = {} };2791 \\ var x = MultipleChoice { .C = {} };
2577 \\}2792 \\}
2793 \\comptime {@export("entry", entry);}
2578 ,2794 ,
2579 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",2795 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",
2580 ".tmp_source.zig:4:9: note: other occurrence here");2796 ".tmp_source.zig:4:9: note: other occurrence here");
...@@ -2591,9 +2807,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2591,9 +2807,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2591 \\ C: bool,2807 \\ C: bool,
2592 \\ D: bool,2808 \\ D: bool,
2593 \\};2809 \\};
2594 \\export fn entry() {2810 \\extern fn entry() {
2595 \\ var a = Payload {.A = 1234};2811 \\ var a = Payload {.A = 1234};
2596 \\}2812 \\}
2813 \\comptime {@export("entry", entry);}
2597 ,2814 ,
2598 ".tmp_source.zig:10:5: error: enum field not found: 'D'",2815 ".tmp_source.zig:10:5: error: enum field not found: 'D'",
2599 ".tmp_source.zig:1:16: note: enum declared here");2816 ".tmp_source.zig:1:16: note: enum declared here");
...@@ -2604,9 +2821,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2604,9 +2821,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2604 \\ B,2821 \\ B,
2605 \\ C,2822 \\ C,
2606 \\};2823 \\};
2607 \\export fn entry() {2824 \\extern fn entry() {
2608 \\ var b = Letter.B;2825 \\ var b = Letter.B;
2609 \\}2826 \\}
2827 \\comptime {@export("entry", entry);}
2610 ,2828 ,
2611 ".tmp_source.zig:2:8: error: structs and unions, not enums, support field types",2829 ".tmp_source.zig:2:8: error: structs and unions, not enums, support field types",
2612 ".tmp_source.zig:1:16: note: consider 'union(enum)' here");2830 ".tmp_source.zig:1:16: note: consider 'union(enum)' here");
...@@ -2615,9 +2833,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2615,9 +2833,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2615 \\const Letter = struct {2833 \\const Letter = struct {
2616 \\ A,2834 \\ A,
2617 \\};2835 \\};
2618 \\export fn entry() {2836 \\extern fn entry() {
2619 \\ var a = Letter { .A = {} };2837 \\ var a = Letter { .A = {} };
2620 \\}2838 \\}
2839 \\comptime {@export("entry", entry);}
2621 ,2840 ,
2622 ".tmp_source.zig:2:5: error: struct field missing type");2841 ".tmp_source.zig:2:5: error: struct field missing type");
26232842
...@@ -2625,9 +2844,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2625,9 +2844,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2625 \\const Letter = extern union {2844 \\const Letter = extern union {
2626 \\ A,2845 \\ A,
2627 \\};2846 \\};
2628 \\export fn entry() {2847 \\extern fn entry() {
2629 \\ var a = Letter { .A = {} };2848 \\ var a = Letter { .A = {} };
2630 \\}2849 \\}
2850 \\comptime {@export("entry", entry);}
2631 ,2851 ,
2632 ".tmp_source.zig:2:5: error: union field missing type");2852 ".tmp_source.zig:2:5: error: union field missing type");
26332853
...@@ -2642,9 +2862,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2642,9 +2862,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2642 \\ B: f64,2862 \\ B: f64,
2643 \\ C: bool,2863 \\ C: bool,
2644 \\};2864 \\};
2645 \\export fn entry() {2865 \\extern fn entry() {
2646 \\ var a = Payload { .A = { 1234 } };2866 \\ var a = Payload { .A = { 1234 } };
2647 \\}2867 \\}
2868 \\comptime {@export("entry", entry);}
2648 ,2869 ,
2649 ".tmp_source.zig:6:29: error: extern union does not support enum tag type");2870 ".tmp_source.zig:6:29: error: extern union does not support enum tag type");
26502871
...@@ -2659,9 +2880,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2659,9 +2880,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2659 \\ B: f64,2880 \\ B: f64,
2660 \\ C: bool,2881 \\ C: bool,
2661 \\};2882 \\};
2662 \\export fn entry() {2883 \\extern fn entry() {
2663 \\ var a = Payload { .A = { 1234 } };2884 \\ var a = Payload { .A = { 1234 } };
2664 \\}2885 \\}
2886 \\comptime {@export("entry", entry);}
2665 ,2887 ,
2666 ".tmp_source.zig:6:29: error: packed union does not support enum tag type");2888 ".tmp_source.zig:6:29: error: packed union does not support enum tag type");
26672889
...@@ -2671,7 +2893,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2671,7 +2893,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2671 \\ B: f64,2893 \\ B: f64,
2672 \\ C: bool,2894 \\ C: bool,
2673 \\};2895 \\};
2674 \\export fn entry() {2896 \\extern fn entry() {
2675 \\ const a = Payload { .A = { 1234 } };2897 \\ const a = Payload { .A = { 1234 } };
2676 \\ foo(a);2898 \\ foo(a);
2677 \\}2899 \\}
...@@ -2681,6 +2903,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2681,6 +2903,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2681 \\ else => unreachable,2903 \\ else => unreachable,
2682 \\ }2904 \\ }
2683 \\}2905 \\}
2906 \\comptime {@export("entry", entry);}
2684 ,2907 ,
2685 ".tmp_source.zig:11:13: error: switch on union which has no attached enum",2908 ".tmp_source.zig:11:13: error: switch on union which has no attached enum",
2686 ".tmp_source.zig:1:17: note: consider 'union(enum)' here");2909 ".tmp_source.zig:1:17: note: consider 'union(enum)' here");
...@@ -2690,9 +2913,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2690,9 +2913,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2690 \\ A = 10,2913 \\ A = 10,
2691 \\ B = 11,2914 \\ B = 11,
2692 \\};2915 \\};
2693 \\export fn entry() {2916 \\extern fn entry() {
2694 \\ var x = Foo(0);2917 \\ var x = Foo(0);
2695 \\}2918 \\}
2919 \\comptime {@export("entry", entry);}
2696 ,2920 ,
2697 ".tmp_source.zig:6:16: error: enum 'Foo' has no tag matching integer value 0",2921 ".tmp_source.zig:6:16: error: enum 'Foo' has no tag matching integer value 0",
2698 ".tmp_source.zig:1:13: note: 'Foo' declared here");2922 ".tmp_source.zig:1:13: note: 'Foo' declared here");
...@@ -2704,9 +2928,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2704,9 +2928,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2704 \\ B,2928 \\ B,
2705 \\ C,2929 \\ C,
2706 \\};2930 \\};
2707 \\export fn entry() {2931 \\extern fn entry() {
2708 \\ var x: Value = Letter.A;2932 \\ var x: Value = Letter.A;
2709 \\}2933 \\}
2934 \\comptime {@export("entry", entry);}
2710 ,2935 ,
2711 ".tmp_source.zig:8:26: error: cast to union 'Value' must initialize 'i32' field 'A'",2936 ".tmp_source.zig:8:26: error: cast to union 'Value' must initialize 'i32' field 'A'",
2712 ".tmp_source.zig:3:5: note: field 'A' declared here");2937 ".tmp_source.zig:3:5: note: field 'A' declared here");
...@@ -2718,13 +2943,36 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2718,13 +2943,36 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2718 \\ B,2943 \\ B,
2719 \\ C,2944 \\ C,
2720 \\};2945 \\};
2721 \\export fn entry() {2946 \\extern fn entry() {
2722 \\ foo(Letter.A);2947 \\ foo(Letter.A);
2723 \\}2948 \\}
2724 \\fn foo(l: Letter) {2949 \\fn foo(l: Letter) {
2725 \\ var x: Value = l;2950 \\ var x: Value = l;
2726 \\}2951 \\}
2952 \\comptime {@export("entry", entry);}
2727 ,2953 ,
2728 ".tmp_source.zig:11:20: error: runtime cast to union 'Value' which has non-void fields",2954 ".tmp_source.zig:11:20: error: runtime cast to union 'Value' which has non-void fields",
2729 ".tmp_source.zig:3:5: note: field 'A' has type 'i32'");2955 ".tmp_source.zig:3:5: note: field 'A' has type 'i32'");
2956
2957 cases.addCase({
2958 const tc = cases.create("export collision",
2959 \\const foo = @import("foo.zig");
2960 \\
2961 \\comptime {@export("bar", bar);}
2962 \\extern fn bar() -> usize {
2963 \\ return foo.baz;
2964 \\}
2965 ,
2966 "foo.zig:2:11: error: exported symbol collision: 'bar'",
2967 ".tmp_source.zig:3:11: note: other symbol is here");
2968
2969 tc.addSourceFile("foo.zig",
2970 \\extern fn bar() {}
2971 \\comptime {@export("bar", bar);}
2972 \\pub const baz = 1234;
2973 );
2974
2975 tc
2976 });
2977
2730}2978}
test/standalone/issue_339/test.zig+4-1
...@@ -2,6 +2,9 @@ pub fn panic(msg: []const u8) -> noreturn { @breakpoint(); while (true) {} }...@@ -2,6 +2,9 @@ pub fn panic(msg: []const u8) -> noreturn { @breakpoint(); while (true) {} }
22
3fn bar() -> %void {}3fn bar() -> %void {}
44
5export fn foo() {5comptime {
6 @export("foo", foo);
7}
8extern fn foo() {
6 %%bar();9 %%bar();
7}10}
test/translate_c.zig+32-32
...@@ -26,7 +26,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -26,7 +26,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
26 \\ return a < 0 ? -a : a;26 \\ return a < 0 ? -a : a;
27 \\}27 \\}
28 ,28 ,
29 \\export fn abs(a: c_int) -> c_int {29 \\pub fn abs(a: c_int) -> c_int {
30 \\ return if (a < 0) -a else a;30 \\ return if (a < 0) -a else a;
31 \\}31 \\}
32 );32 );
...@@ -325,12 +325,12 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -325,12 +325,12 @@ pub fn addCases(cases: &tests.TranslateCContext) {
325 \\ return a;325 \\ return a;
326 \\}326 \\}
327 ,327 ,
328 \\export fn foo1(_arg_a: c_uint) -> c_uint {328 \\pub fn foo1(_arg_a: c_uint) -> c_uint {
329 \\ var a = _arg_a;329 \\ var a = _arg_a;
330 \\ a +%= 1;330 \\ a +%= 1;
331 \\ return a;331 \\ return a;
332 \\}332 \\}
333 \\export fn foo2(_arg_a: c_int) -> c_int {333 \\pub fn foo2(_arg_a: c_int) -> c_int {
334 \\ var a = _arg_a;334 \\ var a = _arg_a;
335 \\ a += 1;335 \\ a += 1;
336 \\ return a;336 \\ return a;
...@@ -346,7 +346,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -346,7 +346,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
346 \\ return i;346 \\ return i;
347 \\}347 \\}
348 ,348 ,
349 \\export fn log2(_arg_a: c_uint) -> c_int {349 \\pub fn log2(_arg_a: c_uint) -> c_int {
350 \\ var a = _arg_a;350 \\ var a = _arg_a;
351 \\ var i: c_int = 0;351 \\ var i: c_int = 0;
352 \\ while (a > c_uint(0)) {352 \\ while (a > c_uint(0)) {
...@@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
367 \\ return a;367 \\ return a;
368 \\}368 \\}
369 ,369 ,
370 \\export fn max(a: c_int, b: c_int) -> c_int {370 \\pub fn max(a: c_int, b: c_int) -> c_int {
371 \\ if (a < b) return b;371 \\ if (a < b) return b;
372 \\ if (a < b) return b else return a;372 \\ if (a < b) return b else return a;
373 \\}373 \\}
...@@ -382,7 +382,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -382,7 +382,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
382 \\ return a;382 \\ return a;
383 \\}383 \\}
384 ,384 ,
385 \\export fn max(a: c_int, b: c_int) -> c_int {385 \\pub fn max(a: c_int, b: c_int) -> c_int {
386 \\ if (a == b) return a;386 \\ if (a == b) return a;
387 \\ if (a != b) return b;387 \\ if (a != b) return b;
388 \\ return a;388 \\ return a;
...@@ -407,7 +407,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -407,7 +407,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
407 \\ c = a % b;407 \\ c = a % b;
408 \\}408 \\}
409 ,409 ,
410 \\export fn s(a: c_int, b: c_int) -> c_int {410 \\pub fn s(a: c_int, b: c_int) -> c_int {
411 \\ var c: c_int;411 \\ var c: c_int;
412 \\ c = (a + b);412 \\ c = (a + b);
413 \\ c = (a - b);413 \\ c = (a - b);
...@@ -415,7 +415,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -415,7 +415,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
415 \\ c = @divTrunc(a, b);415 \\ c = @divTrunc(a, b);
416 \\ c = @rem(a, b);416 \\ c = @rem(a, b);
417 \\}417 \\}
418 \\export fn u(a: c_uint, b: c_uint) -> c_uint {418 \\pub fn u(a: c_uint, b: c_uint) -> c_uint {
419 \\ var c: c_uint;419 \\ var c: c_uint;
420 \\ c = (a +% b);420 \\ c = (a +% b);
421 \\ c = (a -% b);421 \\ c = (a -% b);
...@@ -430,7 +430,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -430,7 +430,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
430 \\ return (a & b) ^ (a | b);430 \\ return (a & b) ^ (a | b);
431 \\}431 \\}
432 ,432 ,
433 \\export fn max(a: c_int, b: c_int) -> c_int {433 \\pub fn max(a: c_int, b: c_int) -> c_int {
434 \\ return (a & b) ^ (a | b);434 \\ return (a & b) ^ (a | b);
435 \\}435 \\}
436 );436 );
...@@ -444,7 +444,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -444,7 +444,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
444 \\ return a;444 \\ return a;
445 \\}445 \\}
446 ,446 ,
447 \\export fn max(a: c_int, b: c_int) -> c_int {447 \\pub fn max(a: c_int, b: c_int) -> c_int {
448 \\ if ((a < b) or (a == b)) return b;448 \\ if ((a < b) or (a == b)) return b;
449 \\ if ((a >= b) and (a == b)) return a;449 \\ if ((a >= b) and (a == b)) return a;
450 \\ return a;450 \\ return a;
...@@ -458,7 +458,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -458,7 +458,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
458 \\ a = tmp;458 \\ a = tmp;
459 \\}459 \\}
460 ,460 ,
461 \\export fn max(_arg_a: c_int) -> c_int {461 \\pub fn max(_arg_a: c_int) -> c_int {
462 \\ var a = _arg_a;462 \\ var a = _arg_a;
463 \\ var tmp: c_int;463 \\ var tmp: c_int;
464 \\ tmp = a;464 \\ tmp = a;
...@@ -472,7 +472,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -472,7 +472,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
472 \\ c = b = a;472 \\ c = b = a;
473 \\}473 \\}
474 ,474 ,
475 \\export fn max(a: c_int) {475 \\pub fn max(a: c_int) {
476 \\ var b: c_int;476 \\ var b: c_int;
477 \\ var c: c_int;477 \\ var c: c_int;
478 \\ c = {478 \\ c = {
...@@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
493 \\ return i;493 \\ return i;
494 \\}494 \\}
495 ,495 ,
496 \\export fn log2(_arg_a: u32) -> c_int {496 \\pub fn log2(_arg_a: u32) -> c_int {
497 \\ var a = _arg_a;497 \\ var a = _arg_a;
498 \\ var i: c_int = 0;498 \\ var i: c_int = 0;
499 \\ while (a > c_uint(0)) {499 \\ while (a > c_uint(0)) {
...@@ -518,7 +518,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -518,7 +518,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
518 \\void foo(void) { bar(); }518 \\void foo(void) { bar(); }
519 ,519 ,
520 \\pub fn bar() {}520 \\pub fn bar() {}
521 \\export fn foo() {521 \\pub fn foo() {
522 \\ bar();522 \\ bar();
523 \\}523 \\}
524 );524 );
...@@ -534,7 +534,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -534,7 +534,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
534 \\pub const struct_Foo = extern struct {534 \\pub const struct_Foo = extern struct {
535 \\ field: c_int,535 \\ field: c_int,
536 \\};536 \\};
537 \\export fn read_field(foo: ?&struct_Foo) -> c_int {537 \\pub fn read_field(foo: ?&struct_Foo) -> c_int {
538 \\ return (??foo).field;538 \\ return (??foo).field;
539 \\}539 \\}
540 );540 );
...@@ -544,7 +544,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -544,7 +544,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
544 \\ ;;;;;544 \\ ;;;;;
545 \\}545 \\}
546 ,546 ,
547 \\export fn foo() {}547 \\pub fn foo() {}
548 );548 );
549549
550 cases.add("undefined array global",550 cases.add("undefined array global",
...@@ -560,7 +560,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -560,7 +560,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
560 \\}560 \\}
561 ,561 ,
562 \\pub var array: [100]c_int = undefined;562 \\pub var array: [100]c_int = undefined;
563 \\export fn foo(index: c_int) -> c_int {563 \\pub fn foo(index: c_int) -> c_int {
564 \\ return array[index];564 \\ return array[index];
565 \\}565 \\}
566 );566 );
...@@ -571,7 +571,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -571,7 +571,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
571 \\ return (int)a;571 \\ return (int)a;
572 \\}572 \\}
573 ,573 ,
574 \\export fn float_to_int(a: f32) -> c_int {574 \\pub fn float_to_int(a: f32) -> c_int {
575 \\ return c_int(a);575 \\ return c_int(a);
576 \\}576 \\}
577 );577 );
...@@ -581,7 +581,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -581,7 +581,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
581 \\ return x;581 \\ return x;
582 \\}582 \\}
583 ,583 ,
584 \\export fn foo(x: ?&c_ushort) -> ?&c_void {584 \\pub fn foo(x: ?&c_ushort) -> ?&c_void {
585 \\ return @ptrCast(?&c_void, x);585 \\ return @ptrCast(?&c_void, x);
586 \\}586 \\}
587 );587 );
...@@ -592,7 +592,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -592,7 +592,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
592 \\ return sizeof(int);592 \\ return sizeof(int);
593 \\}593 \\}
594 ,594 ,
595 \\export fn size_of() -> usize {595 \\pub fn size_of() -> usize {
596 \\ return @sizeOf(c_int);596 \\ return @sizeOf(c_int);
597 \\}597 \\}
598 );598 );
...@@ -602,7 +602,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -602,7 +602,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
602 \\ return 0;602 \\ return 0;
603 \\}603 \\}
604 ,604 ,
605 \\export fn foo() -> ?&c_int {605 \\pub fn foo() -> ?&c_int {
606 \\ return null;606 \\ return null;
607 \\}607 \\}
608 );608 );
...@@ -612,7 +612,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -612,7 +612,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
612 \\ return 1, 2;612 \\ return 1, 2;
613 \\}613 \\}
614 ,614 ,
615 \\export fn foo() -> c_int {615 \\pub fn foo() -> c_int {
616 \\ return {616 \\ return {
617 \\ _ = 1;617 \\ _ = 1;
618 \\ 2618 \\ 2
...@@ -625,7 +625,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -625,7 +625,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
625 \\ return (1 << 2) >> 1;625 \\ return (1 << 2) >> 1;
626 \\}626 \\}
627 ,627 ,
628 \\export fn foo() -> c_int {628 \\pub fn foo() -> c_int {
629 \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1);629 \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1);
630 \\}630 \\}
631 );631 );
...@@ -643,7 +643,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -643,7 +643,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
643 \\ a <<= (a <<= 1);643 \\ a <<= (a <<= 1);
644 \\}644 \\}
645 ,645 ,
646 \\export fn foo() {646 \\pub fn foo() {
647 \\ var a: c_int = 0;647 \\ var a: c_int = 0;
648 \\ a += {648 \\ a += {
649 \\ const _ref = &a;649 \\ const _ref = &a;
...@@ -701,7 +701,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -701,7 +701,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
701 \\ a <<= (a <<= 1);701 \\ a <<= (a <<= 1);
702 \\}702 \\}
703 ,703 ,
704 \\export fn foo() {704 \\pub fn foo() {
705 \\ var a: c_uint = c_uint(0);705 \\ var a: c_uint = c_uint(0);
706 \\ a +%= {706 \\ a +%= {
707 \\ const _ref = &a;707 \\ const _ref = &a;
...@@ -771,7 +771,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -771,7 +771,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
771 \\ u = u--;771 \\ u = u--;
772 \\}772 \\}
773 ,773 ,
774 \\export fn foo() {774 \\pub fn foo() {
775 \\ var i: c_int = 0;775 \\ var i: c_int = 0;
776 \\ var u: c_uint = c_uint(0);776 \\ var u: c_uint = c_uint(0);
777 \\ i += 1;777 \\ i += 1;
...@@ -819,7 +819,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -819,7 +819,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
819 \\ u = --u;819 \\ u = --u;
820 \\}820 \\}
821 ,821 ,
822 \\export fn foo() {822 \\pub fn foo() {
823 \\ var i: c_int = 0;823 \\ var i: c_int = 0;
824 \\ var u: c_uint = c_uint(0);824 \\ var u: c_uint = c_uint(0);
825 \\ i += 1;825 \\ i += 1;
...@@ -862,7 +862,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -862,7 +862,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
862 \\ while (b != 0);862 \\ while (b != 0);
863 \\}863 \\}
864 ,864 ,
865 \\export fn foo() {865 \\pub fn foo() {
866 \\ var a: c_int = 2;866 \\ var a: c_int = 2;
867 \\ while (true) {867 \\ while (true) {
868 \\ a -= 1;868 \\ a -= 1;
...@@ -886,9 +886,9 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -886,9 +886,9 @@ pub fn addCases(cases: &tests.TranslateCContext) {
886 \\ baz();886 \\ baz();
887 \\}887 \\}
888 ,888 ,
889 \\export fn foo() {}889 \\pub fn foo() {}
890 \\export fn baz() {}890 \\pub fn baz() {}
891 \\export fn bar() {891 \\pub fn bar() {
892 \\ var f: ?extern fn() = foo;892 \\ var f: ?extern fn() = foo;
893 \\ (??f)();893 \\ (??f)();
894 \\ (??f)();894 \\ (??f)();
...@@ -901,7 +901,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -901,7 +901,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
901 \\ *x = 1;901 \\ *x = 1;
902 \\}902 \\}
903 ,903 ,
904 \\export fn foo(x: ?&c_int) {904 \\pub fn foo(x: ?&c_int) {
905 \\ (*??x) = 1;905 \\ (*??x) = 1;
906 \\}906 \\}
907 );907 );