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
58155815
58165816TestDecl = "test" String Block
58175817
5818TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | UseDecl)
5818TopLevelDecl = option("pub") (FnDef | ExternDecl | GlobalVarDecl | UseDecl)
58195819
58205820ErrorValueDecl = "error" Symbol ";"
58215821
58225822GlobalVarDecl = VariableDeclaration ";"
58235823
5824VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") "=" Expression
5824VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") option("section" "(" Expression ")") "=" Expression
58255825
58265826ContainerMember = (ContainerField | FnDef | GlobalVarDecl)
58275827
......@@ -5831,9 +5831,7 @@ UseDecl = "use" Expression ";"
58315831
58325832ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";"
58335833
5834FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("-&gt;" TypeExpr)
5835
5836VisibleMod = "pub" | "export"
5834FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("-&gt;" TypeExpr)
58375835
58385836FnDef = option("inline" | "extern") FnProto Block
58395837
example/hello_world/hello_libc.zig+6-2
......@@ -5,9 +5,13 @@ const c = @cImport({
55 @cInclude("string.h");
66});
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 {
1115 if (c.printf(msg) != c_int(c.strlen(msg)))
1216 return -1;
1317
example/mix_o_files/base64.zig+4-1
......@@ -1,6 +1,9 @@
11const 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 {
47 const src = source_ptr[0..source_len];
58 const dest = dest_ptr[0..dest_len];
69 const base64_decoder = base64.standard_decoder_unsafe;
example/shared_library/mathtest.zig+4-1
......@@ -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 {
25 a + b
36}
src/all_types.hpp+33-28
......@@ -37,6 +37,7 @@ struct IrBasicBlock;
3737struct ScopeDecls;
3838struct ZigWindowsSDK;
3939struct Tld;
40struct TldExport;
4041
4142struct IrGotoItem {
4243 AstNode *source_node;
......@@ -272,7 +273,6 @@ enum ReturnKnowledge {
272273enum VisibMod {
273274 VisibModPrivate,
274275 VisibModPub,
275 VisibModExport,
276276};
277277
278278enum GlobalLinkageId {
......@@ -313,11 +313,14 @@ struct TldVar {
313313 Tld base;
314314
315315 VariableTableEntry *var;
316 AstNode *set_global_section_node;
317 Buf *section_name;
318 AstNode *set_global_linkage_node;
319 GlobalLinkageId linkage;
320316 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;
321324};
322325
323326struct TldFn {
......@@ -432,6 +435,8 @@ struct AstNodeFnProto {
432435 Buf *lib_name;
433436 // populated if the "align A" is present
434437 AstNode *align_expr;
438 // populated if the "section(S)" is present
439 AstNode *section_expr;
435440};
436441
437442struct AstNodeFnDef {
......@@ -487,8 +492,10 @@ struct AstNodeVariableDeclaration {
487492 AstNode *expr;
488493 // populated if this is an extern declaration
489494 Buf *lib_name;
490 // populated if the "align A" is present
495 // populated if the "align(A)" is present
491496 AstNode *align_expr;
497 // populated if the "section(S)" is present
498 AstNode *section_expr;
492499};
493500
494501struct AstNodeErrorValueDecl {
......@@ -1177,6 +1184,12 @@ enum FnInline {
11771184 FnInlineNever,
11781185};
11791186
1187struct FnExport {
1188 Buf name;
1189 GlobalLinkageId linkage;
1190 AstNode *source_node;
1191};
1192
11801193struct FnTableEntry {
11811194 LLVMValueRef llvm_value;
11821195 const char *llvm_name;
......@@ -1204,12 +1217,11 @@ struct FnTableEntry {
12041217 ZigList<IrInstruction *> alloca_list;
12051218 ZigList<VariableTableEntry *> variable_list;
12061219
1207 AstNode *set_global_section_node;
12081220 Buf *section_name;
1209 AstNode *set_global_linkage_node;
1210 GlobalLinkageId linkage;
12111221 AstNode *set_alignstack_node;
12121222 uint32_t alignstack_value;
1223
1224 ZigList<FnExport> export_list;
12131225};
12141226
12151227uint32_t fn_table_entry_hash(FnTableEntry*);
......@@ -1258,8 +1270,6 @@ enum BuiltinFnId {
12581270 BuiltinFnIdSetFloatMode,
12591271 BuiltinFnIdTypeName,
12601272 BuiltinFnIdCanImplicitCast,
1261 BuiltinFnIdSetGlobalSection,
1262 BuiltinFnIdSetGlobalLinkage,
12631273 BuiltinFnIdPanic,
12641274 BuiltinFnIdPtrCast,
12651275 BuiltinFnIdBitCast,
......@@ -1279,6 +1289,8 @@ enum BuiltinFnId {
12791289 BuiltinFnIdOpaqueType,
12801290 BuiltinFnIdSetAlignStack,
12811291 BuiltinFnIdArgType,
1292 BuiltinFnIdExport,
1293 BuiltinFnIdExportWithLinkage,
12821294};
12831295
12841296struct BuiltinFnEntry {
......@@ -1425,7 +1437,7 @@ struct CodeGen {
14251437 HashMap<GenericFnTypeId *, FnTableEntry *, generic_fn_type_id_hash, generic_fn_type_id_eql> generic_table;
14261438 HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table;
14271439 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;
14291441 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;
14301442
14311443
......@@ -1886,8 +1898,6 @@ enum IrInstructionId {
18861898 IrInstructionIdCheckStatementIsVoid,
18871899 IrInstructionIdTypeName,
18881900 IrInstructionIdCanImplicitCast,
1889 IrInstructionIdSetGlobalSection,
1890 IrInstructionIdSetGlobalLinkage,
18911901 IrInstructionIdDeclRef,
18921902 IrInstructionIdPanic,
18931903 IrInstructionIdTagName,
......@@ -1901,6 +1911,7 @@ enum IrInstructionId {
19011911 IrInstructionIdOpaqueType,
19021912 IrInstructionIdSetAlignStack,
19031913 IrInstructionIdArgType,
1914 IrInstructionIdExport,
19041915};
19051916
19061917struct IrInstruction {
......@@ -2626,20 +2637,6 @@ struct IrInstructionCanImplicitCast {
26262637 IrInstruction *target_value;
26272638};
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
26432640struct IrInstructionDeclRef {
26442641 IrInstruction base;
26452642
......@@ -2728,6 +2725,14 @@ struct IrInstructionArgType {
27282725 IrInstruction *arg_index;
27292726};
27302727
2728struct IrInstructionExport {
2729 IrInstruction base;
2730
2731 IrInstruction *name;
2732 IrInstruction *linkage;
2733 IrInstruction *target;
2734};
2735
27312736static const size_t slice_ptr_index = 0;
27322737static 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
10621062 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
10631063
10641064 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;
10661066 fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified;
10671067 } else {
10681068 fn_type_id->cc = fn_proto->cc;
......@@ -1093,6 +1093,38 @@ static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_
10931093 return true;
10941094}
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
10961128static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) {
10971129 assert(proto_node->type == NodeTypeFnProto);
10981130 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) {
24722504 buf_append_buf(buf, tld->name);
24732505}
24742506
2475FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) {
2507FnTableEntry *create_fn_raw(FnInline inline_value) {
24762508 FnTableEntry *fn_entry = allocate<FnTableEntry>(1);
24772509
24782510 fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;
......@@ -2480,7 +2512,6 @@ FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) {
24802512 fn_entry->analyzed_executable.fn_entry = fn_entry;
24812513 fn_entry->ir_executable.fn_entry = fn_entry;
24822514 fn_entry->fn_inline = inline_value;
2483 fn_entry->linkage = linkage;
24842515
24852516 return fn_entry;
24862517}
......@@ -2490,9 +2521,7 @@ FnTableEntry *create_fn(AstNode *proto_node) {
24902521 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
24912522
24922523 FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto;
2493 GlobalLinkageId linkage = (fn_proto->visib_mod == VisibModExport || proto_node->data.fn_proto.is_extern) ?
2494 GlobalLinkageIdStrong : GlobalLinkageIdInternal;
2495 FnTableEntry *fn_entry = create_fn_raw(inline_value, linkage);
2524 FnTableEntry *fn_entry = create_fn_raw(inline_value);
24962525
24972526 fn_entry->proto_node = proto_node;
24982527 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) {
25722601 add_node_error(g, param_node, buf_sprintf("missing parameter name"));
25732602 }
25742603 }
2575 } else if (fn_table_entry->linkage != GlobalLinkageIdInternal) {
2604 } else {
25762605 g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base);
25772606 }
25782607
......@@ -2580,6 +2609,15 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
25802609
25812610 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
25832621 if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) {
25842622 tld_fn->base.resolution = TldResolutionInvalid;
25852623 return;
......@@ -2594,15 +2632,12 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
25942632 {
25952633 if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) {
25962634 g->main_fn = fn_table_entry;
2597
2598 if (tld_fn->base.visib_mod != VisibModExport) {
2599 TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void);
2600 TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;
2601 if (actual_return_type != err_void) {
2602 add_node_error(g, fn_proto->return_type,
2603 buf_sprintf("expected return type of main to be '%%void', instead is '%s'",
2604 buf_ptr(&actual_return_type->name)));
2605 }
2635 TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void);
2636 TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;
2637 if (actual_return_type != err_void) {
2638 add_node_error(g, fn_proto->return_type,
2639 buf_sprintf("expected return type of main to be '%%void', instead is '%s'",
2640 buf_ptr(&actual_return_type->name)));
26062641 }
26072642 } else if ((import->package == g->panic_package || g->have_pub_panic) &&
26082643 buf_eql_str(&fn_table_entry->symbol_name, "panic"))
......@@ -2613,7 +2648,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
26132648 }
26142649 }
26152650 } 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
26182653 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) {
26402675}
26412676
26422677static 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
26572678 {
26582679 auto entry = decls_scope->decl_table.put_unique(tld->name, tld);
26592680 if (entry) {
......@@ -2729,7 +2750,6 @@ static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_s
27292750 g->resolve_queue.append(&tld_comptime->base);
27302751}
27312752
2732
27332753void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node,
27342754 Scope *parent_scope)
27352755{
......@@ -2985,7 +3005,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
29853005 AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration;
29863006
29873007 bool is_const = var_decl->is_const;
2988 bool is_export = (tld_var->base.visib_mod == VisibModExport);
29893008 bool is_extern = var_decl->is_extern;
29903009
29913010 TypeTableEntry *explicit_type = nullptr;
......@@ -2994,20 +3013,13 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
29943013 explicit_type = validate_var_type(g, var_decl->type, proposed_type);
29953014 }
29963015
2997 if (is_export && is_extern) {
2998 add_node_error(g, source_node, buf_sprintf("variable is both export and extern"));
2999 }
3000
30013016 VarLinkage linkage;
3002 if (is_export) {
3003 linkage = VarLinkageExport;
3004 } else if (is_extern) {
3017 if (is_extern) {
30053018 linkage = VarLinkageExternal;
30063019 } else {
30073020 linkage = VarLinkageInternal;
30083021 }
30093022
3010
30113023 IrInstruction *init_value = nullptr;
30123024
30133025 // 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) {
30563068 }
30573069 }
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
30593080 g->global_vars.append(tld_var);
30603081}
30613082
......@@ -3724,8 +3745,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
37243745 Buf *proto_name = proto_node->data.fn_proto.name;
37253746
37263747 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) {
37293752 if (buf_eql_str(proto_name, "main")) {
37303753 g->have_pub_main = true;
37313754 g->windows_subsystem_windows = false;
......@@ -3733,28 +3756,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
37333756 } else if (buf_eql_str(proto_name, "panic")) {
37343757 g->have_pub_panic = true;
37353758 }
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;
37563759 }
3757
37583760 }
37593761 }
37603762
......@@ -5445,3 +5447,4 @@ uint32_t type_ptr_hash(const TypeTableEntry *ptr) {
54455447bool type_ptr_eql(const TypeTableEntry *a, const TypeTableEntry *b) {
54465448 return a == b;
54475449}
5450
src/analyze.hpp+2
......@@ -182,4 +182,6 @@ uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry);
182182TypeTableEntry *get_align_amt_type(CodeGen *g);
183183PackageTableEntry *new_anonymous_package(void);
184184
185Buf *const_value_to_buffer(ConstExprValue *const_val);
186
185187#endif
src/ast_render.cpp+20-1
......@@ -78,7 +78,6 @@ static const char *visib_mod_string(VisibMod mod) {
7878 switch (mod) {
7979 case VisibModPub: return "pub ";
8080 case VisibModPrivate: return "";
81 case VisibModExport: return "export ";
8281 }
8382 zig_unreachable();
8483}
......@@ -440,6 +439,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
440439 }
441440 }
442441 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
444453 AstNode *return_type_node = node->data.fn_proto.return_type;
445454 if (return_type_node != nullptr) {
......@@ -526,6 +535,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
526535 fprintf(ar->f, ": ");
527536 render_node_grouped(ar, node->data.variable_declaration.type);
528537 }
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 }
529548 if (node->data.variable_declaration.expr) {
530549 fprintf(ar->f, " = ");
531550 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) {
391391 }
392392}
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
394408static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
395409 if (fn_table_entry->llvm_value)
396410 return fn_table_entry->llvm_value;
397411
398 bool external_linkage = (fn_table_entry->linkage != GlobalLinkageIdInternal);
399 Buf *symbol_name = get_mangled_name(g, &fn_table_entry->symbol_name, external_linkage);
412 Buf *unmangled_name = &fn_table_entry->symbol_name;
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;
401428 if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall && external_linkage &&
402429 g->zig_target.arch.arch == ZigLLVM_x86)
403430 {
404 // prevent name mangling
431 // prevent llvm name mangling
405432 symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name));
406433 }
407434
408435
409436 TypeTableEntry *fn_type = fn_table_entry->type_entry;
410437 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) {
412439 LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name));
413440 if (existing_llvm_fn) {
414441 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) {
418445 }
419446 } else {
420447 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 }
421454 }
422455 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) {
445478 }
446479 }
447480
448 switch (fn_table_entry->linkage) {
449 case GlobalLinkageIdInternal:
450 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMInternalLinkage);
451 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;
481 LLVMSetLinkage(fn_table_entry->llvm_value, to_llvm_linkage(linkage));
482
483 if (linkage == GlobalLinkageIdInternal) {
484 LLVMSetUnnamedAddr(fn_table_entry->llvm_value, true);
462485 }
463486
464487 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) {
565588 bool is_definition = fn_table_entry->body_node != nullptr;
566589 unsigned flags = 0;
567590 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);
569593 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,
570594 get_di_scope(g, scope->parent), buf_ptr(&fn_table_entry->symbol_name), "",
571595 import->di_file, line_number,
......@@ -3487,8 +3511,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
34873511 case IrInstructionIdCheckStatementIsVoid:
34883512 case IrInstructionIdTypeName:
34893513 case IrInstructionIdCanImplicitCast:
3490 case IrInstructionIdSetGlobalSection:
3491 case IrInstructionIdSetGlobalLinkage:
34923514 case IrInstructionIdDeclRef:
34933515 case IrInstructionIdSwitchVar:
34943516 case IrInstructionIdOffsetOf:
......@@ -3499,6 +3521,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
34993521 case IrInstructionIdSetAlignStack:
35003522 case IrInstructionIdArgType:
35013523 case IrInstructionIdTagType:
3524 case IrInstructionIdExport:
35023525 zig_unreachable();
35033526 case IrInstructionIdReturn:
35043527 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
......@@ -4969,8 +4992,6 @@ static void define_builtin_fns(CodeGen *g) {
49694992 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
49704993 create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
49714994 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2);
4972 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
4973 create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
49744995 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
49754996 create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2);
49764997 create_builtin_fn(g, BuiltinFnIdBitCast, "bitCast", 2);
......@@ -4995,6 +5016,8 @@ static void define_builtin_fns(CodeGen *g) {
49955016 create_builtin_fn(g, BuiltinFnIdOpaqueType, "OpaqueType", 0);
49965017 create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1);
49975018 create_builtin_fn(g, BuiltinFnIdArgType, "ArgType", 2);
5019 create_builtin_fn(g, BuiltinFnIdExport, "export", 2);
5020 create_builtin_fn(g, BuiltinFnIdExportWithLinkage, "exportWithLinkage", 3);
49985021}
49995022
50005023static const char *bool_to_str(bool b) {
......@@ -5433,6 +5456,27 @@ static void gen_root_source(CodeGen *g) {
54335456 assert(g->root_out_name);
54345457 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
54365480 if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS &&
54375481 !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup &&
54385482 ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe))
......@@ -5442,20 +5486,6 @@ static void gen_root_source(CodeGen *g) {
54425486 if (g->zig_target.os == ZigLLVM_Win32 && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) {
54435487 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig");
54445488 }
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
54605490 if (!g->error_during_imports) {
54615491 semantic_analyze(g);
......@@ -5682,7 +5712,7 @@ static void gen_h_file(CodeGen *g) {
56825712 for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) {
56835713 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)
56865716 continue;
56875717
56885718 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 *) {
207207 return IrInstructionIdDeclVar;
208208}
209209
210static constexpr IrInstructionId ir_instruction_id(IrInstructionExport *) {
211 return IrInstructionIdExport;
212}
213
210214static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) {
211215 return IrInstructionIdLoadPtr;
212216}
......@@ -523,14 +527,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCanImplicitCast
523527 return IrInstructionIdCanImplicitCast;
524528}
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
534530static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) {
535531 return IrInstructionIdDeclRef;
536532}
......@@ -1205,6 +1201,24 @@ static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_
12051201 return new_instruction;
12061202}
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
12081222static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) {
12091223 IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node);
12101224 instruction->ptr = ptr;
......@@ -2159,32 +2173,6 @@ static IrInstruction *ir_build_can_implicit_cast(IrBuilder *irb, Scope *scope, A
21592173 return &instruction->base;
21602174}
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
21882176static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node,
21892177 Tld *tld, LVal lval)
21902178{
......@@ -2396,6 +2384,21 @@ static IrInstruction *ir_instruction_declvar_get_dep(IrInstructionDeclVar *instr
23962384 return nullptr;
23972385}
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
23992402static IrInstruction *ir_instruction_loadptr_get_dep(IrInstructionLoadPtr *instruction, size_t index) {
24002403 switch (index) {
24012404 case 0: return instruction->ptr;
......@@ -2979,20 +2982,6 @@ static IrInstruction *ir_instruction_canimplicitcast_get_dep(IrInstructionCanImp
29792982 }
29802983}
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
29962985static IrInstruction *ir_instruction_declref_get_dep(IrInstructionDeclRef *instruction, size_t index) {
29972986 return nullptr;
29982987}
......@@ -3106,6 +3095,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
31063095 return ir_instruction_binop_get_dep((IrInstructionBinOp *) instruction, index);
31073096 case IrInstructionIdDeclVar:
31083097 return ir_instruction_declvar_get_dep((IrInstructionDeclVar *) instruction, index);
3098 case IrInstructionIdExport:
3099 return ir_instruction_export_get_dep((IrInstructionExport *) instruction, index);
31093100 case IrInstructionIdLoadPtr:
31103101 return ir_instruction_loadptr_get_dep((IrInstructionLoadPtr *) instruction, index);
31113102 case IrInstructionIdStorePtr:
......@@ -3264,10 +3255,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
32643255 return ir_instruction_typename_get_dep((IrInstructionTypeName *) instruction, index);
32653256 case IrInstructionIdCanImplicitCast:
32663257 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);
32713258 case IrInstructionIdDeclRef:
32723259 return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index);
32733260 case IrInstructionIdPanic:
......@@ -4528,39 +4515,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
45284515
45294516 return ir_build_can_implicit_cast(irb, scope, node, arg0_value, arg1_value);
45304517 }
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 }
45644518 case BuiltinFnIdPanic:
45654519 {
45664520 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
47844738
47854739 return ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);
47864740 }
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 }
47874766 }
47884767 zig_unreachable();
47894768}
......@@ -5106,6 +5085,11 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
51065085 return align_value;
51075086 }
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
51095093 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope);
51105094 if (init_value == irb->codegen->invalid_instruction)
51115095 return init_value;
......@@ -6355,6 +6339,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
63556339 case NodeTypeSwitchRange:
63566340 case NodeTypeStructField:
63576341 case NodeTypeLabel:
6342 case NodeTypeFnDef:
6343 case NodeTypeFnDecl:
6344 case NodeTypeErrorValueDecl:
6345 case NodeTypeTestDecl:
63586346 zig_unreachable();
63596347 case NodeTypeBlock:
63606348 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
64366424 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval);
64376425 case NodeTypeFnProto:
64386426 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");
64476427 }
64486428 zig_unreachable();
64496429}
......@@ -10481,6 +10461,194 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
1048110461 return ira->codegen->builtin_types.entry_void;
1048210462}
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
1048410652static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,
1048510653 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)
1048610654{
......@@ -12399,102 +12567,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,
1239912567 return ira->codegen->builtin_types.entry_type;
1240012568}
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
1249812570static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
1249912571 IrInstructionSetDebugSafety *set_debug_safety_instruction)
1250012572{
......@@ -16165,10 +16237,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1616516237 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);
1616616238 case IrInstructionIdPtrTypeChild:
1616716239 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);
1617216240 case IrInstructionIdSetDebugSafety:
1617316241 return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);
1617416242 case IrInstructionIdSetFloatMode:
......@@ -16311,6 +16379,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1631116379 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction);
1631216380 case IrInstructionIdTagType:
1631316381 return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction);
16382 case IrInstructionIdExport:
16383 return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction);
1631416384 }
1631516385 zig_unreachable();
1631616386}
......@@ -16418,12 +16488,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1641816488 case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free
1641916489 case IrInstructionIdCheckSwitchProngs:
1642016490 case IrInstructionIdCheckStatementIsVoid:
16421 case IrInstructionIdSetGlobalSection:
16422 case IrInstructionIdSetGlobalLinkage:
1642316491 case IrInstructionIdPanic:
1642416492 case IrInstructionIdSetEvalBranchQuota:
1642516493 case IrInstructionIdPtrTypeOf:
1642616494 case IrInstructionIdSetAlignStack:
16495 case IrInstructionIdExport:
1642716496 return true;
1642816497 case IrInstructionIdPhi:
1642916498 case IrInstructionIdUnOp:
src/ir_print.cpp+21-19
......@@ -899,19 +899,6 @@ static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instructi
899899 ir_print_other_instruction(irp, instruction->child_type);
900900}
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
915902static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) {
916903 const char *ptr_str = instruction->lval.is_ptr ? "ptr " : "";
917904 const char *const_str = instruction->lval.is_const ? "const " : "";
......@@ -991,6 +978,24 @@ static void ir_print_enum_tag_type(IrPrint *irp, IrInstructionTagType *instructi
991978 fprintf(irp->f, ")");
992979}
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
9951000static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
9961001 ir_print_prefix(irp, instruction);
......@@ -1267,12 +1272,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
12671272 case IrInstructionIdPtrTypeOf:
12681273 ir_print_ptr_type_of(irp, (IrInstructionPtrTypeOf *)instruction);
12691274 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;
12761275 case IrInstructionIdDeclRef:
12771276 ir_print_decl_ref(irp, (IrInstructionDeclRef *)instruction);
12781277 break;
......@@ -1306,6 +1305,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
13061305 case IrInstructionIdTagType:
13071306 ir_print_enum_tag_type(irp, (IrInstructionTagType *)instruction);
13081307 break;
1308 case IrInstructionIdExport:
1309 ir_print_export(irp, (IrInstructionExport *)instruction);
1310 break;
13091311 }
13101312 fprintf(irp->f, "\n");
13111313}
src/parser.cpp+20-8
......@@ -1600,6 +1600,14 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
16001600 next_token = &pc->tokens->at(*token_index);
16011601 }
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
16031611 if (next_token->id == TokenIdEq) {
16041612 *token_index += 1;
16051613 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
......@@ -2144,7 +2152,7 @@ static bool statement_terminates_without_semicolon(AstNode *node) {
21442152
21452153/*
21462154Block = "{" 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
21482156*/
21492157static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mandatory) {
21502158 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
22052213}
22062214
22072215/*
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)
22092217*/
22102218static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
22112219 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
22592267 ast_eat_token(pc, token_index, TokenIdRParen);
22602268 next_token = &pc->tokens->at(*token_index);
22612269 }
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 }
22622278 if (next_token->id == TokenIdArrow) {
22632279 *token_index += 1;
22642280 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,
24472463 if (visib_tok->id == TokenIdKeywordPub) {
24482464 *token_index += 1;
24492465 visib_mod = VisibModPub;
2450 } else if (visib_tok->id == TokenIdKeywordExport) {
2451 *token_index += 1;
2452 visib_mod = VisibModExport;
24532466 } else {
24542467 visib_mod = VisibModPrivate;
24552468 }
......@@ -2580,9 +2593,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig
25802593 if (visib_tok->id == TokenIdKeywordPub) {
25812594 *token_index += 1;
25822595 visib_mod = VisibModPub;
2583 } else if (visib_tok->id == TokenIdKeywordExport) {
2584 *token_index += 1;
2585 visib_mod = VisibModExport;
25862596 } else {
25872597 visib_mod = VisibModPrivate;
25882598 }
......@@ -2669,6 +2679,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
26692679 visit_field(&node->data.fn_proto.return_type, visit, context);
26702680 visit_node_list(&node->data.fn_proto.params, visit, context);
26712681 visit_field(&node->data.fn_proto.align_expr, visit, context);
2682 visit_field(&node->data.fn_proto.section_expr, visit, context);
26722683 break;
26732684 case NodeTypeFnDef:
26742685 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
26962707 visit_field(&node->data.variable_declaration.type, visit, context);
26972708 visit_field(&node->data.variable_declaration.expr, visit, context);
26982709 visit_field(&node->data.variable_declaration.align_expr, visit, context);
2710 visit_field(&node->data.variable_declaration.section_expr, visit, context);
26992711 break;
27002712 case NodeTypeErrorValueDecl:
27012713 // none
src/tokenizer.cpp+2-2
......@@ -119,7 +119,6 @@ static const struct ZigKeyword zig_keywords[] = {
119119 {"else", TokenIdKeywordElse},
120120 {"enum", TokenIdKeywordEnum},
121121 {"error", TokenIdKeywordError},
122 {"export", TokenIdKeywordExport},
123122 {"extern", TokenIdKeywordExtern},
124123 {"false", TokenIdKeywordFalse},
125124 {"fn", TokenIdKeywordFn},
......@@ -134,6 +133,7 @@ static const struct ZigKeyword zig_keywords[] = {
134133 {"packed", TokenIdKeywordPacked},
135134 {"pub", TokenIdKeywordPub},
136135 {"return", TokenIdKeywordReturn},
136 {"section", TokenIdKeywordSection},
137137 {"stdcallcc", TokenIdKeywordStdcallCC},
138138 {"struct", TokenIdKeywordStruct},
139139 {"switch", TokenIdKeywordSwitch},
......@@ -1518,7 +1518,6 @@ const char * token_name(TokenId id) {
15181518 case TokenIdKeywordElse: return "else";
15191519 case TokenIdKeywordEnum: return "enum";
15201520 case TokenIdKeywordError: return "error";
1521 case TokenIdKeywordExport: return "export";
15221521 case TokenIdKeywordExtern: return "extern";
15231522 case TokenIdKeywordFalse: return "false";
15241523 case TokenIdKeywordFn: return "fn";
......@@ -1533,6 +1532,7 @@ const char * token_name(TokenId id) {
15331532 case TokenIdKeywordPacked: return "packed";
15341533 case TokenIdKeywordPub: return "pub";
15351534 case TokenIdKeywordReturn: return "return";
1535 case TokenIdKeywordSection: return "section";
15361536 case TokenIdKeywordStdcallCC: return "stdcallcc";
15371537 case TokenIdKeywordStruct: return "struct";
15381538 case TokenIdKeywordSwitch: return "switch";
src/tokenizer.hpp+1-1
......@@ -47,6 +47,7 @@ enum TokenId {
4747 TokenIdFloatLiteral,
4848 TokenIdIntLiteral,
4949 TokenIdKeywordAlign,
50 TokenIdKeywordSection,
5051 TokenIdKeywordAnd,
5152 TokenIdKeywordAsm,
5253 TokenIdKeywordBreak,
......@@ -58,7 +59,6 @@ enum TokenId {
5859 TokenIdKeywordElse,
5960 TokenIdKeywordEnum,
6061 TokenIdKeywordError,
61 TokenIdKeywordExport,
6262 TokenIdKeywordExtern,
6363 TokenIdKeywordFalse,
6464 TokenIdKeywordFn,
src/translate_c.cpp+2-4
......@@ -73,7 +73,6 @@ struct Context {
7373 ImportTableEntry *import;
7474 ZigList<ErrorMsg *> *errors;
7575 VisibMod visib_mod;
76 VisibMod export_visib_mod;
7776 AstNode *root;
7877 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
7978 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) {
32513250
32523251 StorageClass sc = fn_decl->getStorageClass();
32533252 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;
32553255 } else if (sc == SC_Extern || sc == SC_Static) {
32563256 proto_node->data.fn_proto.visib_mod = c->visib_mod;
32573257 } else if (sc == SC_PrivateExtern) {
......@@ -4274,10 +4274,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
42744274 c->errors = errors;
42754275 if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) {
42764276 c->visib_mod = VisibModPub;
4277 c->export_visib_mod = VisibModPub;
42784277 } else {
42794278 c->visib_mod = VisibModPub;
4280 c->export_visib_mod = VisibModExport;
42814279 }
42824280 c->decl_table.init(8);
42834281 c->macro_table.init(8);
std/debug.zig-2
......@@ -96,8 +96,6 @@ const WHITE = "\x1b[37;1m";
9696const DIM = "\x1b[2m";
9797const RESET = "\x1b[0m";
9898
99pub var user_main_fn: ?fn() -> %void = null;
100
10199error PathNotFound;
102100error InvalidDebugInfo;
103101
std/elf.zig+31-31
......@@ -188,39 +188,39 @@ pub const Elf = struct {
188188 if (elf.is_64) {
189189 if (sh_entry_size != 64) return error.InvalidFormat;
190190
191 for (elf.section_headers) |*section| {
192 section.name = %return in.readInt(elf.endian, u32);
193 section.sh_type = %return in.readInt(elf.endian, u32);
194 section.flags = %return in.readInt(elf.endian, u64);
195 section.addr = %return in.readInt(elf.endian, u64);
196 section.offset = %return in.readInt(elf.endian, u64);
197 section.size = %return in.readInt(elf.endian, u64);
198 section.link = %return in.readInt(elf.endian, u32);
199 section.info = %return in.readInt(elf.endian, u32);
200 section.addr_align = %return in.readInt(elf.endian, u64);
201 section.ent_size = %return in.readInt(elf.endian, u64);
191 for (elf.section_headers) |*elf_section| {
192 elf_section.name = %return in.readInt(elf.endian, u32);
193 elf_section.sh_type = %return in.readInt(elf.endian, u32);
194 elf_section.flags = %return in.readInt(elf.endian, u64);
195 elf_section.addr = %return in.readInt(elf.endian, u64);
196 elf_section.offset = %return in.readInt(elf.endian, u64);
197 elf_section.size = %return in.readInt(elf.endian, u64);
198 elf_section.link = %return in.readInt(elf.endian, u32);
199 elf_section.info = %return in.readInt(elf.endian, u32);
200 elf_section.addr_align = %return in.readInt(elf.endian, u64);
201 elf_section.ent_size = %return in.readInt(elf.endian, u64);
202202 }
203203 } else {
204204 if (sh_entry_size != 40) return error.InvalidFormat;
205205
206 for (elf.section_headers) |*section| {
206 for (elf.section_headers) |*elf_section| {
207207 // TODO (multiple occurences) allow implicit cast from %u32 -> %u64 ?
208 section.name = %return in.readInt(elf.endian, u32);
209 section.sh_type = %return in.readInt(elf.endian, u32);
210 section.flags = u64(%return in.readInt(elf.endian, u32));
211 section.addr = u64(%return in.readInt(elf.endian, u32));
212 section.offset = u64(%return in.readInt(elf.endian, u32));
213 section.size = u64(%return in.readInt(elf.endian, u32));
214 section.link = %return in.readInt(elf.endian, u32);
215 section.info = %return in.readInt(elf.endian, u32);
216 section.addr_align = u64(%return in.readInt(elf.endian, u32));
217 section.ent_size = u64(%return in.readInt(elf.endian, u32));
208 elf_section.name = %return in.readInt(elf.endian, u32);
209 elf_section.sh_type = %return in.readInt(elf.endian, u32);
210 elf_section.flags = u64(%return in.readInt(elf.endian, u32));
211 elf_section.addr = u64(%return in.readInt(elf.endian, u32));
212 elf_section.offset = u64(%return in.readInt(elf.endian, u32));
213 elf_section.size = u64(%return in.readInt(elf.endian, u32));
214 elf_section.link = %return in.readInt(elf.endian, u32);
215 elf_section.info = %return in.readInt(elf.endian, u32);
216 elf_section.addr_align = u64(%return in.readInt(elf.endian, u32));
217 elf_section.ent_size = u64(%return in.readInt(elf.endian, u32));
218218 }
219219 }
220220
221 for (elf.section_headers) |*section| {
222 if (section.sh_type != SHT_NOBITS) {
223 const file_end_offset = %return math.add(u64, section.offset, section.size);
221 for (elf.section_headers) |*elf_section| {
222 if (elf_section.sh_type != SHT_NOBITS) {
223 const file_end_offset = %return math.add(u64, elf_section.offset, elf_section.size);
224224 if (stream_end < file_end_offset) return error.InvalidFormat;
225225 }
226226 }
......@@ -243,10 +243,10 @@ pub const Elf = struct {
243243 var file_stream = io.FileInStream.init(elf.in_file);
244244 const in = &file_stream.stream;
245245
246 for (elf.section_headers) |*section| {
247 if (section.sh_type == SHT_NULL) continue;
246 for (elf.section_headers) |*elf_section| {
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;
250250 %return elf.in_file.seekTo(name_offset);
251251
252252 for (name) |expected_c| {
......@@ -256,7 +256,7 @@ pub const Elf = struct {
256256
257257 {
258258 const null_byte = %return in.readByte();
259 if (null_byte == 0) return section;
259 if (null_byte == 0) return elf_section;
260260 }
261261
262262 next_section:
......@@ -265,7 +265,7 @@ pub const Elf = struct {
265265 return null;
266266 }
267267
268 pub fn seekToSection(elf: &Elf, section: &SectionHeader) -> %void {
269 %return elf.in_file.seekTo(section.offset);
268 pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) -> %void {
269 %return elf.in_file.seekTo(elf_section.offset);
270270 }
271271};
std/mem.zig+1
......@@ -4,6 +4,7 @@ const math = @import("math/index.zig");
44const builtin = @import("builtin");
55
66pub const Cmp = math.Cmp;
7error OutOfMemory;
78
89pub const Allocator = struct {
910 /// 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 {
651651 iov_len: usize,
652652};
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
676654pub fn getsockname(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize {
677655 arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len))
678656}
std/os/linux_i386.zig-10
......@@ -502,13 +502,3 @@ pub nakedcc fn restore_rt() {
502502 : [number] "{eax}" (usize(SYS_rt_sigreturn))
503503 : "rcx", "r11")
504504}
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");
55const std = @import("std");
66const 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
138var argc_ptr: &usize = undefined;
149
15
16export nakedcc fn _start() -> noreturn {
17 if (!want_start_symbol) {
18 @setGlobalLinkage(_start, builtin.GlobalLinkage.Internal);
19 unreachable;
10comptime {
11 if (builtin.link_libc) {
12 @export("main", main);
13 } else if (builtin.os == builtin.Os.windows) {
14 @export("WinMainCRTStartup", WinMainCRTStartup);
15 } else {
16 @export("_start", _start);
2017 }
18}
2119
20nakedcc fn _start() -> noreturn {
2221 switch (builtin.arch) {
2322 builtin.Arch.x86_64 => {
2423 argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize));
......@@ -33,14 +32,9 @@ export nakedcc fn _start() -> noreturn {
3332 @noInlineCall(posixCallMainAndExit);
3433}
3534
36export fn WinMainCRTStartup() -> noreturn {
37 if (!want_WinMainCRTStartup) {
38 @setGlobalLinkage(WinMainCRTStartup, builtin.GlobalLinkage.Internal);
39 unreachable;
40 }
35extern fn WinMainCRTStartup() -> noreturn {
4136 @setAlignStack(16);
4237
43 std.debug.user_main_fn = root.main;
4438 root.main() %% std.os.windows.ExitProcess(1);
4539 std.os.windows.ExitProcess(0);
4640}
......@@ -60,17 +54,10 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void {
6054 while (envp[env_count] != null) : (env_count += 1) {}
6155 std.os.posix_environ_raw = @ptrCast(&&u8, envp)[0..env_count];
6256
63 std.debug.user_main_fn = root.main;
64
6557 return root.main();
6658}
6759
68export 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
60extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 {
7461 callMain(usize(c_argc), c_argv, c_envp) %% return 1;
7562 return 0;
7663}
std/special/bootstrap_lib.zig+5-1
......@@ -2,7 +2,11 @@
22
33const 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,
610 lpReserved: std.os.windows.LPVOID) -> std.os.windows.BOOL
711{
812 return std.os.windows.TRUE;
std/special/builtin.zig+23-13
......@@ -13,10 +13,24 @@ pub coldcc fn panic(msg: []const u8) -> noreturn {
1313 }
1414}
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
1630// Note that memset does not return `dest`, like the libc API.
1731// The semantics of memset is dictated by the corresponding
1832// 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) {
2034 @setDebugSafety(this, false);
2135
2236 var index: usize = 0;
......@@ -27,7 +41,7 @@ export fn memset(dest: ?&u8, c: u8, n: usize) {
2741// Note that memcpy does not return `dest`, like the libc API.
2842// The semantics of memcpy is dictated by the corresponding
2943// 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) {
3145 @setDebugSafety(this, false);
3246
3347 var index: usize = 0;
......@@ -35,25 +49,21 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {
3549 (??dest)[index] = (??src)[index];
3650}
3751
38export 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 }
52extern fn __stack_chk_fail() -> noreturn {
4353 @panic("stack smashing detected");
4454}
4555
4656const math = @import("../math/index.zig");
4757
48export 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) }
58extern fn fmodf(x: f32, y: f32) -> f32 { generic_fmod(f32, x, y) }
59extern fn fmod(x: f64, y: f64) -> f64 { generic_fmod(f64, x, y) }
5060
5161// TODO add intrinsics for these (and probably the double version too)
5262// and have the math stuff use the intrinsic. same as @mod and @rem
53export fn floorf(x: f32) -> f32 { math.floor(x) }
54export fn ceilf(x: f32) -> f32 { math.ceil(x) }
55export fn floor(x: f64) -> f64 { math.floor(x) }
56export fn ceil(x: f64) -> f64 { math.ceil(x) }
63extern fn floorf(x: f32) -> f32 { math.floor(x) }
64extern fn ceilf(x: f32) -> f32 { math.ceil(x) }
65extern fn floor(x: f64) -> f64 { math.floor(x) }
66extern fn ceil(x: f64) -> f64 { math.ceil(x) }
5767
5868fn generic_fmod(comptime T: type, x: T, y: T) -> T {
5969 @setDebugSafety(this, false);
std/special/compiler_rt/aulldiv.zig+54-65
......@@ -1,66 +1,55 @@
1const builtin = @import("builtin");
2const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;
3const is_win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386;
4
5export nakedcc fn _aulldiv() {
6 if (is_win32) {
7 @setDebugSafety(this, false);
8 @setGlobalLinkage(_aulldiv, linkage);
9 asm volatile (
10 \\.intel_syntax noprefix
11 \\
12 \\ push ebx
13 \\ push esi
14 \\ mov eax,dword ptr [esp+18h]
15 \\ or eax,eax
16 \\ jne L1
17 \\ mov ecx,dword ptr [esp+14h]
18 \\ mov eax,dword ptr [esp+10h]
19 \\ xor edx,edx
20 \\ div ecx
21 \\ mov ebx,eax
22 \\ mov eax,dword ptr [esp+0Ch]
23 \\ div ecx
24 \\ mov edx,ebx
25 \\ jmp L2
26 \\ L1:
27 \\ mov ecx,eax
28 \\ mov ebx,dword ptr [esp+14h]
29 \\ mov edx,dword ptr [esp+10h]
30 \\ mov eax,dword ptr [esp+0Ch]
31 \\ L3:
32 \\ shr ecx,1
33 \\ rcr ebx,1
34 \\ shr edx,1
35 \\ rcr eax,1
36 \\ or ecx,ecx
37 \\ jne L3
38 \\ div ebx
39 \\ mov esi,eax
40 \\ mul dword ptr [esp+18h]
41 \\ mov ecx,eax
42 \\ mov eax,dword ptr [esp+14h]
43 \\ mul esi
44 \\ add edx,ecx
45 \\ jb L4
46 \\ cmp edx,dword ptr [esp+10h]
47 \\ ja L4
48 \\ jb L5
49 \\ cmp eax,dword ptr [esp+0Ch]
50 \\ jbe L5
51 \\ L4:
52 \\ dec esi
53 \\ L5:
54 \\ xor edx,edx
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;
1pub nakedcc fn _aulldiv() {
2 @setDebugSafety(this, false);
3 asm volatile (
4 \\.intel_syntax noprefix
5 \\
6 \\ push ebx
7 \\ push esi
8 \\ mov eax,dword ptr [esp+18h]
9 \\ or eax,eax
10 \\ jne L1
11 \\ mov ecx,dword ptr [esp+14h]
12 \\ mov eax,dword ptr [esp+10h]
13 \\ xor edx,edx
14 \\ div ecx
15 \\ mov ebx,eax
16 \\ mov eax,dword ptr [esp+0Ch]
17 \\ div ecx
18 \\ mov edx,ebx
19 \\ jmp L2
20 \\ L1:
21 \\ mov ecx,eax
22 \\ mov ebx,dword ptr [esp+14h]
23 \\ mov edx,dword ptr [esp+10h]
24 \\ mov eax,dword ptr [esp+0Ch]
25 \\ L3:
26 \\ shr ecx,1
27 \\ rcr ebx,1
28 \\ shr edx,1
29 \\ rcr eax,1
30 \\ or ecx,ecx
31 \\ jne L3
32 \\ div ebx
33 \\ mov esi,eax
34 \\ mul dword ptr [esp+18h]
35 \\ mov ecx,eax
36 \\ mov eax,dword ptr [esp+14h]
37 \\ mul esi
38 \\ add edx,ecx
39 \\ jb L4
40 \\ cmp edx,dword ptr [esp+10h]
41 \\ ja L4
42 \\ jb L5
43 \\ cmp eax,dword ptr [esp+0Ch]
44 \\ jbe L5
45 \\ L4:
46 \\ dec esi
47 \\ L5:
48 \\ xor edx,edx
49 \\ mov eax,esi
50 \\ L2:
51 \\ pop esi
52 \\ pop ebx
53 \\ ret 10h
54 );
6655}
std/special/compiler_rt/aullrem.zig+55-66
......@@ -1,67 +1,56 @@
1const builtin = @import("builtin");
2const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;
3const is_win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386;
4
5export nakedcc fn _aullrem() {
6 if (is_win32) {
7 @setDebugSafety(this, false);
8 @setGlobalLinkage(_aullrem, linkage);
9 asm volatile (
10 \\.intel_syntax noprefix
11 \\
12 \\ push ebx
13 \\ mov eax,dword ptr [esp+14h]
14 \\ or eax,eax
15 \\ jne L1a
16 \\ mov ecx,dword ptr [esp+10h]
17 \\ mov eax,dword ptr [esp+0Ch]
18 \\ xor edx,edx
19 \\ div ecx
20 \\ mov eax,dword ptr [esp+8]
21 \\ div ecx
22 \\ mov eax,edx
23 \\ xor edx,edx
24 \\ jmp L2a
25 \\ L1a:
26 \\ mov ecx,eax
27 \\ mov ebx,dword ptr [esp+10h]
28 \\ mov edx,dword ptr [esp+0Ch]
29 \\ mov eax,dword ptr [esp+8]
30 \\ L3a:
31 \\ shr ecx,1
32 \\ rcr ebx,1
33 \\ shr edx,1
34 \\ rcr eax,1
35 \\ or ecx,ecx
36 \\ jne L3a
37 \\ div ebx
38 \\ mov ecx,eax
39 \\ mul dword ptr [esp+14h]
40 \\ xchg eax,ecx
41 \\ mul dword ptr [esp+10h]
42 \\ add edx,ecx
43 \\ jb L4a
44 \\ cmp edx,dword ptr [esp+0Ch]
45 \\ ja L4a
46 \\ jb L5a
47 \\ cmp eax,dword ptr [esp+8]
48 \\ jbe L5a
49 \\ L4a:
50 \\ sub eax,dword ptr [esp+10h]
51 \\ sbb edx,dword ptr [esp+14h]
52 \\ L5a:
53 \\ sub eax,dword ptr [esp+8]
54 \\ sbb edx,dword ptr [esp+0Ch]
55 \\ neg edx
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;
1pub nakedcc fn _aullrem() {
2 @setDebugSafety(this, false);
3 asm volatile (
4 \\.intel_syntax noprefix
5 \\
6 \\ push ebx
7 \\ mov eax,dword ptr [esp+14h]
8 \\ or eax,eax
9 \\ jne L1a
10 \\ mov ecx,dword ptr [esp+10h]
11 \\ mov eax,dword ptr [esp+0Ch]
12 \\ xor edx,edx
13 \\ div ecx
14 \\ mov eax,dword ptr [esp+8]
15 \\ div ecx
16 \\ mov eax,edx
17 \\ xor edx,edx
18 \\ jmp L2a
19 \\ L1a:
20 \\ mov ecx,eax
21 \\ mov ebx,dword ptr [esp+10h]
22 \\ mov edx,dword ptr [esp+0Ch]
23 \\ mov eax,dword ptr [esp+8]
24 \\ L3a:
25 \\ shr ecx,1
26 \\ rcr ebx,1
27 \\ shr edx,1
28 \\ rcr eax,1
29 \\ or ecx,ecx
30 \\ jne L3a
31 \\ div ebx
32 \\ mov ecx,eax
33 \\ mul dword ptr [esp+14h]
34 \\ xchg eax,ecx
35 \\ mul dword ptr [esp+10h]
36 \\ add edx,ecx
37 \\ jb L4a
38 \\ cmp edx,dword ptr [esp+0Ch]
39 \\ ja L4a
40 \\ jb L5a
41 \\ cmp eax,dword ptr [esp+8]
42 \\ jbe L5a
43 \\ L4a:
44 \\ sub eax,dword ptr [esp+10h]
45 \\ sbb edx,dword ptr [esp+14h]
46 \\ L5a:
47 \\ sub eax,dword ptr [esp+8]
48 \\ sbb edx,dword ptr [esp+0Ch]
49 \\ neg edx
50 \\ neg eax
51 \\ sbb edx,0
52 \\ L2a:
53 \\ pop ebx
54 \\ ret 10h
55 );
6756}
std/special/compiler_rt/comparetf2.zig+3-42
......@@ -20,11 +20,9 @@ const infRep = exponentMask;
2020
2121const builtin = @import("builtin");
2222const 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 {
2625 @setDebugSafety(this, is_test);
27 @setGlobalLinkage(__letf2, linkage);
2826
2927 const aInt = @bitCast(rep_t, a);
3028 const bInt = @bitCast(rep_t, b);
......@@ -63,14 +61,6 @@ export fn __letf2(a: f128, b: f128) -> c_int {
6361 };
6462}
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
7464// TODO https://github.com/zig-lang/zig/issues/305
7565// and then make the return types of some of these functions the enum instead of c_int
7666const GE_LESS = c_int(-1);
......@@ -78,8 +68,7 @@ const GE_EQUAL = c_int(0);
7868const GE_GREATER = c_int(1);
7969const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
8070
81export fn __getf2(a: f128, b: f128) -> c_int {
82 @setGlobalLinkage(__getf2, linkage);
71pub extern fn __getf2(a: f128, b: f128) -> c_int {
8372 @setDebugSafety(this, is_test);
8473
8574 const aInt = @bitCast(srep_t, a);
......@@ -108,38 +97,10 @@ export fn __getf2(a: f128, b: f128) -> c_int {
10897 };
10998}
11099
111export fn __unordtf2(a: f128, b: f128) -> c_int {
112 @setGlobalLinkage(__unordtf2, linkage);
100pub extern fn __unordtf2(a: f128, b: f128) -> c_int {
113101 @setDebugSafety(this, is_test);
114102
115103 const aAbs = @bitCast(rep_t, a) & absMask;
116104 const bAbs = @bitCast(rep_t, b) & absMask;
117105 return c_int(aAbs > infRep or bAbs > infRep);
118106}
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 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunsdfdi(a: f64) -> u64 {
4pub extern fn __fixunsdfdi(a: f64) -> u64 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunsdfdi, linkage);
86 return fixuint(f64, u64, a);
97}
108
std/special/compiler_rt/fixunsdfsi.zig+1-3
......@@ -1,10 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunsdfsi(a: f64) -> u32 {
4pub extern fn __fixunsdfsi(a: f64) -> u32 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunsdfsi, linkage);
86 return fixuint(f64, u32, a);
97}
108
std/special/compiler_rt/fixunsdfti.zig+1-3
......@@ -1,10 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunsdfti(a: f64) -> u128 {
4pub extern fn __fixunsdfti(a: f64) -> u128 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunsdfti, linkage);
86 return fixuint(f64, u128, a);
97}
108
std/special/compiler_rt/fixunssfdi.zig+1-3
......@@ -1,10 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunssfdi(a: f32) -> u64 {
4pub extern fn __fixunssfdi(a: f32) -> u64 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunssfdi, linkage);
86 return fixuint(f32, u64, a);
97}
108
std/special/compiler_rt/fixunssfsi.zig+1-3
......@@ -1,10 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunssfsi(a: f32) -> u32 {
4pub extern fn __fixunssfsi(a: f32) -> u32 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunssfsi, linkage);
86 return fixuint(f32, u32, a);
97}
108
std/special/compiler_rt/fixunssfti.zig+1-3
......@@ -1,10 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunssfti(a: f32) -> u128 {
4pub extern fn __fixunssfti(a: f32) -> u128 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunssfti, linkage);
86 return fixuint(f32, u128, a);
97}
108
std/special/compiler_rt/fixunstfdi.zig+1-3
......@@ -1,10 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunstfdi(a: f128) -> u64 {
4pub extern fn __fixunstfdi(a: f128) -> u64 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunstfdi, linkage);
86 return fixuint(f128, u64, a);
97}
108
std/special/compiler_rt/fixunstfsi.zig+1-3
......@@ -1,10 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunstfsi(a: f128) -> u32 {
4pub extern fn __fixunstfsi(a: f128) -> u32 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunstfsi, linkage);
86 return fixuint(f128, u32, a);
97}
108
std/special/compiler_rt/fixunstfti.zig+1-3
......@@ -1,10 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
3const linkage = @import("index.zig").linkage;
43
5export fn __fixunstfti(a: f128) -> u128 {
4pub extern fn __fixunstfti(a: f128) -> u128 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__fixunstfti, linkage);
86 return fixuint(f128, u128, a);
97}
108
std/special/compiler_rt/index.zig+165-176
......@@ -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
201const builtin = @import("builtin");
212const 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;
26const win64 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.x86_64;
27const win32_nocrt = win32 and !builtin.link_libc;
28const win64_nocrt = win64 and !builtin.link_libc;
29pub const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak;
30const strong_linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;
37 @exportWithLinkage("__udivti3", @import("udivti3.zig").__udivti3, linkage);
38 @exportWithLinkage("__umodti3", @import("umodti3.zig").__umodti3, linkage);
39
40 @exportWithLinkage("__udivsi3", __udivsi3, linkage);
41 @exportWithLinkage("__udivdi3", __udivdi3, linkage);
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
3273const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
3374
......@@ -41,15 +82,13 @@ pub coldcc fn panic(msg: []const u8) -> noreturn {
4182 }
4283}
4384
44export fn __udivdi3(a: u64, b: u64) -> u64 {
85extern fn __udivdi3(a: u64, b: u64) -> u64 {
4586 @setDebugSafety(this, is_test);
46 @setGlobalLinkage(__udivdi3, linkage);
4787 return __udivmoddi4(a, b, null);
4888}
4989
50export fn __umoddi3(a: u64, b: u64) -> u64 {
90extern fn __umoddi3(a: u64, b: u64) -> u64 {
5191 @setDebugSafety(this, is_test);
52 @setGlobalLinkage(__umoddi3, linkage);
5392
5493 var r: u64 = undefined;
5594 _ = __udivmoddi4(a, b, &r);
......@@ -60,17 +99,11 @@ const AeabiUlDivModResult = extern struct {
6099 quot: u64,
61100 rem: u64,
62101};
63export fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult {
102extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult {
64103 @setDebugSafety(this, is_test);
65 if (comptime isArmArch()) {
66 @setGlobalLinkage(__aeabi_uldivmod, linkage);
67 var result: AeabiUlDivModResult = undefined;
68 result.quot = __udivmoddi4(numerator, denominator, &result.rem);
69 return result;
70 }
71
72 @setGlobalLinkage(__aeabi_uldivmod, builtin.GlobalLinkage.Internal);
73 unreachable;
104 var result: AeabiUlDivModResult = undefined;
105 result.quot = __udivmoddi4(numerator, denominator, &result.rem);
106 return result;
74107}
75108
76109fn isArmArch() -> bool {
......@@ -98,156 +131,124 @@ fn isArmArch() -> bool {
98131 };
99132}
100133
101export nakedcc fn __aeabi_uidivmod() {
134nakedcc fn __aeabi_uidivmod() {
102135 @setDebugSafety(this, false);
103
104 if (comptime isArmArch()) {
105 @setGlobalLinkage(__aeabi_uidivmod, linkage);
106 asm volatile (
107 \\ push { lr }
108 \\ sub sp, sp, #4
109 \\ mov r2, sp
110 \\ bl __udivmodsi4
111 \\ ldr r1, [sp]
112 \\ add sp, sp, #4
113 \\ pop { pc }
114 ::: "r2", "r1");
115 unreachable;
116 }
117
118 @setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.Internal);
136 asm volatile (
137 \\ push { lr }
138 \\ sub sp, sp, #4
139 \\ mov r2, sp
140 \\ bl __udivmodsi4
141 \\ ldr r1, [sp]
142 \\ add sp, sp, #4
143 \\ pop { pc }
144 ::: "r2", "r1");
119145}
120146
121147// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,
122148// then decrement %esp by %eax. Preserves all registers except %esp and flags.
123149// This routine is windows specific
124150// http://msdn.microsoft.com/en-us/library/ms648426.aspx
125export nakedcc fn _chkstk() align(4) {
151nakedcc fn _chkstk() align(4) {
126152 @setDebugSafety(this, false);
127153
128 if (win32_nocrt) {
129 @setGlobalLinkage(_chkstk, strong_linkage);
130 asm volatile (
131 \\ push %%ecx
132 \\ push %%eax
133 \\ cmp $0x1000,%%eax
134 \\ lea 12(%%esp),%%ecx
135 \\ jb 1f
136 \\ 2:
137 \\ sub $0x1000,%%ecx
138 \\ test %%ecx,(%%ecx)
139 \\ sub $0x1000,%%eax
140 \\ cmp $0x1000,%%eax
141 \\ ja 2b
142 \\ 1:
143 \\ sub %%eax,%%ecx
144 \\ test %%ecx,(%%ecx)
145 \\ pop %%eax
146 \\ pop %%ecx
147 \\ ret
148 );
149 unreachable;
150 }
151
152 @setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal);
154 asm volatile (
155 \\ push %%ecx
156 \\ push %%eax
157 \\ cmp $0x1000,%%eax
158 \\ lea 12(%%esp),%%ecx
159 \\ jb 1f
160 \\ 2:
161 \\ sub $0x1000,%%ecx
162 \\ test %%ecx,(%%ecx)
163 \\ sub $0x1000,%%eax
164 \\ cmp $0x1000,%%eax
165 \\ ja 2b
166 \\ 1:
167 \\ sub %%eax,%%ecx
168 \\ test %%ecx,(%%ecx)
169 \\ pop %%eax
170 \\ pop %%ecx
171 \\ ret
172 );
153173}
154174
155export nakedcc fn __chkstk() align(4) {
175nakedcc fn __chkstk() align(4) {
156176 @setDebugSafety(this, false);
157177
158 if (win64_nocrt) {
159 @setGlobalLinkage(__chkstk, strong_linkage);
160 asm volatile (
161 \\ push %%rcx
162 \\ push %%rax
163 \\ cmp $0x1000,%%rax
164 \\ lea 24(%%rsp),%%rcx
165 \\ jb 1f
166 \\2:
167 \\ sub $0x1000,%%rcx
168 \\ test %%rcx,(%%rcx)
169 \\ sub $0x1000,%%rax
170 \\ cmp $0x1000,%%rax
171 \\ ja 2b
172 \\1:
173 \\ sub %%rax,%%rcx
174 \\ test %%rcx,(%%rcx)
175 \\ pop %%rax
176 \\ pop %%rcx
177 \\ ret
178 );
179 unreachable;
180 }
181
182 @setGlobalLinkage(__chkstk, builtin.GlobalLinkage.Internal);
178 asm volatile (
179 \\ push %%rcx
180 \\ push %%rax
181 \\ cmp $0x1000,%%rax
182 \\ lea 24(%%rsp),%%rcx
183 \\ jb 1f
184 \\2:
185 \\ sub $0x1000,%%rcx
186 \\ test %%rcx,(%%rcx)
187 \\ sub $0x1000,%%rax
188 \\ cmp $0x1000,%%rax
189 \\ ja 2b
190 \\1:
191 \\ sub %%rax,%%rcx
192 \\ test %%rcx,(%%rcx)
193 \\ pop %%rax
194 \\ pop %%rcx
195 \\ ret
196 );
183197}
184198
185199// _chkstk routine
186200// This routine is windows specific
187201// http://msdn.microsoft.com/en-us/library/ms648426.aspx
188export nakedcc fn __chkstk_ms() align(4) {
202nakedcc fn __chkstk_ms() align(4) {
189203 @setDebugSafety(this, false);
190204
191 if (win32_nocrt) {
192 @setGlobalLinkage(__chkstk_ms, linkage);
193 asm volatile (
194 \\ push %%ecx
195 \\ push %%eax
196 \\ cmp $0x1000,%%eax
197 \\ lea 12(%%esp),%%ecx
198 \\ jb 1f
199 \\ 2:
200 \\ sub $0x1000,%%ecx
201 \\ test %%ecx,(%%ecx)
202 \\ sub $0x1000,%%eax
203 \\ cmp $0x1000,%%eax
204 \\ ja 2b
205 \\ 1:
206 \\ sub %%eax,%%ecx
207 \\ test %%ecx,(%%ecx)
208 \\ pop %%eax
209 \\ pop %%ecx
210 \\ ret
211 );
212 unreachable;
213 }
214
215 @setGlobalLinkage(__chkstk_ms, builtin.GlobalLinkage.Internal);
205 asm volatile (
206 \\ push %%ecx
207 \\ push %%eax
208 \\ cmp $0x1000,%%eax
209 \\ lea 12(%%esp),%%ecx
210 \\ jb 1f
211 \\ 2:
212 \\ sub $0x1000,%%ecx
213 \\ test %%ecx,(%%ecx)
214 \\ sub $0x1000,%%eax
215 \\ cmp $0x1000,%%eax
216 \\ ja 2b
217 \\ 1:
218 \\ sub %%eax,%%ecx
219 \\ test %%ecx,(%%ecx)
220 \\ pop %%eax
221 \\ pop %%ecx
222 \\ ret
223 );
216224}
217225
218export nakedcc fn ___chkstk_ms() align(4) {
226nakedcc fn ___chkstk_ms() align(4) {
219227 @setDebugSafety(this, false);
220228
221 if (win64_nocrt) {
222 @setGlobalLinkage(___chkstk_ms, linkage);
223 asm volatile (
224 \\ push %%rcx
225 \\ push %%rax
226 \\ cmp $0x1000,%%rax
227 \\ lea 24(%%rsp),%%rcx
228 \\ jb 1f
229 \\2:
230 \\ sub $0x1000,%%rcx
231 \\ test %%rcx,(%%rcx)
232 \\ sub $0x1000,%%rax
233 \\ cmp $0x1000,%%rax
234 \\ ja 2b
235 \\1:
236 \\ sub %%rax,%%rcx
237 \\ test %%rcx,(%%rcx)
238 \\ pop %%rax
239 \\ pop %%rcx
240 \\ ret
241 );
242 unreachable;
243 }
244
245 @setGlobalLinkage(___chkstk_ms, builtin.GlobalLinkage.Internal);
229 asm volatile (
230 \\ push %%rcx
231 \\ push %%rax
232 \\ cmp $0x1000,%%rax
233 \\ lea 24(%%rsp),%%rcx
234 \\ jb 1f
235 \\2:
236 \\ sub $0x1000,%%rcx
237 \\ test %%rcx,(%%rcx)
238 \\ sub $0x1000,%%rax
239 \\ cmp $0x1000,%%rax
240 \\ ja 2b
241 \\1:
242 \\ sub %%rax,%%rcx
243 \\ test %%rcx,(%%rcx)
244 \\ pop %%rax
245 \\ pop %%rcx
246 \\ ret
247 );
246248}
247249
248export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
250extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
249251 @setDebugSafety(this, is_test);
250 @setGlobalLinkage(__udivmodsi4, linkage);
251252
252253 const d = __udivsi3(a, b);
253254 *rem = u32(i32(a) -% (i32(d) * i32(b)));
......@@ -255,19 +256,8 @@ export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
255256}
256257
257258
258// TODO make this an alias instead of an extra function call
259// https://github.com/andrewrk/zig/issues/256
260
261export fn __aeabi_uidiv(n: u32, d: u32) -> u32 {
259extern fn __udivsi3(n: u32, d: u32) -> u32 {
262260 @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
272262 const n_uword_bits: c_uint = u32.bit_count;
273263 // special cases
......@@ -463,4 +453,3 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) {
463453 const q: u32 = __udivsi3(a, b);
464454 assert(q == expected_q);
465455}
466
std/special/compiler_rt/udivmoddi4.zig+1-3
......@@ -1,10 +1,8 @@
11const udivmod = @import("udivmod.zig").udivmod;
22const 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 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__udivmoddi4, linkage);
86 return udivmod(u64, a, b, maybe_rem);
97}
108
std/special/compiler_rt/udivmodti4.zig+1-3
......@@ -1,10 +1,8 @@
11const udivmod = @import("udivmod.zig").udivmod;
22const 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 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__udivmodti4, linkage);
86 return udivmod(u128, a, b, maybe_rem);
97}
108
std/special/compiler_rt/udivti3.zig+1-3
......@@ -1,9 +1,7 @@
11const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
22const 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 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__udivti3, linkage);
86 return __udivmodti4(a, b, null);
97}
std/special/compiler_rt/umodti3.zig+1-3
......@@ -1,10 +1,8 @@
11const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
22const 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 {
65 @setDebugSafety(this, builtin.is_test);
7 @setGlobalLinkage(__umodti3, linkage);
86 var r: u128 = undefined;
97 _ = __udivmodti4(a, b, &r);
108 return r;
test/cases/asm.zig+7-6
......@@ -2,23 +2,24 @@ const config = @import("builtin");
22const assert = @import("std").debug.assert;
33
44comptime {
5 @export("derp", derp);
56 if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
67 asm volatile (
7 \\.globl aoeu;
8 \\.type aoeu, @function;
9 \\.set aoeu, derp;
8 \\.globl my_aoeu_symbol_asdf;
9 \\.type my_aoeu_symbol_asdf, @function;
10 \\.set my_aoeu_symbol_asdf, derp;
1011 );
1112 }
1213}
1314
1415test "module level assembly" {
1516 if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
16 assert(aoeu() == 1234);
17 assert(my_aoeu_symbol_asdf() == 1234);
1718 }
1819}
1920
20extern fn aoeu() -> i32;
21extern fn my_aoeu_symbol_asdf() -> i32;
2122
22export fn derp() -> i32 {
23extern fn derp() -> i32 {
2324 return 1234;
2425}
test/cases/misc.zig+20-3
......@@ -12,8 +12,10 @@ test "empty function with comments" {
1212 emptyFunctionWithComments();
1313}
1414
15export fn disabledExternFn() {
16 @setGlobalLinkage(disabledExternFn, builtin.GlobalLinkage.Internal);
15comptime {
16 @exportWithLinkage("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal)
17}
18extern fn disabledExternFn() {
1719}
1820
1921test "call disabled extern fn" {
......@@ -533,7 +535,10 @@ var global_ptr = &gdt[0];
533535// can't really run this test but we can make sure it has no compile error
534536// and generates code
535537const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000];
536export fn writeToVRam() {
538comptime {
539 @export("writeToVRam", writeToVRam);
540}
541extern fn writeToVRam() {
537542 vram[0] = 'X';
538543}
539544
......@@ -557,3 +562,15 @@ fn hereIsAnOpaqueType(ptr: &OpaqueA) -> &OpaqueA {
557562 var a = ptr;
558563 return a;
559564}
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");
44pub fn addCases(cases: &tests.CompareOutputContext) {
55 cases.addC("hello world with libc",
66 \\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 {
89 \\ _ = c.puts(c"Hello, world!");
910 \\ return 0;
1011 \\}
......@@ -137,7 +138,8 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
137138 \\ @cInclude("stdio.h");
138139 \\});
139140 \\
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 {
141143 \\ if (is_windows) {
142144 \\ // we want actual \n, not \r\n
143145 \\ _ = c._setmode(1, c._O_BINARY);
......@@ -282,7 +284,10 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
282284 cases.addC("expose function pointer to C land",
283285 \\const c = @cImport(@cInclude("stdlib.h"));
284286 \\
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 {
286291 \\ const a_int = @ptrCast(&align(1) i32, a ?? unreachable);
287292 \\ const b_int = @ptrCast(&align(1) i32, b ?? unreachable);
288293 \\ if (*a_int < *b_int) {
......@@ -294,7 +299,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
294299 \\ }
295300 \\}
296301 \\
297 \\export fn main() -> c_int {
302 \\extern fn main() -> c_int {
298303 \\ var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
299304 \\
300305 \\ 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) {
322327 \\ @cInclude("stdio.h");
323328 \\});
324329 \\
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 {
326332 \\ if (is_windows) {
327333 \\ // we want actual \n, not \r\n
328334 \\ _ = c._setmode(1, c._O_BINARY);
test/compile_errors.zig+535-287
......@@ -1,253 +1,328 @@
11const tests = @import("tests.zig");
22
33pub 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
448 cases.add("implicit semicolon - block statement",
5 \\export fn entry() {
49 \\extern fn entry() {
650 \\ {}
751 \\ var good = {};
852 \\ ({})
953 \\ var bad = {};
1054 \\}
55 \\comptime {@export("entry", entry);}
1156 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
1257
1358 cases.add("implicit semicolon - block expr",
14 \\export fn entry() {
59 \\extern fn entry() {
1560 \\ _ = {};
1661 \\ var good = {};
1762 \\ _ = {}
1863 \\ var bad = {};
1964 \\}
65 \\comptime {@export("entry", entry);}
2066 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
2167
2268 cases.add("implicit semicolon - comptime statement",
23 \\export fn entry() {
69 \\extern fn entry() {
2470 \\ comptime {}
2571 \\ var good = {};
2672 \\ comptime ({})
2773 \\ var bad = {};
2874 \\}
75 \\comptime {@export("entry", entry);}
2976 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
3077
3178 cases.add("implicit semicolon - comptime expression",
32 \\export fn entry() {
79 \\extern fn entry() {
3380 \\ _ = comptime {};
3481 \\ var good = {};
3582 \\ _ = comptime {}
3683 \\ var bad = {};
3784 \\}
85 \\comptime {@export("entry", entry);}
3886 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
3987
4088 cases.add("implicit semicolon - defer",
41 \\export fn entry() {
89 \\extern fn entry() {
4290 \\ defer {}
4391 \\ var good = {};
4492 \\ defer ({})
4593 \\ var bad = {};
4694 \\}
95 \\comptime {@export("entry", entry);}
4796 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
4897
4998 cases.add("implicit semicolon - if statement",
50 \\export fn entry() {
99 \\extern fn entry() {
51100 \\ if(true) {}
52101 \\ var good = {};
53102 \\ if(true) ({})
54103 \\ var bad = {};
55104 \\}
105 \\comptime {@export("entry", entry);}
56106 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
57107
58108 cases.add("implicit semicolon - if expression",
59 \\export fn entry() {
109 \\extern fn entry() {
60110 \\ _ = if(true) {};
61111 \\ var good = {};
62112 \\ _ = if(true) {}
63113 \\ var bad = {};
64114 \\}
115 \\comptime {@export("entry", entry);}
65116 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
66117
67118 cases.add("implicit semicolon - if-else statement",
68 \\export fn entry() {
119 \\extern fn entry() {
69120 \\ if(true) {} else {}
70121 \\ var good = {};
71122 \\ if(true) ({}) else ({})
72123 \\ var bad = {};
73124 \\}
125 \\comptime {@export("entry", entry);}
74126 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
75127
76128 cases.add("implicit semicolon - if-else expression",
77 \\export fn entry() {
129 \\extern fn entry() {
78130 \\ _ = if(true) {} else {};
79131 \\ var good = {};
80132 \\ _ = if(true) {} else {}
81133 \\ var bad = {};
82134 \\}
135 \\comptime {@export("entry", entry);}
83136 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
84137
85138 cases.add("implicit semicolon - if-else-if statement",
86 \\export fn entry() {
139 \\extern fn entry() {
87140 \\ if(true) {} else if(true) {}
88141 \\ var good = {};
89142 \\ if(true) ({}) else if(true) ({})
90143 \\ var bad = {};
91144 \\}
145 \\comptime {@export("entry", entry);}
92146 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
93147
94148 cases.add("implicit semicolon - if-else-if expression",
95 \\export fn entry() {
149 \\extern fn entry() {
96150 \\ _ = if(true) {} else if(true) {};
97151 \\ var good = {};
98152 \\ _ = if(true) {} else if(true) {}
99153 \\ var bad = {};
100154 \\}
155 \\comptime {@export("entry", entry);}
101156 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
102157
103158 cases.add("implicit semicolon - if-else-if-else statement",
104 \\export fn entry() {
159 \\extern fn entry() {
105160 \\ if(true) {} else if(true) {} else {}
106161 \\ var good = {};
107162 \\ if(true) ({}) else if(true) ({}) else ({})
108163 \\ var bad = {};
109164 \\}
165 \\comptime {@export("entry", entry);}
110166 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
111167
112168 cases.add("implicit semicolon - if-else-if-else expression",
113 \\export fn entry() {
169 \\extern fn entry() {
114170 \\ _ = if(true) {} else if(true) {} else {};
115171 \\ var good = {};
116172 \\ _ = if(true) {} else if(true) {} else {}
117173 \\ var bad = {};
118174 \\}
175 \\comptime {@export("entry", entry);}
119176 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
120177
121178 cases.add("implicit semicolon - test statement",
122 \\export fn entry() {
179 \\extern fn entry() {
123180 \\ if (foo()) |_| {}
124181 \\ var good = {};
125182 \\ if (foo()) |_| ({})
126183 \\ var bad = {};
127184 \\}
185 \\comptime {@export("entry", entry);}
128186 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
129187
130188 cases.add("implicit semicolon - test expression",
131 \\export fn entry() {
189 \\extern fn entry() {
132190 \\ _ = if (foo()) |_| {};
133191 \\ var good = {};
134192 \\ _ = if (foo()) |_| {}
135193 \\ var bad = {};
136194 \\}
195 \\comptime {@export("entry", entry);}
137196 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
138197
139198 cases.add("implicit semicolon - while statement",
140 \\export fn entry() {
199 \\extern fn entry() {
141200 \\ while(true) {}
142201 \\ var good = {};
143202 \\ while(true) ({})
144203 \\ var bad = {};
145204 \\}
205 \\comptime {@export("entry", entry);}
146206 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
147207
148208 cases.add("implicit semicolon - while expression",
149 \\export fn entry() {
209 \\extern fn entry() {
150210 \\ _ = while(true) {};
151211 \\ var good = {};
152212 \\ _ = while(true) {}
153213 \\ var bad = {};
154214 \\}
215 \\comptime {@export("entry", entry);}
155216 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
156217
157218 cases.add("implicit semicolon - while-continue statement",
158 \\export fn entry() {
219 \\extern fn entry() {
159220 \\ while(true):({}) {}
160221 \\ var good = {};
161222 \\ while(true):({}) ({})
162223 \\ var bad = {};
163224 \\}
225 \\comptime {@export("entry", entry);}
164226 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
165227
166228 cases.add("implicit semicolon - while-continue expression",
167 \\export fn entry() {
229 \\extern fn entry() {
168230 \\ _ = while(true):({}) {};
169231 \\ var good = {};
170232 \\ _ = while(true):({}) {}
171233 \\ var bad = {};
172234 \\}
235 \\comptime {@export("entry", entry);}
173236 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
174237
175238 cases.add("implicit semicolon - for statement",
176 \\export fn entry() {
239 \\extern fn entry() {
177240 \\ for(foo()) {}
178241 \\ var good = {};
179242 \\ for(foo()) ({})
180243 \\ var bad = {};
181244 \\}
245 \\comptime {@export("entry", entry);}
182246 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
183247
184248 cases.add("implicit semicolon - for expression",
185 \\export fn entry() {
249 \\extern fn entry() {
186250 \\ _ = for(foo()) {};
187251 \\ var good = {};
188252 \\ _ = for(foo()) {}
189253 \\ var bad = {};
190254 \\}
255 \\comptime {@export("entry", entry);}
191256 , ".tmp_source.zig:5:5: error: invalid token: 'var'");
192257
193258 cases.add("multiple function definitions",
194259 \\fn a() {}
195260 \\fn a() {}
196 \\export fn entry() { a(); }
261 \\comptime {@export("entry", entry);}
262 \\extern fn entry() { a(); }
197263 , ".tmp_source.zig:2:1: error: redefinition of 'a'");
198264
199265 cases.add("unreachable with return",
200266 \\fn a() -> noreturn {return;}
201 \\export fn entry() { a(); }
267 \\comptime {@export("entry", entry);}
268 \\extern fn entry() { a(); }
202269 , ".tmp_source.zig:1:21: error: expected type 'noreturn', found 'void'");
203270
204271 cases.add("control reaches end of non-void function",
205272 \\fn a() -> i32 {}
206 \\export fn entry() { _ = a(); }
273 \\comptime {@export("entry", entry);}
274 \\extern fn entry() { _ = a(); }
207275 , ".tmp_source.zig:1:15: error: expected type 'i32', found 'void'");
208276
209277 cases.add("undefined function call",
210 \\export fn a() {
278 \\extern fn a() {
211279 \\ b();
212280 \\}
281 \\comptime {@export("a", a);}
213282 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
214283
215284 cases.add("wrong number of arguments",
216 \\export fn a() {
285 \\extern fn a() {
217286 \\ b(1);
218287 \\}
219288 \\fn b(a: i32, b: i32, c: i32) { }
289 \\comptime {@export("a", a);}
220290 , ".tmp_source.zig:2:6: error: expected 3 arguments, found 1");
221291
222292 cases.add("invalid type",
223293 \\fn a() -> bogus {}
224 \\export fn entry() { _ = a(); }
294 \\comptime {@export("entry", entry);}
295 \\extern fn entry() { _ = a(); }
225296 , ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'");
226297
227298 cases.add("pointer to unreachable",
228299 \\fn a() -> &noreturn {}
229 \\export fn entry() { _ = a(); }
300 \\comptime {@export("entry", entry);}
301 \\extern fn entry() { _ = a(); }
230302 , ".tmp_source.zig:1:12: error: pointer to unreachable not allowed");
231303
232304 cases.add("unreachable code",
233 \\export fn a() {
305 \\extern fn a() {
234306 \\ return;
235307 \\ b();
236308 \\}
237309 \\
238310 \\fn b() {}
311 \\comptime {@export("a", a);}
239312 , ".tmp_source.zig:3:5: error: unreachable code");
240313
241314 cases.add("bad import",
242315 \\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(); }
244318 , ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'");
245319
246320 cases.add("undeclared identifier",
247 \\export fn a() {
321 \\extern fn a() {
248322 \\ b +
249323 \\ c
250324 \\}
325 \\comptime {@export("a", a);}
251326 ,
252327 ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'",
253328 ".tmp_source.zig:3:5: error: use of undeclared identifier 'c'");
......@@ -255,99 +330,114 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
255330 cases.add("parameter redeclaration",
256331 \\fn f(a : i32, a : i32) {
257332 \\}
258 \\export fn entry() { f(1, 2); }
333 \\comptime {@export("entry", entry);}
334 \\extern fn entry() { f(1, 2); }
259335 , ".tmp_source.zig:1:15: error: redeclaration of variable 'a'");
260336
261337 cases.add("local variable redeclaration",
262 \\export fn f() {
338 \\extern fn f() {
263339 \\ const a : i32 = 0;
264340 \\ const a = 0;
265341 \\}
342 \\comptime {@export("f", f);}
266343 , ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
267344
268345 cases.add("local variable redeclares parameter",
269346 \\fn f(a : i32) {
270347 \\ const a = 0;
271348 \\}
272 \\export fn entry() { f(1); }
349 \\comptime {@export("entry", entry);}
350 \\extern fn entry() { f(1); }
273351 , ".tmp_source.zig:2:5: error: redeclaration of variable 'a'");
274352
275353 cases.add("variable has wrong type",
276 \\export fn f() -> i32 {
354 \\extern fn f() -> i32 {
277355 \\ const a = c"a";
278356 \\ a
279357 \\}
358 \\comptime {@export("f", f);}
280359 , ".tmp_source.zig:3:5: error: expected type 'i32', found '&const u8'");
281360
282361 cases.add("if condition is bool, not int",
283 \\export fn f() {
362 \\extern fn f() {
284363 \\ if (0) {}
285364 \\}
365 \\comptime {@export("f", f);}
286366 , ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'");
287367
288368 cases.add("assign unreachable",
289 \\export fn f() {
369 \\extern fn f() {
290370 \\ const a = return;
291371 \\}
372 \\comptime {@export("f", f);}
292373 , ".tmp_source.zig:2:5: error: unreachable code");
293374
294375 cases.add("unreachable variable",
295 \\export fn f() {
376 \\extern fn f() {
296377 \\ const a: noreturn = {};
297378 \\}
379 \\comptime {@export("f", f);}
298380 , ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed");
299381
300382 cases.add("unreachable parameter",
301383 \\fn f(a: noreturn) {}
302 \\export fn entry() { f(); }
384 \\comptime {@export("entry", entry);}
385 \\extern fn entry() { f(); }
303386 , ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed");
304387
305388 cases.add("bad assignment target",
306 \\export fn f() {
389 \\extern fn f() {
307390 \\ 3 = 3;
308391 \\}
392 \\comptime {@export("f", f);}
309393 , ".tmp_source.zig:2:7: error: cannot assign to constant");
310394
311395 cases.add("assign to constant variable",
312 \\export fn f() {
396 \\extern fn f() {
313397 \\ const a = 3;
314398 \\ a = 4;
315399 \\}
400 \\comptime {@export("f", f);}
316401 , ".tmp_source.zig:3:7: error: cannot assign to constant");
317402
318403 cases.add("use of undeclared identifier",
319 \\export fn f() {
404 \\extern fn f() {
320405 \\ b = 3;
321406 \\}
407 \\comptime {@export("f", f);}
322408 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
323409
324410 cases.add("const is a statement, not an expression",
325 \\export fn f() {
411 \\extern fn f() {
326412 \\ (const a = 0);
327413 \\}
414 \\comptime {@export("f", f);}
328415 , ".tmp_source.zig:2:6: error: invalid token: 'const'");
329416
330417 cases.add("array access of undeclared identifier",
331 \\export fn f() {
418 \\extern fn f() {
332419 \\ i[i] = i[i];
333420 \\}
421 \\comptime {@export("f", f);}
334422 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",
335423 ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'");
336424
337425 cases.add("array access of non array",
338 \\export fn f() {
426 \\extern fn f() {
339427 \\ var bad : bool = undefined;
340428 \\ bad[bad] = bad[bad];
341429 \\}
430 \\comptime {@export("f", f);}
342431 , ".tmp_source.zig:3:8: error: array access of non-array type 'bool'",
343432 ".tmp_source.zig:3:19: error: array access of non-array type 'bool'");
344433
345434 cases.add("array access with non integer index",
346 \\export fn f() {
435 \\extern fn f() {
347436 \\ var array = "aoeu";
348437 \\ var bad = false;
349438 \\ array[bad] = array[bad];
350439 \\}
440 \\comptime {@export("f", f);}
351441 , ".tmp_source.zig:4:11: error: expected type 'usize', found 'bool'",
352442 ".tmp_source.zig:4:24: error: expected type 'usize', found 'bool'");
353443
......@@ -356,7 +446,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
356446 \\fn f() {
357447 \\ x = 1;
358448 \\}
359 \\export fn entry() { f(); }
449 \\extern fn entry() { f(); }
450 \\comptime {@export("entry", entry);}
360451 , ".tmp_source.zig:3:7: error: cannot assign to constant");
361452
362453
......@@ -365,29 +456,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
365456 \\ const x : i32 = if (b) { 1 };
366457 \\ const y = if (b) { i32(1) };
367458 \\}
368 \\export fn entry() { f(true); }
459 \\extern fn entry() { f(true); }
460 \\comptime {@export("entry", entry);}
369461 , ".tmp_source.zig:2:30: error: integer value 1 cannot be implicitly casted to type 'void'",
370462 ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'");
371463
372464 cases.add("direct struct loop",
373465 \\const A = struct { a : A, };
374 \\export fn entry() -> usize { @sizeOf(A) }
466 \\extern fn entry() -> usize { @sizeOf(A) }
467 \\comptime {@export("entry", entry);}
375468 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
376469
377470 cases.add("indirect struct loop",
378471 \\const A = struct { b : B, };
379472 \\const B = struct { c : C, };
380473 \\const C = struct { a : A, };
381 \\export fn entry() -> usize { @sizeOf(A) }
474 \\extern fn entry() -> usize { @sizeOf(A) }
475 \\comptime {@export("entry", entry);}
382476 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
383477
384478 cases.add("invalid struct field",
385479 \\const A = struct { x : i32, };
386 \\export fn f() {
480 \\extern fn f() {
387481 \\ var a : A = undefined;
388482 \\ a.foo = 1;
389483 \\ const y = a.bar;
390484 \\}
485 \\comptime {@export("f", f);}
391486 ,
392487 ".tmp_source.zig:4:6: error: no member named 'foo' in struct 'A'",
393488 ".tmp_source.zig:5:16: error: no member named 'bar' in struct 'A'");
......@@ -415,7 +510,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
415510 \\ y : i32,
416511 \\ z : i32,
417512 \\};
418 \\export fn f() {
513 \\extern fn f() {
419514 \\ const a = A {
420515 \\ .z = 1,
421516 \\ .y = 2,
......@@ -423,6 +518,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
423518 \\ .z = 4,
424519 \\ };
425520 \\}
521 \\comptime {@export("f", f);}
426522 , ".tmp_source.zig:11:9: error: duplicate field");
427523
428524 cases.add("missing field in struct value expression",
......@@ -431,7 +527,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
431527 \\ y : i32,
432528 \\ z : i32,
433529 \\};
434 \\export fn f() {
530 \\extern fn f() {
435531 \\ // we want the error on the '{' not the 'A' because
436532 \\ // the A could be a complicated expression
437533 \\ const a = A {
......@@ -439,6 +535,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
439535 \\ .y = 2,
440536 \\ };
441537 \\}
538 \\comptime {@export("f", f);}
442539 , ".tmp_source.zig:9:17: error: missing field: 'x'");
443540
444541 cases.add("invalid field in struct value expression",
......@@ -447,69 +544,79 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
447544 \\ y : i32,
448545 \\ z : i32,
449546 \\};
450 \\export fn f() {
547 \\extern fn f() {
451548 \\ const a = A {
452549 \\ .z = 4,
453550 \\ .y = 2,
454551 \\ .foo = 42,
455552 \\ };
456553 \\}
554 \\comptime {@export("f", f);}
457555 , ".tmp_source.zig:10:9: error: no member named 'foo' in struct 'A'");
458556
459557 cases.add("invalid break expression",
460 \\export fn f() {
558 \\extern fn f() {
461559 \\ break;
462560 \\}
561 \\comptime {@export("f", f);}
463562 , ".tmp_source.zig:2:5: error: break expression outside loop");
464563
465564 cases.add("invalid continue expression",
466 \\export fn f() {
565 \\extern fn f() {
467566 \\ continue;
468567 \\}
568 \\comptime {@export("f", f);}
469569 , ".tmp_source.zig:2:5: error: continue expression outside loop");
470570
471571 cases.add("invalid maybe type",
472 \\export fn f() {
572 \\extern fn f() {
473573 \\ if (true) |x| { }
474574 \\}
575 \\comptime {@export("f", f);}
475576 , ".tmp_source.zig:2:9: error: expected nullable type, found 'bool'");
476577
477578 cases.add("cast unreachable",
478579 \\fn f() -> i32 {
479580 \\ i32(return 1)
480581 \\}
481 \\export fn entry() { _ = f(); }
582 \\extern fn entry() { _ = f(); }
583 \\comptime {@export("entry", entry);}
482584 , ".tmp_source.zig:2:8: error: unreachable code");
483585
484586 cases.add("invalid builtin fn",
485587 \\fn f() -> @bogus(foo) {
486588 \\}
487 \\export fn entry() { _ = f(); }
589 \\extern fn entry() { _ = f(); }
590 \\comptime {@export("entry", entry);}
488591 , ".tmp_source.zig:1:11: error: invalid builtin function: 'bogus'");
489592
490593 cases.add("top level decl dependency loop",
491594 \\const a : @typeOf(b) = 0;
492595 \\const b : @typeOf(a) = 0;
493 \\export fn entry() {
596 \\extern fn entry() {
494597 \\ const c = a + b;
495598 \\}
599 \\comptime {@export("entry", entry);}
496600 , ".tmp_source.zig:1:1: error: 'a' depends on itself");
497601
498602 cases.add("noalias on non pointer param",
499603 \\fn f(noalias x: i32) {}
500 \\export fn entry() { f(1234); }
604 \\extern fn entry() { f(1234); }
605 \\comptime {@export("entry", entry);}
501606 , ".tmp_source.zig:1:6: error: noalias on non-pointer parameter");
502607
503608 cases.add("struct init syntax for array",
504609 \\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);}
506612 , ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax");
507613
508614 cases.add("type variables must be constant",
509615 \\var foo = u8;
510 \\export fn entry() -> foo {
616 \\extern fn entry() -> foo {
511617 \\ return 1;
512618 \\}
619 \\comptime {@export("entry", entry);}
513620 , ".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) {
521628 \\ var Bar : i32 = undefined;
522629 \\}
523630 \\
524 \\export fn entry() {
631 \\extern fn entry() {
525632 \\ f(1234);
526633 \\}
634 \\comptime {@export("entry", entry);}
527635 ,
528636 ".tmp_source.zig:4:6: error: redefinition of 'Foo'",
529637 ".tmp_source.zig:1:1: note: previous definition is here",
......@@ -545,7 +653,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
545653 \\ }
546654 \\}
547655 \\
548 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
656 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
657 \\comptime {@export("entry", entry);}
549658 , ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch");
550659
551660 cases.add("switch expression - duplicate enumeration prong",
......@@ -565,7 +674,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
565674 \\ }
566675 \\}
567676 \\
568 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
677 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
678 \\comptime {@export("entry", entry);}
569679 , ".tmp_source.zig:13:15: error: duplicate switch value",
570680 ".tmp_source.zig:10:15: note: other value is here");
571681
......@@ -587,7 +697,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
587697 \\ }
588698 \\}
589699 \\
590 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
700 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
701 \\comptime {@export("entry", entry);}
591702 , ".tmp_source.zig:13:15: error: duplicate switch value",
592703 ".tmp_source.zig:10:15: note: other value is here");
593704
......@@ -599,9 +710,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
599710 \\ else => true,
600711 \\ };
601712 \\}
602 \\export fn entry() {
713 \\extern fn entry() {
603714 \\ f(1234);
604715 \\}
716 \\comptime {@export("entry", entry);}
605717 , ".tmp_source.zig:5:9: error: multiple else prongs in switch expression");
606718
607719 cases.add("switch expression - non exhaustive integer prongs",
......@@ -610,7 +722,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
610722 \\ 0 => {},
611723 \\ }
612724 \\}
613 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
725 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
726 \\comptime {@export("entry", entry);}
614727 ,
615728 ".tmp_source.zig:2:5: error: switch must handle all possibilities");
616729
......@@ -623,7 +736,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
623736 \\ 206 ... 255 => 3,
624737 \\ }
625738 \\}
626 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
739 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
740 \\comptime {@export("entry", entry);}
627741 ,
628742 ".tmp_source.zig:6:9: error: duplicate switch value",
629743 ".tmp_source.zig:5:14: note: previous value is here");
......@@ -635,14 +749,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
635749 \\ }
636750 \\}
637751 \\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);}
639754 ,
640755 ".tmp_source.zig:2:5: error: else prong required when switching on type '&u8'");
641756
642757 cases.add("global variable initializer must be constant expression",
643758 \\extern fn foo() -> i32;
644759 \\const x = foo();
645 \\export fn entry() -> i32 { x }
760 \\extern fn entry() -> i32 { x }
761 \\comptime {@export("entry", entry);}
646762 , ".tmp_source.zig:2:11: error: unable to evaluate constant expression");
647763
648764 cases.add("array concatenation with wrong type",
......@@ -650,7 +766,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
650766 \\const derp = usize(1234);
651767 \\const a = derp ++ "foo";
652768 \\
653 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }
769 \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) }
770 \\comptime {@export("entry", entry);}
654771 , ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'");
655772
656773 cases.add("non compile time array concatenation",
......@@ -658,12 +775,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
658775 \\ s ++ "foo"
659776 \\}
660777 \\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);}
662780 , ".tmp_source.zig:2:5: error: unable to evaluate constant expression");
663781
664782 cases.add("@cImport with bogus include",
665783 \\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);}
667786 , ".tmp_source.zig:1:11: error: C import failed",
668787 ".h:1:10: note: 'bogus.h' file not found");
669788
......@@ -671,17 +790,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
671790 \\const x = 3;
672791 \\const y = &x;
673792 \\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);}
675795 , ".tmp_source.zig:3:26: error: expected type '&const i32', found '&const (integer literal)'");
676796
677797 cases.add("integer overflow error",
678798 \\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);}
680801 , ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'");
681802
682803 cases.add("incompatible number literals",
683804 \\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);}
685807 , ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");
686808
687809 cases.add("missing function call param",
......@@ -707,13 +829,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
707829 \\ const result = members[index]();
708830 \\}
709831 \\
710 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
832 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
833 \\comptime {@export("entry", entry);}
711834 , ".tmp_source.zig:20:34: error: expected 1 arguments, found 0");
712835
713836 cases.add("missing function name and param name",
714837 \\fn () {}
715838 \\fn f(i32) {}
716 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
839 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
840 \\comptime {@export("entry", entry);}
717841 ,
718842 ".tmp_source.zig:1:1: error: missing function name",
719843 ".tmp_source.zig:2:6: error: missing parameter name");
......@@ -723,16 +847,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
723847 \\fn a() -> i32 {0}
724848 \\fn b() -> i32 {1}
725849 \\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);}
727852 , ".tmp_source.zig:1:21: error: expected type 'fn()', found 'fn() -> i32'");
728853
729854 cases.add("extern function pointer mismatch",
730855 \\const fns = [](fn(i32)->i32){ a, b, c };
731856 \\pub fn a(x: i32) -> i32 {x + 0}
732857 \\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)) }
734861 \\
735 \\export fn entry() -> usize { @sizeOf(@typeOf(fns)) }
862 \\comptime {@export("entry", entry);}
863 \\comptime {@export("c", c);}
736864 , ".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) {
740868 \\const x : f64 = 1.0;
741869 \\const y : f32 = x;
742870 \\
743 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
871 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
872 \\comptime {@export("entry", entry);}
744873 , ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'");
745874
746875
747876 cases.add("colliding invalid top level functions",
748877 \\fn func() -> bogus {}
749878 \\fn func() -> bogus {}
750 \\export fn entry() -> usize { @sizeOf(@typeOf(func)) }
879 \\extern fn entry() -> usize { @sizeOf(@typeOf(func)) }
880 \\comptime {@export("entry", entry);}
751881 ,
752882 ".tmp_source.zig:2:1: error: redefinition of 'func'",
753883 ".tmp_source.zig:1:14: error: use of undeclared identifier 'bogus'");
......@@ -755,7 +885,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
755885
756886 cases.add("bogus compile var",
757887 \\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);}
759890 , ".tmp_source.zig:1:29: error: no member named 'bogus' in '");
760891
761892
......@@ -766,7 +897,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
766897 \\var global_var: usize = 1;
767898 \\fn get() -> usize { global_var }
768899 \\
769 \\export fn entry() -> usize { @sizeOf(@typeOf(Foo)) }
900 \\extern fn entry() -> usize { @sizeOf(@typeOf(Foo)) }
901 \\comptime {@export("entry", entry);}
770902 ,
771903 ".tmp_source.zig:5:21: error: unable to evaluate constant expression",
772904 ".tmp_source.zig:2:12: note: called from here",
......@@ -779,7 +911,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
779911 \\};
780912 \\const x = Foo {.field = 1} + Foo {.field = 2};
781913 \\
782 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }
914 \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) }
915 \\comptime {@export("entry", entry);}
783916 , ".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) {
789922 \\const int_x = u32(1) / u32(0);
790923 \\const float_x = f32(1.0) / f32(0.0);
791924 \\
792 \\export fn entry1() -> usize { @sizeOf(@typeOf(lit_int_x)) }
793 \\export fn entry2() -> usize { @sizeOf(@typeOf(lit_float_x)) }
794 \\export fn entry3() -> usize { @sizeOf(@typeOf(int_x)) }
795 \\export fn entry4() -> usize { @sizeOf(@typeOf(float_x)) }
925 \\extern fn entry1() -> usize { @sizeOf(@typeOf(lit_int_x)) }
926 \\extern fn entry2() -> usize { @sizeOf(@typeOf(lit_float_x)) }
927 \\extern fn entry3() -> usize { @sizeOf(@typeOf(int_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);}
796933 ,
797934 ".tmp_source.zig:1:21: error: division by zero is undefined",
798935 ".tmp_source.zig:2:25: error: division by zero is undefined",
......@@ -804,14 +941,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
804941 \\const foo = "a
805942 \\b";
806943 \\
807 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
944 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
945 \\comptime {@export("entry", entry);}
808946 , ".tmp_source.zig:1:13: error: newline not allowed in string literal");
809947
810948 cases.add("invalid comparison for function pointers",
811949 \\fn foo() {}
812950 \\const invalid = foo > foo;
813951 \\
814 \\export fn entry() -> usize { @sizeOf(@typeOf(invalid)) }
952 \\extern fn entry() -> usize { @sizeOf(@typeOf(invalid)) }
953 \\comptime {@export("entry", entry);}
815954 , ".tmp_source.zig:2:21: error: operator not allowed for type 'fn()'");
816955
817956 cases.add("generic function instance with non-constant expression",
......@@ -820,16 +959,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
820959 \\ return foo(a, b);
821960 \\}
822961 \\
823 \\export fn entry() -> usize { @sizeOf(@typeOf(test1)) }
962 \\extern fn entry() -> usize { @sizeOf(@typeOf(test1)) }
963 \\comptime {@export("entry", entry);}
824964 , ".tmp_source.zig:3:16: error: unable to evaluate constant expression");
825965
826966 cases.add("goto jumping into block",
827 \\export fn f() {
967 \\extern fn f() {
828968 \\ {
829969 \\a_label:
830970 \\ }
831971 \\ goto a_label;
832972 \\}
973 \\comptime {@export("f", f);}
833974 , ".tmp_source.zig:5:5: error: no label in scope named 'a_label'");
834975
835976 cases.add("goto jumping past a defer",
......@@ -840,20 +981,23 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
840981 \\}
841982 \\fn derp(){}
842983 \\
843 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
984 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
985 \\comptime {@export("entry", entry);}
844986 , ".tmp_source.zig:2:12: error: no label in scope named 'label'");
845987
846988 cases.add("assign null to non-nullable pointer",
847989 \\const a: &u8 = null;
848990 \\
849 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }
991 \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) }
992 \\comptime {@export("entry", entry);}
850993 , ".tmp_source.zig:1:16: error: expected type '&u8', found '(null)'");
851994
852995 cases.add("indexing an array of size zero",
853996 \\const array = []u8{};
854 \\export fn foo() {
997 \\extern fn foo() {
855998 \\ const pointer = &array[0];
856999 \\}
1000 \\comptime {@export("foo", foo);}
8571001 , ".tmp_source.zig:3:27: error: index 0 outside array of size 0");
8581002
8591003 cases.add("compile time division by zero",
......@@ -862,7 +1006,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
8621006 \\ 1 / x
8631007 \\}
8641008 \\
865 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1009 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
1010 \\comptime {@export("entry", entry);}
8661011 ,
8671012 ".tmp_source.zig:3:7: error: division by zero is undefined",
8681013 ".tmp_source.zig:1:14: note: called from here");
......@@ -870,7 +1015,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
8701015 cases.add("branch on undefined value",
8711016 \\const x = if (undefined) true else false;
8721017 \\
873 \\export fn entry() -> usize { @sizeOf(@typeOf(x)) }
1018 \\extern fn entry() -> usize { @sizeOf(@typeOf(x)) }
1019 \\comptime {@export("entry", entry);}
8741020 , ".tmp_source.zig:1:15: error: use of undefined value");
8751021
8761022
......@@ -880,7 +1026,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
8801026 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);
8811027 \\}
8821028 \\
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)) }
8841031 ,
8851032 ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches",
8861033 ".tmp_source.zig:3:21: note: called from here");
......@@ -888,7 +1035,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
8881035 cases.add("@embedFile with bogus file",
8891036 \\const resource = @embedFile("bogus.txt");
8901037 \\
891 \\export fn entry() -> usize { @sizeOf(@typeOf(resource)) }
1038 \\comptime {@export("entry", entry);}
1039 \\extern fn entry() -> usize { @sizeOf(@typeOf(resource)) }
8921040 , ".tmp_source.zig:1:29: error: unable to find '", "bogus.txt'");
8931041
8941042 cases.add("non-const expression in struct literal outside function",
......@@ -898,7 +1046,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
8981046 \\const a = Foo {.x = get_it()};
8991047 \\extern fn get_it() -> i32;
9001048 \\
901 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }
1049 \\comptime {@export("entry", entry);}
1050 \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) }
9021051 , ".tmp_source.zig:4:21: error: unable to evaluate constant expression");
9031052
9041053 cases.add("non-const expression function call with struct return value outside function",
......@@ -912,18 +1061,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
9121061 \\}
9131062 \\var global_side_effect = false;
9141063 \\
915 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }
1064 \\comptime {@export("entry", entry);}
1065 \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) }
9161066 ,
9171067 ".tmp_source.zig:6:24: error: unable to evaluate constant expression",
9181068 ".tmp_source.zig:4:17: note: called from here");
9191069
9201070 cases.add("undeclared identifier error should mark fn as impure",
921 \\export fn foo() {
1071 \\extern fn foo() {
9221072 \\ test_a_thing();
9231073 \\}
9241074 \\fn test_a_thing() {
9251075 \\ bad_fn_call();
9261076 \\}
1077 \\comptime {@export("foo", foo);}
9271078 , ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'");
9281079
9291080 cases.add("illegal comparison of types",
......@@ -938,14 +1089,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
9381089 \\ *a == *b
9391090 \\}
9401091 \\
941 \\export fn entry1() -> usize { @sizeOf(@typeOf(bad_eql_1)) }
942 \\export fn entry2() -> usize { @sizeOf(@typeOf(bad_eql_2)) }
1092 \\extern fn entry1() -> usize { @sizeOf(@typeOf(bad_eql_1)) }
1093 \\extern fn entry2() -> usize { @sizeOf(@typeOf(bad_eql_2)) }
1094 \\comptime {@export("entry1", entry1);}
1095 \\comptime {@export("entry2", entry2);}
9431096 ,
9441097 ".tmp_source.zig:2:7: error: operator not allowed for type '[]u8'",
9451098 ".tmp_source.zig:9:8: error: operator not allowed for type 'EnumWithData'");
9461099
9471100 cases.add("non-const switch number literal",
948 \\export fn foo() {
1101 \\extern fn foo() {
9491102 \\ const x = switch (bar()) {
9501103 \\ 1, 2 => 1,
9511104 \\ 3, 4 => 2,
......@@ -955,22 +1108,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
9551108 \\fn bar() -> i32 {
9561109 \\ 2
9571110 \\}
1111 \\comptime {@export("foo", foo);}
9581112 , ".tmp_source.zig:2:15: error: unable to infer expression type");
9591113
9601114 cases.add("atomic orderings of cmpxchg - failure stricter than success",
9611115 \\const AtomicOrder = @import("builtin").AtomicOrder;
962 \\export fn f() {
1116 \\extern fn f() {
9631117 \\ var x: i32 = 1234;
9641118 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}
9651119 \\}
1120 \\comptime {@export("f", f);}
9661121 , ".tmp_source.zig:4:72: error: failure atomic ordering must be no stricter than success");
9671122
9681123 cases.add("atomic orderings of cmpxchg - success Monotonic or stricter",
9691124 \\const AtomicOrder = @import("builtin").AtomicOrder;
970 \\export fn f() {
1125 \\extern fn f() {
9711126 \\ var x: i32 = 1234;
9721127 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}
9731128 \\}
1129 \\comptime {@export("f", f);}
9741130 , ".tmp_source.zig:4:49: error: success atomic ordering must be Monotonic or stricter");
9751131
9761132 cases.add("negation overflow in function evaluation",
......@@ -979,7 +1135,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
9791135 \\ -x
9801136 \\}
9811137 \\
982 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1138 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
1139 \\comptime {@export("entry", entry);}
9831140 ,
9841141 ".tmp_source.zig:3:5: error: negation caused overflow",
9851142 ".tmp_source.zig:1:14: note: called from here");
......@@ -990,7 +1147,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
9901147 \\ a + b
9911148 \\}
9921149 \\
993 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1150 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
1151 \\comptime {@export("entry", entry);}
9941152 ,
9951153 ".tmp_source.zig:3:7: error: operation caused overflow",
9961154 ".tmp_source.zig:1:14: note: called from here");
......@@ -1002,7 +1160,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10021160 \\ a - b
10031161 \\}
10041162 \\
1005 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1163 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
1164 \\comptime {@export("entry", entry);}
10061165 ,
10071166 ".tmp_source.zig:3:7: error: operation caused overflow",
10081167 ".tmp_source.zig:1:14: note: called from here");
......@@ -1013,7 +1172,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10131172 \\ a * b
10141173 \\}
10151174 \\
1016 \\export fn entry() -> usize { @sizeOf(@typeOf(y)) }
1175 \\extern fn entry() -> usize { @sizeOf(@typeOf(y)) }
1176 \\comptime {@export("entry", entry);}
10171177 ,
10181178 ".tmp_source.zig:3:7: error: operation caused overflow",
10191179 ".tmp_source.zig:1:14: note: called from here");
......@@ -1024,40 +1184,35 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10241184 \\ @truncate(i8, x)
10251185 \\}
10261186 \\
1027 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1187 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
1188 \\comptime {@export("entry", entry);}
10281189 , ".tmp_source.zig:3:19: error: expected signed integer type, found 'u32'");
10291190
10301191 cases.add("%return in function with non error return type",
1031 \\export fn f() {
1192 \\extern fn f() {
10321193 \\ %return something();
10331194 \\}
10341195 \\fn something() -> %void { }
1196 \\comptime {@export("f", f);}
10351197 ,
10361198 ".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
10471200 cases.add("invalid pointer for var type",
10481201 \\extern fn ext() -> usize;
10491202 \\var bytes: [ext()]u8 = undefined;
1050 \\export fn f() {
1203 \\extern fn f() {
10511204 \\ for (bytes) |*b, i| {
10521205 \\ *b = u8(i);
10531206 \\ }
10541207 \\}
1208 \\comptime {@export("f", f);}
10551209 , ".tmp_source.zig:2:13: error: unable to evaluate constant expression");
10561210
10571211 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{
10591213 \\ x + y
10601214 \\}
1215 \\comptime {@export("foo", foo);}
10611216 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");
10621217
10631218 cases.add("extern function with comptime parameter",
......@@ -1065,14 +1220,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10651220 \\fn f() -> i32 {
10661221 \\ foo(1, 2)
10671222 \\}
1068 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1223 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
1224 \\comptime {@export("entry", entry);}
10691225 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");
10701226
10711227 cases.add("convert fixed size array to slice with invalid size",
1072 \\export fn f() {
1228 \\extern fn f() {
10731229 \\ var array: [5]u8 = undefined;
10741230 \\ var foo = ([]const u32)(array)[0];
10751231 \\}
1232 \\comptime {@export("f", f);}
10761233 , ".tmp_source.zig:3:28: error: unable to convert [5]u8 to []const u32: size mismatch");
10771234
10781235 cases.add("non-pure function returns type",
......@@ -1090,10 +1247,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10901247 \\ }
10911248 \\}
10921249 \\
1093 \\export fn function_with_return_type_type() {
1250 \\extern fn function_with_return_type_type() {
10941251 \\ var list: List(i32) = undefined;
10951252 \\ list.length = 10;
10961253 \\}
1254 \\comptime {@export("function_with_return_type_type", function_with_return_type_type);}
10971255 , ".tmp_source.zig:3:7: error: unable to evaluate constant expression",
10981256 ".tmp_source.zig:16:19: note: called from here");
10991257
......@@ -1102,7 +1260,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11021260 \\fn f(m: []const u8) {
11031261 \\ m.copy(u8, self[0..], m);
11041262 \\}
1105 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1263 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
1264 \\comptime {@export("entry", entry);}
11061265 , ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'");
11071266
11081267 cases.add("wrong number of arguments for method fn call",
......@@ -1113,21 +1272,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11131272 \\
11141273 \\ foo.method(1, 2);
11151274 \\}
1116 \\export fn entry() -> usize { @sizeOf(@typeOf(f)) }
1275 \\extern fn entry() -> usize { @sizeOf(@typeOf(f)) }
1276 \\comptime {@export("entry", entry);}
11171277 , ".tmp_source.zig:6:15: error: expected 2 arguments, found 3");
11181278
11191279 cases.add("assign through constant pointer",
1120 \\export fn f() {
1280 \\extern fn f() {
11211281 \\ var cstr = c"Hat";
11221282 \\ cstr[0] = 'W';
11231283 \\}
1284 \\comptime {@export("f", f);}
11241285 , ".tmp_source.zig:3:11: error: cannot assign to constant");
11251286
11261287 cases.add("assign through constant slice",
1127 \\export fn f() {
1288 \\extern fn f() {
11281289 \\ var cstr: []const u8 = "Hat";
11291290 \\ cstr[0] = 'W';
11301291 \\}
1292 \\comptime {@export("f", f);}
11311293 , ".tmp_source.zig:3:11: error: cannot assign to constant");
11321294
11331295 cases.add("main function with bogus args type",
......@@ -1138,7 +1300,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11381300 \\fn foo(blah: []u8) {
11391301 \\ for (blah) { }
11401302 \\}
1141 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1303 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1304 \\comptime {@export("entry", entry);}
11421305 , ".tmp_source.zig:2:5: error: for loop expression missing element parameter");
11431306
11441307 cases.add("misspelled type with pointer only reference",
......@@ -1171,7 +1334,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11711334 \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };
11721335 \\}
11731336 \\
1174 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1337 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1338 \\comptime {@export("entry", entry);}
11751339 , ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'");
11761340
11771341 cases.add("method call with first arg type primitive",
......@@ -1185,11 +1349,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11851349 \\ }
11861350 \\};
11871351 \\
1188 \\export fn f() {
1352 \\extern fn f() {
11891353 \\ const derp = Foo.init(3);
11901354 \\
11911355 \\ derp.init();
11921356 \\}
1357 \\comptime {@export("f", f);}
11931358 , ".tmp_source.zig:14:5: error: expected type 'i32', found '&const Foo'");
11941359
11951360 cases.add("method call with first arg type wrong container",
......@@ -1213,10 +1378,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
12131378 \\ field: i32,
12141379 \\};
12151380 \\
1216 \\export fn foo() {
1381 \\extern fn foo() {
12171382 \\ var x = List.init(&global_allocator);
12181383 \\ x.init();
12191384 \\}
1385 \\comptime {@export("foo", foo);}
12201386 , ".tmp_source.zig:23:5: error: expected type '&Allocator', found '&List'");
12211387
12221388 cases.add("binary not on number literal",
......@@ -1224,16 +1390,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
12241390 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
12251391 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
12261392 \\
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);}
12281395 , ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'");
12291396
12301397 cases.addCase({
12311398 const tc = cases.create("multiple files with private function error",
12321399 \\const foo = @import("foo.zig");
12331400 \\
1234 \\export fn callPrivFunction() {
1401 \\extern fn callPrivFunction() {
12351402 \\ foo.privateFunction();
12361403 \\}
1404 \\comptime {@export("callPrivFunction", callPrivFunction);}
12371405 ,
12381406 ".tmp_source.zig:4:8: error: 'privateFunction' is private",
12391407 "foo.zig:1:1: note: declared here");
......@@ -1249,17 +1417,19 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
12491417 \\const zero: i32 = 0;
12501418 \\const a = zero{1};
12511419 \\
1252 \\export fn entry() -> usize { @sizeOf(@typeOf(a)) }
1420 \\extern fn entry() -> usize { @sizeOf(@typeOf(a)) }
1421 \\comptime {@export("entry", entry);}
12531422 , ".tmp_source.zig:2:11: error: expected type, found 'i32'");
12541423
12551424 cases.add("assign to constant field",
12561425 \\const Foo = struct {
12571426 \\ field: i32,
12581427 \\};
1259 \\export fn derp() {
1428 \\extern fn derp() {
12601429 \\ const f = Foo {.field = 1234,};
12611430 \\ f.field = 0;
12621431 \\}
1432 \\comptime {@export("derp", derp);}
12631433 , ".tmp_source.zig:6:13: error: cannot assign to constant");
12641434
12651435 cases.add("return from defer expression",
......@@ -1277,7 +1447,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
12771447 \\ return 0;
12781448 \\}
12791449 \\
1280 \\export fn entry() -> usize { @sizeOf(@typeOf(testTrickyDefer)) }
1450 \\extern fn entry() -> usize { @sizeOf(@typeOf(testTrickyDefer)) }
1451 \\comptime {@export("entry", entry);}
12811452 , ".tmp_source.zig:4:11: error: cannot return from defer expression");
12821453
12831454 cases.add("attempt to access var args out of bounds",
......@@ -1289,7 +1460,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
12891460 \\ add(i32(1234))
12901461 \\}
12911462 \\
1292 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1463 \\comptime {@export("entry", entry);}
1464 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
12931465 ,
12941466 ".tmp_source.zig:2:19: error: index 1 outside argument list of size 1",
12951467 ".tmp_source.zig:6:8: note: called from here");
......@@ -1307,27 +1479,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
13071479 \\ add(1, 2, 3, 4)
13081480 \\}
13091481 \\
1310 \\export fn entry() -> usize { @sizeOf(@typeOf(bar)) }
1482 \\comptime {@export("entry", entry);}
1483 \\extern fn entry() -> usize { @sizeOf(@typeOf(bar)) }
13111484 , ".tmp_source.zig:10:9: error: parameter of type '(integer literal)' requires comptime");
13121485
13131486 cases.add("assign too big number to u16",
1314 \\export fn foo() {
1487 \\extern fn foo() {
13151488 \\ var vga_mem: u16 = 0xB8000;
13161489 \\}
1490 \\comptime {@export("foo", foo);}
13171491 , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");
13181492
13191493 cases.add("global variable alignment non power of 2",
13201494 \\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);}
13221497 , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2");
13231498
13241499 cases.add("function alignment non power of 2",
13251500 \\extern fn foo() align(3);
1326 \\export fn entry() { foo() }
1501 \\extern fn entry() { foo() }
1502 \\comptime {@export("entry", entry);}
13271503 , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2");
13281504
13291505 cases.add("compile log",
1330 \\export fn foo() {
1506 \\extern fn foo() {
13311507 \\ comptime bar(12, "hi");
13321508 \\}
13331509 \\fn bar(a: i32, b: []const u8) {
......@@ -1335,6 +1511,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
13351511 \\ @compileLog("a", a, "b", b);
13361512 \\ @compileLog("end");
13371513 \\}
1514 \\comptime {@export("foo", foo);}
13381515 ,
13391516 ".tmp_source.zig:5:5: error: found compile log statement",
13401517 ".tmp_source.zig:2:17: note: called from here",
......@@ -1358,7 +1535,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
13581535 \\ return *x;
13591536 \\}
13601537 \\
1361 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1538 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1539 \\comptime {@export("entry", entry);}
13621540 , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align(1:3:6) const u3'");
13631541
13641542 cases.add("referring to a struct that is invalid",
......@@ -1366,19 +1544,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
13661544 \\ Type: u8,
13671545 \\};
13681546 \\
1369 \\export fn foo() {
1547 \\extern fn foo() {
13701548 \\ comptime assert(@sizeOf(UsbDeviceRequest) == 0x8);
13711549 \\}
13721550 \\
13731551 \\fn assert(ok: bool) {
13741552 \\ if (!ok) unreachable;
13751553 \\}
1554 \\comptime {@export("foo", foo);}
13761555 ,
13771556 ".tmp_source.zig:10:14: error: unable to evaluate constant expression",
13781557 ".tmp_source.zig:6:20: note: called from here");
13791558
13801559 cases.add("control flow uses comptime var at runtime",
1381 \\export fn foo() {
1560 \\extern fn foo() {
13821561 \\ comptime var i = 0;
13831562 \\ while (i < 5) : (i += 1) {
13841563 \\ bar();
......@@ -1386,53 +1565,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
13861565 \\}
13871566 \\
13881567 \\fn bar() { }
1568 \\comptime {@export("foo", foo);}
13891569 ,
13901570 ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime",
13911571 ".tmp_source.zig:3:24: note: compile-time variable assigned here");
13921572
13931573 cases.add("ignored return value",
1394 \\export fn foo() {
1574 \\extern fn foo() {
13951575 \\ bar();
13961576 \\}
13971577 \\fn bar() -> i32 { 0 }
1578 \\comptime {@export("foo", foo);}
13981579 , ".tmp_source.zig:2:8: error: expression value is ignored");
13991580
14001581 cases.add("ignored assert-err-ok return value",
1401 \\export fn foo() {
1582 \\extern fn foo() {
14021583 \\ %%bar();
14031584 \\}
14041585 \\fn bar() -> %i32 { 0 }
1586 \\comptime {@export("foo", foo);}
14051587 , ".tmp_source.zig:2:5: error: expression value is ignored");
14061588
14071589 cases.add("ignored statement value",
1408 \\export fn foo() {
1590 \\extern fn foo() {
14091591 \\ 1;
14101592 \\}
1593 \\comptime {@export("foo", foo);}
14111594 , ".tmp_source.zig:2:5: error: expression value is ignored");
14121595
14131596 cases.add("ignored comptime statement value",
1414 \\export fn foo() {
1597 \\extern fn foo() {
14151598 \\ comptime {1;}
14161599 \\}
1600 \\comptime {@export("foo", foo);}
14171601 , ".tmp_source.zig:2:15: error: expression value is ignored");
14181602
14191603 cases.add("ignored comptime value",
1420 \\export fn foo() {
1604 \\extern fn foo() {
14211605 \\ comptime 1;
14221606 \\}
1607 \\comptime {@export("foo", foo);}
14231608 , ".tmp_source.zig:2:5: error: expression value is ignored");
14241609
14251610 cases.add("ignored defered statement value",
1426 \\export fn foo() {
1611 \\extern fn foo() {
14271612 \\ defer {1;}
14281613 \\}
1614 \\comptime {@export("foo", foo);}
14291615 , ".tmp_source.zig:2:12: error: expression value is ignored");
14301616
14311617 cases.add("ignored defered statement value",
1432 \\export fn foo() {
1618 \\extern fn foo() {
14331619 \\ defer bar();
14341620 \\}
14351621 \\fn bar() -> %i32 { 0 }
1622 \\comptime {@export("foo", foo);}
14361623 , ".tmp_source.zig:2:14: error: expression value is ignored");
14371624
14381625 cases.add("dereference an array",
......@@ -1443,7 +1630,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
14431630 \\ return (*out)[0..1];
14441631 \\}
14451632 \\
1446 \\export fn entry() -> usize { @sizeOf(@typeOf(pass)) }
1633 \\extern fn entry() -> usize { @sizeOf(@typeOf(pass)) }
1634 \\comptime {@export("entry", entry);}
14471635 , ".tmp_source.zig:4:5: error: attempt to dereference non pointer type '[10]u8'");
14481636
14491637 cases.add("pass const ptr to mutable ptr fn",
......@@ -1456,46 +1644,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
14561644 \\ return true;
14571645 \\}
14581646 \\
1459 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1647 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1648 \\comptime {@export("entry", entry);}
14601649 , ".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
14811651 cases.add("pass non-copyable type by value to function",
14821652 \\const Point = struct { x: i32, y: i32, };
14831653 \\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);}
14851656 , ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value");
14861657
14871658 cases.add("implicit cast from array to mutable slice",
14881659 \\var global_array: [10]i32 = undefined;
14891660 \\fn foo(param: []i32) {}
1490 \\export fn entry() {
1661 \\extern fn entry() {
14911662 \\ foo(global_array);
14921663 \\}
1664 \\comptime {@export("entry", entry);}
14931665 , ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'");
14941666
14951667 cases.add("ptrcast to non-pointer",
1496 \\export fn entry(a: &i32) -> usize {
1668 \\extern fn entry(a: &i32) -> usize {
14971669 \\ return @ptrCast(usize, a);
14981670 \\}
1671 \\comptime {@export("entry", entry);}
14991672 , ".tmp_source.zig:2:21: error: expected pointer, found 'usize'");
15001673
15011674 cases.add("too many error values to cast to small integer",
......@@ -1504,7 +1677,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15041677 \\fn foo(e: error) -> u2 {
15051678 \\ return u2(e);
15061679 \\}
1507 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1680 \\extern fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1681 \\comptime {@export("entry", entry);}
15081682 , ".tmp_source.zig:4:14: error: too many error values to fit in 'u2'");
15091683
15101684 cases.add("asm at compile time",
......@@ -1523,41 +1697,46 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15231697
15241698 cases.add("invalid member of builtin enum",
15251699 \\const builtin = @import("builtin");
1526 \\export fn entry() {
1700 \\extern fn entry() {
15271701 \\ const foo = builtin.Arch.x86;
15281702 \\}
1703 \\comptime {@export("entry", entry);}
15291704 , ".tmp_source.zig:3:29: error: container 'Arch' has no member called 'x86'");
15301705
15311706 cases.add("int to ptr of 0 bits",
1532 \\export fn foo() {
1707 \\extern fn foo() {
15331708 \\ var x: usize = 0x1000;
15341709 \\ var y: &void = @intToPtr(&void, x);
15351710 \\}
1711 \\comptime {@export("foo", foo);}
15361712 , ".tmp_source.zig:3:31: error: type '&void' has 0 bits and cannot store information");
15371713
15381714 cases.add("@fieldParentPtr - non struct",
15391715 \\const Foo = i32;
1540 \\export fn foo(a: &i32) -> &Foo {
1716 \\extern fn foo(a: &i32) -> &Foo {
15411717 \\ return @fieldParentPtr(Foo, "a", a);
15421718 \\}
1719 \\comptime {@export("foo", foo);}
15431720 , ".tmp_source.zig:3:28: error: expected struct type, found 'i32'");
15441721
15451722 cases.add("@fieldParentPtr - bad field name",
15461723 \\const Foo = struct {
15471724 \\ derp: i32,
15481725 \\};
1549 \\export fn foo(a: &i32) -> &Foo {
1726 \\extern fn foo(a: &i32) -> &Foo {
15501727 \\ return @fieldParentPtr(Foo, "a", a);
15511728 \\}
1729 \\comptime {@export("foo", foo);}
15521730 , ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'");
15531731
15541732 cases.add("@fieldParentPtr - field pointer is not pointer",
15551733 \\const Foo = struct {
15561734 \\ a: i32,
15571735 \\};
1558 \\export fn foo(a: i32) -> &Foo {
1736 \\extern fn foo(a: i32) -> &Foo {
15591737 \\ return @fieldParentPtr(Foo, "a", a);
15601738 \\}
1739 \\comptime {@export("foo", foo);}
15611740 , ".tmp_source.zig:5:38: error: expected pointer, found 'i32'");
15621741
15631742 cases.add("@fieldParentPtr - comptime field ptr not based on struct",
......@@ -1587,18 +1766,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15871766
15881767 cases.add("@offsetOf - non struct",
15891768 \\const Foo = i32;
1590 \\export fn foo() -> usize {
1769 \\extern fn foo() -> usize {
15911770 \\ return @offsetOf(Foo, "a");
15921771 \\}
1772 \\comptime {@export("foo", foo);}
15931773 , ".tmp_source.zig:3:22: error: expected struct type, found 'i32'");
15941774
15951775 cases.add("@offsetOf - bad field name",
15961776 \\const Foo = struct {
15971777 \\ derp: i32,
15981778 \\};
1599 \\export fn foo() -> usize {
1779 \\extern fn foo() -> usize {
16001780 \\ return @offsetOf(Foo, "a");
16011781 \\}
1782 \\comptime {@export("foo", foo);}
16021783 , ".tmp_source.zig:5:27: error: struct 'Foo' has no field 'a'");
16031784
16041785 cases.addExe("missing main fn in executable",
......@@ -1611,38 +1792,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16111792 "error: 'main' is private",
16121793 ".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
16321795 cases.add("returning address of local variable - simple",
1633 \\export fn foo() -> &i32 {
1796 \\extern fn foo() -> &i32 {
16341797 \\ var a: i32 = undefined;
16351798 \\ return &a;
16361799 \\}
1800 \\comptime {@export("foo", foo);}
16371801 ,
16381802 ".tmp_source.zig:3:13: error: function returns address of local variable");
16391803
16401804 cases.add("returning address of local variable - phi",
1641 \\export fn foo(c: bool) -> &i32 {
1805 \\extern fn foo(c: bool) -> &i32 {
16421806 \\ var a: i32 = undefined;
16431807 \\ var b: i32 = undefined;
16441808 \\ return if (c) &a else &b;
16451809 \\}
1810 \\comptime {@export("foo", foo);}
16461811 ,
16471812 ".tmp_source.zig:4:12: error: function returns address of local variable");
16481813
......@@ -1671,55 +1836,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16711836 ".tmp_source.zig:5:9: note: previous definition is here");
16721837
16731838 cases.add("while expected bool, got nullable",
1674 \\export fn foo() {
1839 \\extern fn foo() {
16751840 \\ while (bar()) {}
16761841 \\}
16771842 \\fn bar() -> ?i32 { 1 }
1843 \\comptime {@export("foo", foo);}
16781844 ,
16791845 ".tmp_source.zig:2:15: error: expected type 'bool', found '?i32'");
16801846
16811847 cases.add("while expected bool, got error union",
1682 \\export fn foo() {
1848 \\extern fn foo() {
16831849 \\ while (bar()) {}
16841850 \\}
16851851 \\fn bar() -> %i32 { 1 }
1852 \\comptime {@export("foo", foo);}
16861853 ,
16871854 ".tmp_source.zig:2:15: error: expected type 'bool', found '%i32'");
16881855
16891856 cases.add("while expected nullable, got bool",
1690 \\export fn foo() {
1857 \\extern fn foo() {
16911858 \\ while (bar()) |x| {}
16921859 \\}
16931860 \\fn bar() -> bool { true }
1861 \\comptime {@export("foo", foo);}
16941862 ,
16951863 ".tmp_source.zig:2:15: error: expected nullable type, found 'bool'");
16961864
16971865 cases.add("while expected nullable, got error union",
1698 \\export fn foo() {
1866 \\extern fn foo() {
16991867 \\ while (bar()) |x| {}
17001868 \\}
17011869 \\fn bar() -> %i32 { 1 }
1870 \\comptime {@export("foo", foo);}
17021871 ,
17031872 ".tmp_source.zig:2:15: error: expected nullable type, found '%i32'");
17041873
17051874 cases.add("while expected error union, got bool",
1706 \\export fn foo() {
1875 \\extern fn foo() {
17071876 \\ while (bar()) |x| {} else |err| {}
17081877 \\}
17091878 \\fn bar() -> bool { true }
1879 \\comptime {@export("foo", foo);}
17101880 ,
17111881 ".tmp_source.zig:2:15: error: expected error union type, found 'bool'");
17121882
17131883 cases.add("while expected error union, got nullable",
1714 \\export fn foo() {
1884 \\extern fn foo() {
17151885 \\ while (bar()) |x| {} else |err| {}
17161886 \\}
17171887 \\fn bar() -> ?i32 { 1 }
1888 \\comptime {@export("foo", foo);}
17181889 ,
17191890 ".tmp_source.zig:2:15: error: expected error union type, found '?i32'");
17201891
17211892 cases.add("inline fn calls itself indirectly",
1722 \\export fn foo() {
1893 \\extern fn foo() {
17231894 \\ bar();
17241895 \\}
17251896 \\inline fn bar() {
......@@ -1731,29 +1902,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
17311902 \\ quux();
17321903 \\}
17331904 \\extern fn quux();
1905 \\comptime {@export("foo", foo);}
17341906 ,
17351907 ".tmp_source.zig:4:8: error: unable to inline function");
17361908
17371909 cases.add("save reference to inline function",
1738 \\export fn foo() {
1910 \\extern fn foo() {
17391911 \\ quux(@ptrToInt(bar));
17401912 \\}
17411913 \\inline fn bar() { }
17421914 \\extern fn quux(usize);
1915 \\comptime {@export("foo", foo);}
17431916 ,
17441917 ".tmp_source.zig:4:8: error: unable to inline function");
17451918
17461919 cases.add("signed integer division",
1747 \\export fn foo(a: i32, b: i32) -> i32 {
1920 \\extern fn foo(a: i32, b: i32) -> i32 {
17481921 \\ a / b
17491922 \\}
1923 \\comptime {@export("foo", foo);}
17501924 ,
17511925 ".tmp_source.zig:2:7: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact");
17521926
17531927 cases.add("signed integer remainder division",
1754 \\export fn foo(a: i32, b: i32) -> i32 {
1928 \\extern fn foo(a: i32, b: i32) -> i32 {
17551929 \\ a % b
17561930 \\}
1931 \\comptime {@export("foo", foo);}
17571932 ,
17581933 ".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) {
17921967 ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits");
17931968
17941969 cases.add("@setDebugSafety twice for same scope",
1795 \\export fn foo() {
1970 \\extern fn foo() {
17961971 \\ @setDebugSafety(this, false);
17971972 \\ @setDebugSafety(this, false);
17981973 \\}
1974 \\comptime {@export("foo", foo);}
17991975 ,
18001976 ".tmp_source.zig:3:5: error: debug safety set twice for same scope",
18011977 ".tmp_source.zig:2:5: note: first set here");
18021978
18031979 cases.add("@setFloatMode twice for same scope",
1804 \\export fn foo() {
1980 \\extern fn foo() {
18051981 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
18061982 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
18071983 \\}
1984 \\comptime {@export("foo", foo);}
18081985 ,
18091986 ".tmp_source.zig:3:5: error: float mode set twice for same scope",
18101987 ".tmp_source.zig:2:5: note: first set here");
18111988
18121989 cases.add("array access of type",
1813 \\export fn foo() {
1990 \\extern fn foo() {
18141991 \\ var b: u8[40] = undefined;
18151992 \\}
1993 \\comptime {@export("foo", foo);}
18161994 ,
18171995 ".tmp_source.zig:2:14: error: array access of non-array type 'type'");
18181996
18191997 cases.add("cannot break out of defer expression",
1820 \\export fn foo() {
1998 \\extern fn foo() {
18211999 \\ while (true) {
18222000 \\ defer {
18232001 \\ break;
18242002 \\ }
18252003 \\ }
18262004 \\}
2005 \\comptime {@export("foo", foo);}
18272006 ,
18282007 ".tmp_source.zig:4:13: error: cannot break out of defer expression");
18292008
18302009 cases.add("cannot continue out of defer expression",
1831 \\export fn foo() {
2010 \\extern fn foo() {
18322011 \\ while (true) {
18332012 \\ defer {
18342013 \\ continue;
18352014 \\ }
18362015 \\ }
18372016 \\}
2017 \\comptime {@export("foo", foo);}
18382018 ,
18392019 ".tmp_source.zig:4:13: error: cannot continue out of defer expression");
18402020
18412021 cases.add("cannot goto out of defer expression",
1842 \\export fn foo() {
2022 \\extern fn foo() {
18432023 \\ defer {
18442024 \\ goto label;
18452025 \\ };
18462026 \\label:
18472027 \\}
2028 \\comptime {@export("foo", foo);}
18482029 ,
18492030 ".tmp_source.zig:3:9: error: cannot goto out of defer expression");
18502031
......@@ -1878,9 +2059,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
18782059 \\const bar = baz + foo;
18792060 \\const baz = 1;
18802061 \\
1881 \\export fn entry() -> i32 {
2062 \\extern fn entry() -> i32 {
18822063 \\ return bar;
18832064 \\}
2065 \\comptime {@export("entry", entry);}
18842066 ,
18852067 ".tmp_source.zig:1:13: error: aoeu",
18862068 ".tmp_source.zig:3:19: note: referenced here",
......@@ -1893,9 +2075,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
18932075 \\
18942076 \\var foo: Foo = undefined;
18952077 \\
1896 \\export fn entry() -> usize {
2078 \\extern fn entry() -> usize {
18972079 \\ return @sizeOf(@typeOf(foo.x));
18982080 \\}
2081 \\comptime {@export("entry", entry);}
18992082 ,
19002083 ".tmp_source.zig:1:13: error: struct 'Foo' contains itself");
19012084
......@@ -1914,16 +2097,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19142097 ".tmp_source.zig:2:15: error: float literal out of range of any type");
19152098
19162099 cases.add("explicit cast float literal to integer when there is a fraction component",
1917 \\export fn entry() -> i32 {
2100 \\extern fn entry() -> i32 {
19182101 \\ i32(12.34)
19192102 \\}
2103 \\comptime {@export("entry", entry);}
19202104 ,
19212105 ".tmp_source.zig:2:9: error: fractional component prevents float value 12.340000 from being casted to type 'i32'");
19222106
19232107 cases.add("non pointer given to @ptrToInt",
1924 \\export fn entry(x: i32) -> usize {
2108 \\extern fn entry(x: i32) -> usize {
19252109 \\ @ptrToInt(x)
19262110 \\}
2111 \\comptime {@export("entry", entry);}
19272112 ,
19282113 ".tmp_source.zig:2:15: error: expected pointer, found 'i32'");
19292114
......@@ -1942,24 +2127,27 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19422127 ".tmp_source.zig:2:15: error: exact shift shifted out 1 bits");
19432128
19442129 cases.add("shifting without int type or comptime known",
1945 \\export fn entry(x: u8) -> u8 {
2130 \\extern fn entry(x: u8) -> u8 {
19462131 \\ return 0x11 << x;
19472132 \\}
2133 \\comptime {@export("entry", entry);}
19482134 ,
19492135 ".tmp_source.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known");
19502136
19512137 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 {
19532139 \\ return x << y;
19542140 \\}
2141 \\comptime {@export("entry", entry);}
19552142 ,
19562143 ".tmp_source.zig:2:17: error: expected type 'u3', found 'u8'");
19572144
19582145 cases.add("globally shadowing a primitive type",
19592146 \\const u16 = @intType(false, 8);
1960 \\export fn entry() {
2147 \\extern fn entry() {
19612148 \\ const a: u16 = 300;
19622149 \\}
2150 \\comptime {@export("entry", entry);}
19632151 ,
19642152 ".tmp_source.zig:1:1: error: declaration shadows type 'u16'");
19652153
......@@ -1969,7 +2157,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19692157 \\ b: u32,
19702158 \\};
19712159 \\
1972 \\export fn entry() {
2160 \\extern fn entry() {
19732161 \\ var foo = Foo { .a = 1, .b = 10 };
19742162 \\ bar(&foo.b);
19752163 \\}
......@@ -1977,6 +2165,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19772165 \\fn bar(x: &u32) {
19782166 \\ *x += 1;
19792167 \\}
2168 \\comptime {@export("entry", entry);}
19802169 ,
19812170 ".tmp_source.zig:8:13: error: expected type '&u32', found '&align(1) u32'");
19822171
......@@ -1986,7 +2175,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19862175 \\ b: u32,
19872176 \\};
19882177 \\
1989 \\export fn entry() {
2178 \\extern fn entry() {
19902179 \\ var foo = Foo { .a = 1, .b = 10 };
19912180 \\ foo.b += 1;
19922181 \\ bar((&foo.b)[0..1]);
......@@ -1995,55 +2184,61 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19952184 \\fn bar(x: []u32) {
19962185 \\ x[0] += 1;
19972186 \\}
2187 \\comptime {@export("entry", entry);}
19982188 ,
19992189 ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'");
20002190
20012191 cases.add("increase pointer alignment in @ptrCast",
2002 \\export fn entry() -> u32 {
2192 \\extern fn entry() -> u32 {
20032193 \\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04};
20042194 \\ const ptr = @ptrCast(&u32, &bytes[0]);
20052195 \\ return *ptr;
20062196 \\}
2197 \\comptime {@export("entry", entry);}
20072198 ,
20082199 ".tmp_source.zig:3:17: error: cast increases pointer alignment",
20092200 ".tmp_source.zig:3:38: note: '&u8' has alignment 1",
20102201 ".tmp_source.zig:3:27: note: '&u32' has alignment 4");
20112202
20122203 cases.add("increase pointer alignment in slice resize",
2013 \\export fn entry() -> u32 {
2204 \\extern fn entry() -> u32 {
20142205 \\ var bytes = []u8{0x01, 0x02, 0x03, 0x04};
20152206 \\ return ([]u32)(bytes[0..])[0];
20162207 \\}
2208 \\comptime {@export("entry", entry);}
20172209 ,
20182210 ".tmp_source.zig:3:19: error: cast increases pointer alignment",
20192211 ".tmp_source.zig:3:19: note: '[]u8' has alignment 1",
20202212 ".tmp_source.zig:3:19: note: '[]u32' has alignment 4");
20212213
20222214 cases.add("@alignCast expects pointer or slice",
2023 \\export fn entry() {
2215 \\extern fn entry() {
20242216 \\ @alignCast(4, u32(3))
20252217 \\}
2218 \\comptime {@export("entry", entry);}
20262219 ,
20272220 ".tmp_source.zig:2:22: error: expected pointer or slice, found 'u32'");
20282221
20292222 cases.add("passing an under-aligned function pointer",
2030 \\export fn entry() {
2223 \\extern fn entry() {
20312224 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
20322225 \\}
20332226 \\fn testImplicitlyDecreaseFnAlign(ptr: fn () align(8) -> i32, answer: i32) {
20342227 \\ if (ptr() != answer) unreachable;
20352228 \\}
20362229 \\fn alignedSmall() align(4) -> i32 { 1234 }
2230 \\comptime {@export("entry", entry);}
20372231 ,
20382232 ".tmp_source.zig:2:35: error: expected type 'fn() align(8) -> i32', found 'fn() align(4) -> i32'");
20392233
20402234 cases.add("passing a not-aligned-enough pointer to cmpxchg",
20412235 \\const AtomicOrder = @import("builtin").AtomicOrder;
2042 \\export fn entry() -> bool {
2236 \\extern fn entry() -> bool {
20432237 \\ var x: i32 align(1) = 1234;
20442238 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
20452239 \\ return x == 5678;
20462240 \\}
2241 \\comptime {@export("entry", entry);}
20472242 ,
20482243 ".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) {
20692264 cases.add("wrong pointer implicitly casted to pointer to @OpaqueType()",
20702265 \\const Derp = @OpaqueType();
20712266 \\extern fn bar(d: &Derp);
2072 \\export fn foo() {
2267 \\extern fn foo() {
20732268 \\ const x = u8(1);
20742269 \\ bar(@ptrCast(&c_void, &x));
20752270 \\}
2271 \\comptime {@export("foo", foo);}
20762272 ,
20772273 ".tmp_source.zig:5:9: error: expected type '&Derp', found '&c_void'");
20782274
20792275 cases.add("non-const variables of things that require const variables",
20802276 \\const Opaque = @OpaqueType();
20812277 \\
2082 \\export fn entry(opaque: &Opaque) {
2278 \\extern fn entry(opaque: &Opaque) {
20832279 \\ var m2 = &2;
20842280 \\ const y: u32 = *m2;
20852281 \\
......@@ -2099,6 +2295,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
20992295 \\const Foo = struct {
21002296 \\ fn bar(self: &const Foo) {}
21012297 \\};
2298 \\comptime {@export("entry", entry);}
21022299 ,
21032300 ".tmp_source.zig:4:4: error: variable of type '&const (integer literal)' must be const or comptime",
21042301 ".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) {
21132310 ".tmp_source.zig:17:4: error: unreachable code");
21142311
21152312 cases.add("wrong types given to atomic order args in cmpxchg",
2116 \\export fn entry() {
2313 \\extern fn entry() {
21172314 \\ var x: i32 = 1234;
21182315 \\ while (!@cmpxchg(&x, 1234, 5678, u32(1234), u32(1234))) {}
21192316 \\}
2317 \\comptime {@export("entry", entry);}
21202318 ,
21212319 ".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
21302321 cases.add("struct with invalid field",
21312322 \\const std = @import("std");
21322323 \\const Allocator = std.mem.Allocator;
......@@ -2145,12 +2336,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
21452336 \\ },
21462337 \\};
21472338 \\
2148 \\export fn entry() {
2339 \\extern fn entry() {
21492340 \\ const a = MdNode.Header {
21502341 \\ .text = MdText.init(&std.debug.global_allocator),
21512342 \\ .weight = HeaderWeight.H1,
21522343 \\ };
21532344 \\}
2345 \\comptime {@export("entry", entry);}
21542346 ,
21552347 ".tmp_source.zig:14:17: error: use of undeclared identifier 'HeaderValue'");
21562348
......@@ -2162,35 +2354,39 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
21622354 ".tmp_source.zig:2:5: error: @setAlignStack outside function");
21632355
21642356 cases.add("@setAlignStack in naked function",
2165 \\export nakedcc fn entry() {
2357 \\nakedcc fn entry() {
21662358 \\ @setAlignStack(16);
21672359 \\}
2360 \\comptime {@export("entry", entry);}
21682361 ,
21692362 ".tmp_source.zig:2:5: error: @setAlignStack in naked function");
21702363
21712364 cases.add("@setAlignStack in inline function",
2172 \\export fn entry() {
2365 \\extern fn entry() {
21732366 \\ foo();
21742367 \\}
21752368 \\inline fn foo() {
21762369 \\ @setAlignStack(16);
21772370 \\}
2371 \\comptime {@export("entry", entry);}
21782372 ,
21792373 ".tmp_source.zig:5:5: error: @setAlignStack in inline function");
21802374
21812375 cases.add("@setAlignStack set twice",
2182 \\export fn entry() {
2376 \\extern fn entry() {
21832377 \\ @setAlignStack(16);
21842378 \\ @setAlignStack(16);
21852379 \\}
2380 \\comptime {@export("entry", entry);}
21862381 ,
21872382 ".tmp_source.zig:3:5: error: alignstack set twice",
21882383 ".tmp_source.zig:2:5: note: first set here");
21892384
21902385 cases.add("@setAlignStack too big",
2191 \\export fn entry() {
2386 \\extern fn entry() {
21922387 \\ @setAlignStack(511 + 1);
21932388 \\}
2389 \\comptime {@export("entry", entry);}
21942390 ,
21952391 ".tmp_source.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256");
21962392
......@@ -2221,7 +2417,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
22212417 \\ LinkLibC,
22222418 \\};
22232419 \\
2224 \\export fn entry() {
2420 \\extern fn entry() {
22252421 \\ const tests = []TestCase {
22262422 \\ Free("001"),
22272423 \\ Free("002"),
......@@ -2236,13 +2432,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
22362432 \\ }
22372433 \\ }
22382434 \\}
2435 \\comptime {@export("entry", entry);}
22392436 ,
22402437 ".tmp_source.zig:37:16: error: cannot store runtime value in compile time variable");
22412438
22422439 cases.add("field access of opaque type",
22432440 \\const MyType = @OpaqueType();
22442441 \\
2245 \\export fn entry() -> bool {
2442 \\extern fn entry() -> bool {
22462443 \\ var x: i32 = 1;
22472444 \\ return bar(@ptrCast(&MyType, &x));
22482445 \\}
......@@ -2250,6 +2447,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
22502447 \\fn bar(x: &MyType) -> bool {
22512448 \\ return x.blah;
22522449 \\}
2450 \\comptime {@export("entry", entry);}
22532451 ,
22542452 ".tmp_source.zig:9:13: error: type '&MyType' does not support field access");
22552453
......@@ -2353,10 +2551,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
23532551 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");
23542552
23552553 cases.add("calling var args extern function, passing array instead of pointer",
2356 \\export fn entry() {
2554 \\extern fn entry() {
23572555 \\ foo("hello");
23582556 \\}
23592557 \\pub extern fn foo(format: &const u8, ...);
2558 \\comptime {@export("entry", entry);}
23602559 ,
23612560 ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");
23622561
......@@ -2371,9 +2570,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
23712570 \\ }
23722571 \\}
23732572 \\
2374 \\export fn entry() {
2573 \\extern fn entry() {
23752574 \\ var allocator: ContextAllocator = undefined;
23762575 \\}
2576 \\comptime {@export("entry", entry);}
23772577 ,
23782578 ".tmp_source.zig:4:25: error: aoeu",
23792579 ".tmp_source.zig:1:36: note: called from here",
......@@ -2388,9 +2588,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
23882588 \\ Five,
23892589 \\};
23902590 \\
2391 \\export fn entry() {
2591 \\extern fn entry() {
23922592 \\ var x = Small.One;
23932593 \\}
2594 \\comptime {@export("entry", entry);}
23942595 ,
23952596 ".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) {
24012602 \\ Three,
24022603 \\};
24032604 \\
2404 \\export fn entry() {
2605 \\extern fn entry() {
24052606 \\ var x = Small.One;
24062607 \\}
2608 \\comptime {@export("entry", entry);}
24072609 ,
24082610 ".tmp_source.zig:1:20: error: expected integer, found 'f32'");
24092611
......@@ -2415,9 +2617,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24152617 \\ Four,
24162618 \\};
24172619 \\
2418 \\export fn entry() {
2620 \\extern fn entry() {
24192621 \\ var x: u2 = Small.Two;
24202622 \\}
2623 \\comptime {@export("entry", entry);}
24212624 ,
24222625 ".tmp_source.zig:9:22: error: expected type 'u2', found 'Small'");
24232626
......@@ -2429,9 +2632,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24292632 \\ Four,
24302633 \\};
24312634 \\
2432 \\export fn entry() {
2635 \\extern fn entry() {
24332636 \\ var x = u3(Small.Two);
24342637 \\}
2638 \\comptime {@export("entry", entry);}
24352639 ,
24362640 ".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) {
24432647 \\ Four,
24442648 \\};
24452649 \\
2446 \\export fn entry() {
2650 \\extern fn entry() {
24472651 \\ var y = u3(3);
24482652 \\ var x = Small(y);
24492653 \\}
2654 \\comptime {@export("entry", entry);}
24502655 ,
24512656 ".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) {
24582663 \\ Four,
24592664 \\};
24602665 \\
2461 \\export fn entry() {
2666 \\extern fn entry() {
24622667 \\ var y = Small.Two;
24632668 \\}
2669 \\comptime {@export("entry", entry);}
24642670 ,
24652671 ".tmp_source.zig:1:19: error: expected unsigned integer, found 'i2'");
24662672
......@@ -2468,9 +2674,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24682674 \\const MultipleChoice = struct {
24692675 \\ A: i32 = 20,
24702676 \\};
2471 \\export fn entry() {
2677 \\extern fn entry() {
24722678 \\ var x: MultipleChoice = undefined;
24732679 \\}
2680 \\comptime {@export("entry", entry);}
24742681 ,
24752682 ".tmp_source.zig:2:14: error: enums, not structs, support field assignment");
24762683
......@@ -2478,26 +2685,29 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24782685 \\const MultipleChoice = union {
24792686 \\ A: i32 = 20,
24802687 \\};
2481 \\export fn entry() {
2688 \\extern fn entry() {
24822689 \\ var x: MultipleChoice = undefined;
24832690 \\}
2691 \\comptime {@export("entry", entry);}
24842692 ,
24852693 ".tmp_source.zig:2:14: error: non-enum union field assignment",
24862694 ".tmp_source.zig:1:24: note: consider 'union(enum)' here");
24872695
24882696 cases.add("enum with 0 fields",
24892697 \\const Foo = enum {};
2490 \\export fn entry() -> usize {
2698 \\extern fn entry() -> usize {
24912699 \\ return @sizeOf(Foo);
24922700 \\}
2701 \\comptime {@export("entry", entry);}
24932702 ,
24942703 ".tmp_source.zig:1:13: error: enums must have 1 or more fields");
24952704
24962705 cases.add("union with 0 fields",
24972706 \\const Foo = union {};
2498 \\export fn entry() -> usize {
2707 \\extern fn entry() -> usize {
24992708 \\ return @sizeOf(Foo);
25002709 \\}
2710 \\comptime {@export("entry", entry);}
25012711 ,
25022712 ".tmp_source.zig:1:13: error: unions must have 1 or more fields");
25032713
......@@ -2509,9 +2719,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25092719 \\ D = 1000,
25102720 \\ E = 60,
25112721 \\};
2512 \\export fn entry() {
2722 \\extern fn entry() {
25132723 \\ var x = MultipleChoice.C;
25142724 \\}
2725 \\comptime {@export("entry", entry);}
25152726 ,
25162727 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",
25172728 ".tmp_source.zig:4:9: note: other occurrence here");
......@@ -2526,9 +2737,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25262737 \\ A: i32,
25272738 \\ B: f64,
25282739 \\};
2529 \\export fn entry() -> usize {
2740 \\extern fn entry() -> usize {
25302741 \\ return @sizeOf(Payload);
25312742 \\}
2743 \\comptime {@export("entry", entry);}
25322744 ,
25332745 ".tmp_source.zig:6:17: error: enum field missing: 'C'",
25342746 ".tmp_source.zig:4:5: note: declared here");
......@@ -2537,9 +2749,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25372749 \\const Foo = union {
25382750 \\ A: i32,
25392751 \\};
2540 \\export fn entry() {
2752 \\extern fn entry() {
25412753 \\ const x = @TagType(Foo);
25422754 \\}
2755 \\comptime {@export("entry", entry);}
25432756 ,
25442757 ".tmp_source.zig:5:24: error: union 'Foo' has no tag",
25452758 ".tmp_source.zig:1:13: note: consider 'union(enum)' here");
......@@ -2548,9 +2761,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25482761 \\const Foo = union(enum(f32)) {
25492762 \\ A: i32,
25502763 \\};
2551 \\export fn entry() {
2764 \\extern fn entry() {
25522765 \\ const x = @TagType(Foo);
25532766 \\}
2767 \\comptime {@export("entry", entry);}
25542768 ,
25552769 ".tmp_source.zig:1:23: error: expected integer tag type, found 'f32'");
25562770
......@@ -2558,9 +2772,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25582772 \\const Foo = union(u32) {
25592773 \\ A: i32,
25602774 \\};
2561 \\export fn entry() {
2775 \\extern fn entry() {
25622776 \\ const x = @TagType(Foo);
25632777 \\}
2778 \\comptime {@export("entry", entry);}
25642779 ,
25652780 ".tmp_source.zig:1:18: error: expected enum tag type, found 'u32'");
25662781
......@@ -2572,9 +2787,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25722787 \\ D = 1000,
25732788 \\ E = 60,
25742789 \\};
2575 \\export fn entry() {
2790 \\extern fn entry() {
25762791 \\ var x = MultipleChoice { .C = {} };
25772792 \\}
2793 \\comptime {@export("entry", entry);}
25782794 ,
25792795 ".tmp_source.zig:6:9: error: enum tag value 60 already taken",
25802796 ".tmp_source.zig:4:9: note: other occurrence here");
......@@ -2591,9 +2807,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25912807 \\ C: bool,
25922808 \\ D: bool,
25932809 \\};
2594 \\export fn entry() {
2810 \\extern fn entry() {
25952811 \\ var a = Payload {.A = 1234};
25962812 \\}
2813 \\comptime {@export("entry", entry);}
25972814 ,
25982815 ".tmp_source.zig:10:5: error: enum field not found: 'D'",
25992816 ".tmp_source.zig:1:16: note: enum declared here");
......@@ -2604,9 +2821,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26042821 \\ B,
26052822 \\ C,
26062823 \\};
2607 \\export fn entry() {
2824 \\extern fn entry() {
26082825 \\ var b = Letter.B;
26092826 \\}
2827 \\comptime {@export("entry", entry);}
26102828 ,
26112829 ".tmp_source.zig:2:8: error: structs and unions, not enums, support field types",
26122830 ".tmp_source.zig:1:16: note: consider 'union(enum)' here");
......@@ -2615,9 +2833,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26152833 \\const Letter = struct {
26162834 \\ A,
26172835 \\};
2618 \\export fn entry() {
2836 \\extern fn entry() {
26192837 \\ var a = Letter { .A = {} };
26202838 \\}
2839 \\comptime {@export("entry", entry);}
26212840 ,
26222841 ".tmp_source.zig:2:5: error: struct field missing type");
26232842
......@@ -2625,9 +2844,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26252844 \\const Letter = extern union {
26262845 \\ A,
26272846 \\};
2628 \\export fn entry() {
2847 \\extern fn entry() {
26292848 \\ var a = Letter { .A = {} };
26302849 \\}
2850 \\comptime {@export("entry", entry);}
26312851 ,
26322852 ".tmp_source.zig:2:5: error: union field missing type");
26332853
......@@ -2642,9 +2862,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26422862 \\ B: f64,
26432863 \\ C: bool,
26442864 \\};
2645 \\export fn entry() {
2865 \\extern fn entry() {
26462866 \\ var a = Payload { .A = { 1234 } };
26472867 \\}
2868 \\comptime {@export("entry", entry);}
26482869 ,
26492870 ".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) {
26592880 \\ B: f64,
26602881 \\ C: bool,
26612882 \\};
2662 \\export fn entry() {
2883 \\extern fn entry() {
26632884 \\ var a = Payload { .A = { 1234 } };
26642885 \\}
2886 \\comptime {@export("entry", entry);}
26652887 ,
26662888 ".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) {
26712893 \\ B: f64,
26722894 \\ C: bool,
26732895 \\};
2674 \\export fn entry() {
2896 \\extern fn entry() {
26752897 \\ const a = Payload { .A = { 1234 } };
26762898 \\ foo(a);
26772899 \\}
......@@ -2681,6 +2903,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26812903 \\ else => unreachable,
26822904 \\ }
26832905 \\}
2906 \\comptime {@export("entry", entry);}
26842907 ,
26852908 ".tmp_source.zig:11:13: error: switch on union which has no attached enum",
26862909 ".tmp_source.zig:1:17: note: consider 'union(enum)' here");
......@@ -2690,9 +2913,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26902913 \\ A = 10,
26912914 \\ B = 11,
26922915 \\};
2693 \\export fn entry() {
2916 \\extern fn entry() {
26942917 \\ var x = Foo(0);
26952918 \\}
2919 \\comptime {@export("entry", entry);}
26962920 ,
26972921 ".tmp_source.zig:6:16: error: enum 'Foo' has no tag matching integer value 0",
26982922 ".tmp_source.zig:1:13: note: 'Foo' declared here");
......@@ -2704,9 +2928,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
27042928 \\ B,
27052929 \\ C,
27062930 \\};
2707 \\export fn entry() {
2931 \\extern fn entry() {
27082932 \\ var x: Value = Letter.A;
27092933 \\}
2934 \\comptime {@export("entry", entry);}
27102935 ,
27112936 ".tmp_source.zig:8:26: error: cast to union 'Value' must initialize 'i32' field 'A'",
27122937 ".tmp_source.zig:3:5: note: field 'A' declared here");
......@@ -2718,13 +2943,36 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
27182943 \\ B,
27192944 \\ C,
27202945 \\};
2721 \\export fn entry() {
2946 \\extern fn entry() {
27222947 \\ foo(Letter.A);
27232948 \\}
27242949 \\fn foo(l: Letter) {
27252950 \\ var x: Value = l;
27262951 \\}
2952 \\comptime {@export("entry", entry);}
27272953 ,
27282954 ".tmp_source.zig:11:20: error: runtime cast to union 'Value' which has non-void fields",
27292955 ".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
27302978}
test/standalone/issue_339/test.zig+4-1
......@@ -2,6 +2,9 @@ pub fn panic(msg: []const u8) -> noreturn { @breakpoint(); while (true) {} }
22
33fn bar() -> %void {}
44
5export fn foo() {
5comptime {
6 @export("foo", foo);
7}
8extern fn foo() {
69 %%bar();
710}
test/translate_c.zig+32-32
......@@ -26,7 +26,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
2626 \\ return a < 0 ? -a : a;
2727 \\}
2828 ,
29 \\export fn abs(a: c_int) -> c_int {
29 \\pub fn abs(a: c_int) -> c_int {
3030 \\ return if (a < 0) -a else a;
3131 \\}
3232 );
......@@ -325,12 +325,12 @@ pub fn addCases(cases: &tests.TranslateCContext) {
325325 \\ return a;
326326 \\}
327327 ,
328 \\export fn foo1(_arg_a: c_uint) -> c_uint {
328 \\pub fn foo1(_arg_a: c_uint) -> c_uint {
329329 \\ var a = _arg_a;
330330 \\ a +%= 1;
331331 \\ return a;
332332 \\}
333 \\export fn foo2(_arg_a: c_int) -> c_int {
333 \\pub fn foo2(_arg_a: c_int) -> c_int {
334334 \\ var a = _arg_a;
335335 \\ a += 1;
336336 \\ return a;
......@@ -346,7 +346,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
346346 \\ return i;
347347 \\}
348348 ,
349 \\export fn log2(_arg_a: c_uint) -> c_int {
349 \\pub fn log2(_arg_a: c_uint) -> c_int {
350350 \\ var a = _arg_a;
351351 \\ var i: c_int = 0;
352352 \\ while (a > c_uint(0)) {
......@@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
367367 \\ return a;
368368 \\}
369369 ,
370 \\export fn max(a: c_int, b: c_int) -> c_int {
370 \\pub fn max(a: c_int, b: c_int) -> c_int {
371371 \\ if (a < b) return b;
372372 \\ if (a < b) return b else return a;
373373 \\}
......@@ -382,7 +382,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
382382 \\ return a;
383383 \\}
384384 ,
385 \\export fn max(a: c_int, b: c_int) -> c_int {
385 \\pub fn max(a: c_int, b: c_int) -> c_int {
386386 \\ if (a == b) return a;
387387 \\ if (a != b) return b;
388388 \\ return a;
......@@ -407,7 +407,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
407407 \\ c = a % b;
408408 \\}
409409 ,
410 \\export fn s(a: c_int, b: c_int) -> c_int {
410 \\pub fn s(a: c_int, b: c_int) -> c_int {
411411 \\ var c: c_int;
412412 \\ c = (a + b);
413413 \\ c = (a - b);
......@@ -415,7 +415,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
415415 \\ c = @divTrunc(a, b);
416416 \\ c = @rem(a, b);
417417 \\}
418 \\export fn u(a: c_uint, b: c_uint) -> c_uint {
418 \\pub fn u(a: c_uint, b: c_uint) -> c_uint {
419419 \\ var c: c_uint;
420420 \\ c = (a +% b);
421421 \\ c = (a -% b);
......@@ -430,7 +430,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
430430 \\ return (a & b) ^ (a | b);
431431 \\}
432432 ,
433 \\export fn max(a: c_int, b: c_int) -> c_int {
433 \\pub fn max(a: c_int, b: c_int) -> c_int {
434434 \\ return (a & b) ^ (a | b);
435435 \\}
436436 );
......@@ -444,7 +444,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
444444 \\ return a;
445445 \\}
446446 ,
447 \\export fn max(a: c_int, b: c_int) -> c_int {
447 \\pub fn max(a: c_int, b: c_int) -> c_int {
448448 \\ if ((a < b) or (a == b)) return b;
449449 \\ if ((a >= b) and (a == b)) return a;
450450 \\ return a;
......@@ -458,7 +458,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
458458 \\ a = tmp;
459459 \\}
460460 ,
461 \\export fn max(_arg_a: c_int) -> c_int {
461 \\pub fn max(_arg_a: c_int) -> c_int {
462462 \\ var a = _arg_a;
463463 \\ var tmp: c_int;
464464 \\ tmp = a;
......@@ -472,7 +472,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
472472 \\ c = b = a;
473473 \\}
474474 ,
475 \\export fn max(a: c_int) {
475 \\pub fn max(a: c_int) {
476476 \\ var b: c_int;
477477 \\ var c: c_int;
478478 \\ c = {
......@@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
493493 \\ return i;
494494 \\}
495495 ,
496 \\export fn log2(_arg_a: u32) -> c_int {
496 \\pub fn log2(_arg_a: u32) -> c_int {
497497 \\ var a = _arg_a;
498498 \\ var i: c_int = 0;
499499 \\ while (a > c_uint(0)) {
......@@ -518,7 +518,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
518518 \\void foo(void) { bar(); }
519519 ,
520520 \\pub fn bar() {}
521 \\export fn foo() {
521 \\pub fn foo() {
522522 \\ bar();
523523 \\}
524524 );
......@@ -534,7 +534,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
534534 \\pub const struct_Foo = extern struct {
535535 \\ field: c_int,
536536 \\};
537 \\export fn read_field(foo: ?&struct_Foo) -> c_int {
537 \\pub fn read_field(foo: ?&struct_Foo) -> c_int {
538538 \\ return (??foo).field;
539539 \\}
540540 );
......@@ -544,7 +544,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
544544 \\ ;;;;;
545545 \\}
546546 ,
547 \\export fn foo() {}
547 \\pub fn foo() {}
548548 );
549549
550550 cases.add("undefined array global",
......@@ -560,7 +560,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
560560 \\}
561561 ,
562562 \\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 {
564564 \\ return array[index];
565565 \\}
566566 );
......@@ -571,7 +571,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
571571 \\ return (int)a;
572572 \\}
573573 ,
574 \\export fn float_to_int(a: f32) -> c_int {
574 \\pub fn float_to_int(a: f32) -> c_int {
575575 \\ return c_int(a);
576576 \\}
577577 );
......@@ -581,7 +581,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
581581 \\ return x;
582582 \\}
583583 ,
584 \\export fn foo(x: ?&c_ushort) -> ?&c_void {
584 \\pub fn foo(x: ?&c_ushort) -> ?&c_void {
585585 \\ return @ptrCast(?&c_void, x);
586586 \\}
587587 );
......@@ -592,7 +592,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
592592 \\ return sizeof(int);
593593 \\}
594594 ,
595 \\export fn size_of() -> usize {
595 \\pub fn size_of() -> usize {
596596 \\ return @sizeOf(c_int);
597597 \\}
598598 );
......@@ -602,7 +602,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
602602 \\ return 0;
603603 \\}
604604 ,
605 \\export fn foo() -> ?&c_int {
605 \\pub fn foo() -> ?&c_int {
606606 \\ return null;
607607 \\}
608608 );
......@@ -612,7 +612,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
612612 \\ return 1, 2;
613613 \\}
614614 ,
615 \\export fn foo() -> c_int {
615 \\pub fn foo() -> c_int {
616616 \\ return {
617617 \\ _ = 1;
618618 \\ 2
......@@ -625,7 +625,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
625625 \\ return (1 << 2) >> 1;
626626 \\}
627627 ,
628 \\export fn foo() -> c_int {
628 \\pub fn foo() -> c_int {
629629 \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1);
630630 \\}
631631 );
......@@ -643,7 +643,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
643643 \\ a <<= (a <<= 1);
644644 \\}
645645 ,
646 \\export fn foo() {
646 \\pub fn foo() {
647647 \\ var a: c_int = 0;
648648 \\ a += {
649649 \\ const _ref = &a;
......@@ -701,7 +701,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
701701 \\ a <<= (a <<= 1);
702702 \\}
703703 ,
704 \\export fn foo() {
704 \\pub fn foo() {
705705 \\ var a: c_uint = c_uint(0);
706706 \\ a +%= {
707707 \\ const _ref = &a;
......@@ -771,7 +771,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
771771 \\ u = u--;
772772 \\}
773773 ,
774 \\export fn foo() {
774 \\pub fn foo() {
775775 \\ var i: c_int = 0;
776776 \\ var u: c_uint = c_uint(0);
777777 \\ i += 1;
......@@ -819,7 +819,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
819819 \\ u = --u;
820820 \\}
821821 ,
822 \\export fn foo() {
822 \\pub fn foo() {
823823 \\ var i: c_int = 0;
824824 \\ var u: c_uint = c_uint(0);
825825 \\ i += 1;
......@@ -862,7 +862,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
862862 \\ while (b != 0);
863863 \\}
864864 ,
865 \\export fn foo() {
865 \\pub fn foo() {
866866 \\ var a: c_int = 2;
867867 \\ while (true) {
868868 \\ a -= 1;
......@@ -886,9 +886,9 @@ pub fn addCases(cases: &tests.TranslateCContext) {
886886 \\ baz();
887887 \\}
888888 ,
889 \\export fn foo() {}
890 \\export fn baz() {}
891 \\export fn bar() {
889 \\pub fn foo() {}
890 \\pub fn baz() {}
891 \\pub fn bar() {
892892 \\ var f: ?extern fn() = foo;
893893 \\ (??f)();
894894 \\ (??f)();
......@@ -901,7 +901,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
901901 \\ *x = 1;
902902 \\}
903903 ,
904 \\export fn foo(x: ?&c_int) {
904 \\pub fn foo(x: ?&c_int) {
905905 \\ (*??x) = 1;
906906 \\}
907907 );