authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-19 02:44:14-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-19 02:44:14-05:00
log2a8160e80fc0a03700b83ac9a715f97d1d637f02
treeddaac9739e20717789574db9c200151dfb32a96c
parent3f658879740e3f7aee05be33532b5ba9aaa316bf
parent9d9201c3b48873e432dc6824d42b5ca96b236daa

Merge branch 'export-rewrite'

introduces the `@export` builtin function which can be used in a comptime block to conditionally export a function. it also allows creation of aliases. previous export syntax is still allowed. closes #462 closes #420

39 files changed, 1032 insertions(+), 933 deletions(-)

doc/langref.html.in+15-9
......@@ -136,6 +136,7 @@
136136 <li><a href="#builtin-divFloor">@divFloor</a></li>
137137 <li><a href="#builtin-divTrunc">@divTrunc</a></li>
138138 <li><a href="#builtin-embedFile">@embedFile</a></li>
139 <li><a href="#builtin-export">@export</a></li>
139140 <li><a href="#builtin-tagName">@tagName</a></li>
140141 <li><a href="#builtin-EnumTagType">@EnumTagType</a></li>
141142 <li><a href="#builtin-errorName">@errorName</a></li>
......@@ -4368,6 +4369,11 @@ test.zig:6:2: error: found compile log statement
43684369 <ul>
43694370 <li><a href="#builtin-import">@import</a></li>
43704371 </ul>
4372 <h3 id="builtin-export">@export</h3>
4373 <pre><code class="zig">@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) -&gt; []const u8</code></pre>
4374 <p>
4375 Creates a symbol in the output object file.
4376 </p>
43714377 <h3 id="builtin-tagName">@tagName</h3>
43724378 <pre><code class="zig">@tagName(value: var) -&gt; []const u8</code></pre>
43734379 <p>
......@@ -5815,13 +5821,15 @@ TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestD
58155821
58165822TestDecl = "test" String Block
58175823
5818TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | UseDecl)
5824TopLevelDecl = option("pub") (FnDef | ExternDecl | GlobalVarDecl | UseDecl)
58195825
58205826ErrorValueDecl = "error" Symbol ";"
58215827
5822GlobalVarDecl = VariableDeclaration ";"
5828GlobalVarDecl = option("export") VariableDeclaration ";"
58235829
5824VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") "=" Expression
5830LocalVarDecl = option("comptime") VariableDeclaration
5831
5832VariableDeclaration = ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") option("section" "(" Expression ")") "=" Expression
58255833
58265834ContainerMember = (ContainerField | FnDef | GlobalVarDecl)
58275835
......@@ -5831,11 +5839,9 @@ UseDecl = "use" Expression ";"
58315839
58325840ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";"
58335841
5834FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("-&gt;" TypeExpr)
5835
5836VisibleMod = "pub" | "export"
5842FnProto = option("coldcc" | "nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("-&gt;" TypeExpr)
58375843
5838FnDef = option("inline" | "extern") FnProto Block
5844FnDef = option("inline" | "export") FnProto Block
58395845
58405846ParamDeclList = "(" list(ParamDecl, ",") ")"
58415847
......@@ -5843,7 +5849,7 @@ ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "...")
58435849
58445850Block = "{" many(Statement) option(Expression) "}"
58455851
5846Statement = Label | VariableDeclaration ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"
5852Statement = Label | LocalVarDecl ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"
58475853
58485854Label = Symbol ":"
58495855
......@@ -5949,7 +5955,7 @@ StructLiteralField = "." Symbol "=" Expression
59495955
59505956PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%"
59515957
5952PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl
5958PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl
59535959
59545960ArrayType : "[" option(Expression) "]" option("align" "(" Expression option(":" Integer ":" Integer) ")")) option("const") option("volatile") TypeExpr
59555961
src/all_types.hpp+28-29
......@@ -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,8 @@ 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;
321318};
322319
323320struct TldFn {
......@@ -425,6 +422,7 @@ struct AstNodeFnProto {
425422 AstNode *return_type;
426423 bool is_var_args;
427424 bool is_extern;
425 bool is_export;
428426 bool is_inline;
429427 CallingConvention cc;
430428 AstNode *fn_def_node;
......@@ -432,6 +430,8 @@ struct AstNodeFnProto {
432430 Buf *lib_name;
433431 // populated if the "align A" is present
434432 AstNode *align_expr;
433 // populated if the "section(S)" is present
434 AstNode *section_expr;
435435};
436436
437437struct AstNodeFnDef {
......@@ -480,15 +480,18 @@ struct AstNodeVariableDeclaration {
480480 VisibMod visib_mod;
481481 Buf *symbol;
482482 bool is_const;
483 bool is_inline;
483 bool is_comptime;
484 bool is_export;
484485 bool is_extern;
485486 // one or both of type and expr will be non null
486487 AstNode *type;
487488 AstNode *expr;
488489 // populated if this is an extern declaration
489490 Buf *lib_name;
490 // populated if the "align A" is present
491 // populated if the "align(A)" is present
491492 AstNode *align_expr;
493 // populated if the "section(S)" is present
494 AstNode *section_expr;
492495};
493496
494497struct AstNodeErrorValueDecl {
......@@ -1177,6 +1180,11 @@ enum FnInline {
11771180 FnInlineNever,
11781181};
11791182
1183struct FnExport {
1184 Buf name;
1185 GlobalLinkageId linkage;
1186};
1187
11801188struct FnTableEntry {
11811189 LLVMValueRef llvm_value;
11821190 const char *llvm_name;
......@@ -1204,12 +1212,11 @@ struct FnTableEntry {
12041212 ZigList<IrInstruction *> alloca_list;
12051213 ZigList<VariableTableEntry *> variable_list;
12061214
1207 AstNode *set_global_section_node;
12081215 Buf *section_name;
1209 AstNode *set_global_linkage_node;
1210 GlobalLinkageId linkage;
12111216 AstNode *set_alignstack_node;
12121217 uint32_t alignstack_value;
1218
1219 ZigList<FnExport> export_list;
12131220};
12141221
12151222uint32_t fn_table_entry_hash(FnTableEntry*);
......@@ -1258,8 +1265,6 @@ enum BuiltinFnId {
12581265 BuiltinFnIdSetFloatMode,
12591266 BuiltinFnIdTypeName,
12601267 BuiltinFnIdCanImplicitCast,
1261 BuiltinFnIdSetGlobalSection,
1262 BuiltinFnIdSetGlobalLinkage,
12631268 BuiltinFnIdPanic,
12641269 BuiltinFnIdPtrCast,
12651270 BuiltinFnIdBitCast,
......@@ -1279,6 +1284,7 @@ enum BuiltinFnId {
12791284 BuiltinFnIdOpaqueType,
12801285 BuiltinFnIdSetAlignStack,
12811286 BuiltinFnIdArgType,
1287 BuiltinFnIdExport,
12821288};
12831289
12841290struct BuiltinFnEntry {
......@@ -1425,7 +1431,7 @@ struct CodeGen {
14251431 HashMap<GenericFnTypeId *, FnTableEntry *, generic_fn_type_id_hash, generic_fn_type_id_eql> generic_table;
14261432 HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table;
14271433 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;
1434 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names;
14291435 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;
14301436
14311437
......@@ -1886,8 +1892,6 @@ enum IrInstructionId {
18861892 IrInstructionIdCheckStatementIsVoid,
18871893 IrInstructionIdTypeName,
18881894 IrInstructionIdCanImplicitCast,
1889 IrInstructionIdSetGlobalSection,
1890 IrInstructionIdSetGlobalLinkage,
18911895 IrInstructionIdDeclRef,
18921896 IrInstructionIdPanic,
18931897 IrInstructionIdTagName,
......@@ -1901,6 +1905,7 @@ enum IrInstructionId {
19011905 IrInstructionIdOpaqueType,
19021906 IrInstructionIdSetAlignStack,
19031907 IrInstructionIdArgType,
1908 IrInstructionIdExport,
19041909};
19051910
19061911struct IrInstruction {
......@@ -2626,20 +2631,6 @@ struct IrInstructionCanImplicitCast {
26262631 IrInstruction *target_value;
26272632};
26282633
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
26432634struct IrInstructionDeclRef {
26442635 IrInstruction base;
26452636
......@@ -2728,6 +2719,14 @@ struct IrInstructionArgType {
27282719 IrInstruction *arg_index;
27292720};
27302721
2722struct IrInstructionExport {
2723 IrInstruction base;
2724
2725 IrInstruction *name;
2726 IrInstruction *linkage;
2727 IrInstruction *target;
2728};
2729
27312730static const size_t slice_ptr_index = 0;
27322731static const size_t slice_len_index = 1;
27332732
src/analyze.cpp+112-51
......@@ -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 || fn_proto->is_export;
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 :
......@@ -2548,6 +2577,34 @@ TypeTableEntry *get_test_fn_type(CodeGen *g) {
25482577 return g->test_fn_type;
25492578}
25502579
2580void add_fn_export(CodeGen *g, FnTableEntry *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc) {
2581 if (ccc) {
2582 if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) {
2583 g->have_c_main = true;
2584 g->windows_subsystem_windows = false;
2585 g->windows_subsystem_console = true;
2586 } else if (buf_eql_str(symbol_name, "WinMain") &&
2587 g->zig_target.os == ZigLLVM_Win32)
2588 {
2589 g->have_winmain = true;
2590 g->windows_subsystem_windows = true;
2591 g->windows_subsystem_console = false;
2592 } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&
2593 g->zig_target.os == ZigLLVM_Win32)
2594 {
2595 g->have_winmain_crt_startup = true;
2596 } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") &&
2597 g->zig_target.os == ZigLLVM_Win32)
2598 {
2599 g->have_dllmain_crt_startup = true;
2600 }
2601 }
2602 FnExport *fn_export = fn_table_entry->export_list.add_one();
2603 memset(fn_export, 0, sizeof(FnExport));
2604 buf_init_from_buf(&fn_export->name, symbol_name);
2605 fn_export->linkage = linkage;
2606}
2607
25512608static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
25522609 ImportTableEntry *import = tld_fn->base.import;
25532610 AstNode *source_node = tld_fn->base.source_node;
......@@ -2559,6 +2616,11 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
25592616 FnTableEntry *fn_table_entry = create_fn(source_node);
25602617 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
25612618
2619 if (fn_proto->is_export) {
2620 bool ccc = (fn_proto->cc == CallingConventionUnspecified || fn_proto->cc == CallingConventionC);
2621 add_fn_export(g, fn_table_entry, &fn_table_entry->symbol_name, GlobalLinkageIdStrong, ccc);
2622 }
2623
25622624 tld_fn->fn_entry = fn_table_entry;
25632625
25642626 if (fn_table_entry->body_node) {
......@@ -2572,7 +2634,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
25722634 add_node_error(g, param_node, buf_sprintf("missing parameter name"));
25732635 }
25742636 }
2575 } else if (fn_table_entry->linkage != GlobalLinkageIdInternal) {
2637 } else {
25762638 g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base);
25772639 }
25782640
......@@ -2580,6 +2642,15 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
25802642
25812643 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope);
25822644
2645 if (fn_proto->section_expr != nullptr) {
2646 if (fn_table_entry->body_node == nullptr) {
2647 add_node_error(g, fn_proto->section_expr,
2648 buf_sprintf("cannot set section of external function '%s'", buf_ptr(&fn_table_entry->symbol_name)));
2649 } else {
2650 analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name);
2651 }
2652 }
2653
25832654 if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) {
25842655 tld_fn->base.resolution = TldResolutionInvalid;
25852656 return;
......@@ -2594,15 +2665,12 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
25942665 {
25952666 if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) {
25962667 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 }
2668 TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void);
2669 TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;
2670 if (actual_return_type != err_void) {
2671 add_node_error(g, fn_proto->return_type,
2672 buf_sprintf("expected return type of main to be '%%void', instead is '%s'",
2673 buf_ptr(&actual_return_type->name)));
26062674 }
26072675 } else if ((import->package == g->panic_package || g->have_pub_panic) &&
26082676 buf_eql_str(&fn_table_entry->symbol_name, "panic"))
......@@ -2613,7 +2681,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
26132681 }
26142682 }
26152683 } else if (source_node->type == NodeTypeTestDecl) {
2616 FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong);
2684 FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto);
26172685
26182686 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
26192687
......@@ -2640,17 +2708,23 @@ static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) {
26402708}
26412709
26422710static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
2643 if (tld->visib_mod == VisibModExport) {
2644 g->resolve_queue.append(tld);
2711 bool is_export = false;
2712 if (tld->id == TldIdVar) {
2713 assert(tld->source_node->type == NodeTypeVariableDeclaration);
2714 is_export = tld->source_node->data.variable_declaration.is_export;
2715 } else if (tld->id == TldIdFn) {
2716 assert(tld->source_node->type == NodeTypeFnProto);
2717 is_export = tld->source_node->data.fn_proto.is_export;
26452718 }
2719 if (is_export) {
2720 g->resolve_queue.append(tld);
26462721
2647 if (tld->visib_mod == VisibModExport) {
2648 auto entry = g->exported_symbol_names.put_unique(tld->name, tld);
2722 auto entry = g->exported_symbol_names.put_unique(tld->name, tld->source_node);
26492723 if (entry) {
2650 Tld *other_tld = entry->value;
2724 AstNode *other_source_node = entry->value;
26512725 ErrorMsg *msg = add_node_error(g, tld->source_node,
26522726 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"));
2727 add_error_note(g, msg, other_source_node, buf_sprintf("other symbol here"));
26542728 }
26552729 }
26562730
......@@ -2729,7 +2803,6 @@ static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_s
27292803 g->resolve_queue.append(&tld_comptime->base);
27302804}
27312805
2732
27332806void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node,
27342807 Scope *parent_scope)
27352808{
......@@ -2985,8 +3058,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
29853058 AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration;
29863059
29873060 bool is_const = var_decl->is_const;
2988 bool is_export = (tld_var->base.visib_mod == VisibModExport);
29893061 bool is_extern = var_decl->is_extern;
3062 bool is_export = var_decl->is_export;
29903063
29913064 TypeTableEntry *explicit_type = nullptr;
29923065 if (var_decl->type) {
......@@ -2994,9 +3067,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
29943067 explicit_type = validate_var_type(g, var_decl->type, proposed_type);
29953068 }
29963069
2997 if (is_export && is_extern) {
2998 add_node_error(g, source_node, buf_sprintf("variable is both export and extern"));
2999 }
3070 assert(!is_export || !is_extern);
30003071
30013072 VarLinkage linkage;
30023073 if (is_export) {
......@@ -3007,7 +3078,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
30073078 linkage = VarLinkageInternal;
30083079 }
30093080
3010
30113081 IrInstruction *init_value = nullptr;
30123082
30133083 // TODO more validation for types that can't be used for export/extern variables
......@@ -3056,6 +3126,15 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
30563126 }
30573127 }
30583128
3129 if (var_decl->section_expr != nullptr) {
3130 if (var_decl->is_extern) {
3131 add_node_error(g, var_decl->section_expr,
3132 buf_sprintf("cannot set section of external variable '%s'", buf_ptr(var_decl->symbol)));
3133 } else if (!analyze_const_string(g, tld_var->base.parent_scope, var_decl->section_expr, &tld_var->section_name)) {
3134 tld_var->section_name = nullptr;
3135 }
3136 }
3137
30593138 g->global_vars.append(tld_var);
30603139}
30613140
......@@ -3724,8 +3803,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
37243803 Buf *proto_name = proto_node->data.fn_proto.name;
37253804
37263805 bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub);
3806 bool ok_cc = (proto_node->data.fn_proto.cc == CallingConventionUnspecified ||
3807 proto_node->data.fn_proto.cc == CallingConventionCold);
37273808
3728 if (is_pub) {
3809 if (is_pub && ok_cc) {
37293810 if (buf_eql_str(proto_name, "main")) {
37303811 g->have_pub_main = true;
37313812 g->windows_subsystem_windows = false;
......@@ -3733,28 +3814,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
37333814 } else if (buf_eql_str(proto_name, "panic")) {
37343815 g->have_pub_panic = true;
37353816 }
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;
37563817 }
3757
37583818 }
37593819 }
37603820
......@@ -5445,3 +5505,4 @@ uint32_t type_ptr_hash(const TypeTableEntry *ptr) {
54455505bool type_ptr_eql(const TypeTableEntry *a, const TypeTableEntry *b) {
54465506 return a == b;
54475507}
5508
src/analyze.hpp+3
......@@ -182,4 +182,7 @@ 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);
186void add_fn_export(CodeGen *g, FnTableEntry *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc);
187
185188#endif
src/ast_render.cpp+26-2
......@@ -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}
......@@ -112,6 +111,10 @@ static const char *extern_string(bool is_extern) {
112111 return is_extern ? "extern " : "";
113112}
114113
114static const char *export_string(bool is_export) {
115 return is_export ? "export " : "";
116}
117
115118//static const char *calling_convention_string(CallingConvention cc) {
116119// switch (cc) {
117120// case CallingConventionUnspecified: return "";
......@@ -411,8 +414,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
411414 {
412415 const char *pub_str = visib_mod_string(node->data.fn_proto.visib_mod);
413416 const char *extern_str = extern_string(node->data.fn_proto.is_extern);
417 const char *export_str = export_string(node->data.fn_proto.is_export);
414418 const char *inline_str = inline_string(node->data.fn_proto.is_inline);
415 fprintf(ar->f, "%s%s%sfn", pub_str, inline_str, extern_str);
419 fprintf(ar->f, "%s%s%s%sfn", pub_str, inline_str, export_str, extern_str);
416420 if (node->data.fn_proto.name != nullptr) {
417421 fprintf(ar->f, " ");
418422 print_symbol(ar, node->data.fn_proto.name);
......@@ -440,6 +444,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
440444 }
441445 }
442446 fprintf(ar->f, ")");
447 if (node->data.fn_proto.align_expr) {
448 fprintf(ar->f, " align(");
449 render_node_grouped(ar, node->data.fn_proto.align_expr);
450 fprintf(ar->f, ")");
451 }
452 if (node->data.fn_proto.section_expr) {
453 fprintf(ar->f, " section(");
454 render_node_grouped(ar, node->data.fn_proto.section_expr);
455 fprintf(ar->f, ")");
456 }
443457
444458 AstNode *return_type_node = node->data.fn_proto.return_type;
445459 if (return_type_node != nullptr) {
......@@ -526,6 +540,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
526540 fprintf(ar->f, ": ");
527541 render_node_grouped(ar, node->data.variable_declaration.type);
528542 }
543 if (node->data.variable_declaration.align_expr) {
544 fprintf(ar->f, "align(");
545 render_node_grouped(ar, node->data.variable_declaration.align_expr);
546 fprintf(ar->f, ") ");
547 }
548 if (node->data.variable_declaration.section_expr) {
549 fprintf(ar->f, "section(");
550 render_node_grouped(ar, node->data.variable_declaration.section_expr);
551 fprintf(ar->f, ") ");
552 }
529553 if (node->data.variable_declaration.expr) {
530554 fprintf(ar->f, " = ");
531555 render_node_grouped(ar, node->data.variable_declaration.expr);
src/codegen.cpp+67-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,7 @@ 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", 3);
49985020}
49995021
50005022static const char *bool_to_str(bool b) {
......@@ -5433,6 +5455,27 @@ static void gen_root_source(CodeGen *g) {
54335455 assert(g->root_out_name);
54345456 assert(g->out_type != OutTypeUnknown);
54355457
5458 {
5459 // Zig has lazy top level definitions. Here we semantically analyze the panic function.
5460 ImportTableEntry *import_with_panic;
5461 if (g->have_pub_panic) {
5462 import_with_panic = g->root_import;
5463 } else {
5464 g->panic_package = create_panic_pkg(g);
5465 import_with_panic = add_special_code(g, g->panic_package, "panic.zig");
5466 }
5467 scan_import(g, import_with_panic);
5468 Tld *panic_tld = find_decl(g, &import_with_panic->decls_scope->base, buf_create_from_str("panic"));
5469 assert(panic_tld != nullptr);
5470 resolve_top_level_decl(g, panic_tld, false, nullptr);
5471 }
5472
5473
5474 if (!g->error_during_imports) {
5475 semantic_analyze(g);
5476 }
5477 report_errors_and_maybe_exit(g);
5478
54365479 if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS &&
54375480 !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup &&
54385481 ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe))
......@@ -5442,20 +5485,6 @@ static void gen_root_source(CodeGen *g) {
54425485 if (g->zig_target.os == ZigLLVM_Win32 && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) {
54435486 g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig");
54445487 }
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 }
54595488
54605489 if (!g->error_during_imports) {
54615490 semantic_analyze(g);
......@@ -5682,7 +5711,7 @@ static void gen_h_file(CodeGen *g) {
56825711 for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) {
56835712 FnTableEntry *fn_table_entry = g->fn_defs.at(fn_def_i);
56845713
5685 if (fn_table_entry->linkage == GlobalLinkageIdInternal)
5714 if (fn_table_entry->export_list.length == 0)
56865715 continue;
56875716
56885717 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
src/ir.cpp+235-196
......@@ -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,25 @@ 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 {
4743 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4744 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4745 if (arg0_value == irb->codegen->invalid_instruction)
4746 return arg0_value;
4747
4748 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4749 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4750 if (arg1_value == irb->codegen->invalid_instruction)
4751 return arg1_value;
4752
4753 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4754 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope);
4755 if (arg2_value == irb->codegen->invalid_instruction)
4756 return arg2_value;
4757
4758 return ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value);
4759 }
47874760 }
47884761 zig_unreachable();
47894762}
......@@ -5087,7 +5060,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
50875060 bool is_const = variable_declaration->is_const;
50885061 bool is_extern = variable_declaration->is_extern;
50895062 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node,
5090 ir_should_inline(irb->exec, scope) || variable_declaration->is_inline);
5063 ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime);
50915064 VariableTableEntry *var = ir_create_var(irb, node, scope, variable_declaration->symbol,
50925065 is_const, is_const, is_shadowable, is_comptime);
50935066 // we detect IrInstructionIdDeclVar in gen_block to make sure the next node
......@@ -5106,6 +5079,11 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
51065079 return align_value;
51075080 }
51085081
5082 if (variable_declaration->section_expr != nullptr) {
5083 add_node_error(irb->codegen, variable_declaration->section_expr,
5084 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol)));
5085 }
5086
51095087 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope);
51105088 if (init_value == irb->codegen->invalid_instruction)
51115089 return init_value;
......@@ -6355,6 +6333,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
63556333 case NodeTypeSwitchRange:
63566334 case NodeTypeStructField:
63576335 case NodeTypeLabel:
6336 case NodeTypeFnDef:
6337 case NodeTypeFnDecl:
6338 case NodeTypeErrorValueDecl:
6339 case NodeTypeTestDecl:
63586340 zig_unreachable();
63596341 case NodeTypeBlock:
63606342 return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval);
......@@ -6436,14 +6418,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
64366418 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval);
64376419 case NodeTypeFnProto:
64386420 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");
64476421 }
64486422 zig_unreachable();
64496423}
......@@ -10481,6 +10455,170 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
1048110455 return ira->codegen->builtin_types.entry_void;
1048210456}
1048310457
10458static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) {
10459 IrInstruction *name = instruction->name->other;
10460 Buf *symbol_name = ir_resolve_str(ira, name);
10461 if (symbol_name == nullptr) {
10462 return ira->codegen->builtin_types.entry_invalid;
10463 }
10464
10465 IrInstruction *target = instruction->target->other;
10466 if (type_is_invalid(target->value.type)) {
10467 return ira->codegen->builtin_types.entry_invalid;
10468 }
10469
10470 GlobalLinkageId global_linkage_id = GlobalLinkageIdStrong;
10471 if (instruction->linkage != nullptr) {
10472 IrInstruction *linkage_value = instruction->linkage->other;
10473 if (!ir_resolve_global_linkage(ira, linkage_value, &global_linkage_id)) {
10474 return ira->codegen->builtin_types.entry_invalid;
10475 }
10476 }
10477
10478 auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, instruction->base.source_node);
10479 if (entry) {
10480 AstNode *other_export_node = entry->value;
10481 ErrorMsg *msg = ir_add_error(ira, &instruction->base,
10482 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name)));
10483 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here"));
10484 }
10485
10486 switch (target->value.type->id) {
10487 case TypeTableEntryIdInvalid:
10488 case TypeTableEntryIdVar:
10489 case TypeTableEntryIdUnreachable:
10490 zig_unreachable();
10491 case TypeTableEntryIdFn: {
10492 FnTableEntry *fn_entry = target->value.data.x_fn.fn_entry;
10493 CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc;
10494 switch (cc) {
10495 case CallingConventionUnspecified: {
10496 ErrorMsg *msg = ir_add_error(ira, target,
10497 buf_sprintf("exported function must specify calling convention"));
10498 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here"));
10499 } break;
10500 case CallingConventionC:
10501 case CallingConventionNaked:
10502 case CallingConventionCold:
10503 case CallingConventionStdcall:
10504 add_fn_export(ira->codegen, fn_entry, symbol_name, global_linkage_id, cc == CallingConventionC);
10505 break;
10506 }
10507 } break;
10508 case TypeTableEntryIdStruct:
10509 if (is_slice(target->value.type)) {
10510 ir_add_error(ira, target,
10511 buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value.type->name)));
10512 } else if (target->value.type->data.structure.layout != ContainerLayoutExtern) {
10513 ErrorMsg *msg = ir_add_error(ira, target,
10514 buf_sprintf("exported struct value must be declared extern"));
10515 add_error_note(ira->codegen, msg, target->value.type->data.structure.decl_node, buf_sprintf("declared here"));
10516 }
10517 break;
10518 case TypeTableEntryIdUnion:
10519 if (target->value.type->data.unionation.layout != ContainerLayoutExtern) {
10520 ErrorMsg *msg = ir_add_error(ira, target,
10521 buf_sprintf("exported union value must be declared extern"));
10522 add_error_note(ira->codegen, msg, target->value.type->data.unionation.decl_node, buf_sprintf("declared here"));
10523 }
10524 break;
10525 case TypeTableEntryIdEnum:
10526 if (target->value.type->data.enumeration.layout != ContainerLayoutExtern) {
10527 ErrorMsg *msg = ir_add_error(ira, target,
10528 buf_sprintf("exported enum value must be declared extern"));
10529 add_error_note(ira->codegen, msg, target->value.type->data.enumeration.decl_node, buf_sprintf("declared here"));
10530 }
10531 break;
10532 case TypeTableEntryIdMetaType: {
10533 TypeTableEntry *type_value = target->value.data.x_type;
10534 switch (type_value->id) {
10535 case TypeTableEntryIdInvalid:
10536 case TypeTableEntryIdVar:
10537 zig_unreachable();
10538 case TypeTableEntryIdStruct:
10539 if (is_slice(type_value)) {
10540 ir_add_error(ira, target,
10541 buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name)));
10542 } else if (type_value->data.structure.layout != ContainerLayoutExtern) {
10543 ErrorMsg *msg = ir_add_error(ira, target,
10544 buf_sprintf("exported struct must be declared extern"));
10545 add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here"));
10546 }
10547 break;
10548 case TypeTableEntryIdUnion:
10549 if (type_value->data.unionation.layout != ContainerLayoutExtern) {
10550 ErrorMsg *msg = ir_add_error(ira, target,
10551 buf_sprintf("exported union must be declared extern"));
10552 add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here"));
10553 }
10554 break;
10555 case TypeTableEntryIdEnum:
10556 if (type_value->data.enumeration.layout != ContainerLayoutExtern) {
10557 ErrorMsg *msg = ir_add_error(ira, target,
10558 buf_sprintf("exported enum must be declared extern"));
10559 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here"));
10560 }
10561 break;
10562 case TypeTableEntryIdFn: {
10563 if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) {
10564 ir_add_error(ira, target,
10565 buf_sprintf("exported function type must specify calling convention"));
10566 }
10567 } break;
10568 case TypeTableEntryIdInt:
10569 case TypeTableEntryIdFloat:
10570 case TypeTableEntryIdPointer:
10571 case TypeTableEntryIdArray:
10572 case TypeTableEntryIdBool:
10573 break;
10574 case TypeTableEntryIdMetaType:
10575 case TypeTableEntryIdVoid:
10576 case TypeTableEntryIdUnreachable:
10577 case TypeTableEntryIdNumLitFloat:
10578 case TypeTableEntryIdNumLitInt:
10579 case TypeTableEntryIdUndefLit:
10580 case TypeTableEntryIdNullLit:
10581 case TypeTableEntryIdMaybe:
10582 case TypeTableEntryIdErrorUnion:
10583 case TypeTableEntryIdPureError:
10584 case TypeTableEntryIdNamespace:
10585 case TypeTableEntryIdBlock:
10586 case TypeTableEntryIdBoundFn:
10587 case TypeTableEntryIdArgTuple:
10588 case TypeTableEntryIdOpaque:
10589 ir_add_error(ira, target,
10590 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name)));
10591 break;
10592 }
10593 } break;
10594 case TypeTableEntryIdVoid:
10595 case TypeTableEntryIdBool:
10596 case TypeTableEntryIdInt:
10597 case TypeTableEntryIdFloat:
10598 case TypeTableEntryIdPointer:
10599 case TypeTableEntryIdArray:
10600 case TypeTableEntryIdNumLitFloat:
10601 case TypeTableEntryIdNumLitInt:
10602 case TypeTableEntryIdUndefLit:
10603 case TypeTableEntryIdNullLit:
10604 case TypeTableEntryIdMaybe:
10605 case TypeTableEntryIdErrorUnion:
10606 case TypeTableEntryIdPureError:
10607 zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name));
10608 case TypeTableEntryIdNamespace:
10609 case TypeTableEntryIdBlock:
10610 case TypeTableEntryIdBoundFn:
10611 case TypeTableEntryIdArgTuple:
10612 case TypeTableEntryIdOpaque:
10613 ir_add_error(ira, target,
10614 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name)));
10615 break;
10616 }
10617
10618 ir_build_const_from(ira, &instruction->base);
10619 return ira->codegen->builtin_types.entry_void;
10620}
10621
1048410622static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node,
1048510623 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i)
1048610624{
......@@ -12399,102 +12537,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,
1239912537 return ira->codegen->builtin_types.entry_type;
1240012538}
1240112539
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
1249812540static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
1249912541 IrInstructionSetDebugSafety *set_debug_safety_instruction)
1250012542{
......@@ -16165,10 +16207,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1616516207 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);
1616616208 case IrInstructionIdPtrTypeChild:
1616716209 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);
1617216210 case IrInstructionIdSetDebugSafety:
1617316211 return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);
1617416212 case IrInstructionIdSetFloatMode:
......@@ -16311,6 +16349,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1631116349 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction);
1631216350 case IrInstructionIdTagType:
1631316351 return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction);
16352 case IrInstructionIdExport:
16353 return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction);
1631416354 }
1631516355 zig_unreachable();
1631616356}
......@@ -16418,12 +16458,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1641816458 case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free
1641916459 case IrInstructionIdCheckSwitchProngs:
1642016460 case IrInstructionIdCheckStatementIsVoid:
16421 case IrInstructionIdSetGlobalSection:
16422 case IrInstructionIdSetGlobalLinkage:
1642316461 case IrInstructionIdPanic:
1642416462 case IrInstructionIdSetEvalBranchQuota:
1642516463 case IrInstructionIdPtrTypeOf:
1642616464 case IrInstructionIdSetAlignStack:
16465 case IrInstructionIdExport:
1642716466 return true;
1642816467 case IrInstructionIdPhi:
1642916468 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+114-53
......@@ -676,7 +676,7 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b
676676}
677677
678678/*
679PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl
679PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl
680680KeywordLiteral = "true" | "false" | "null" | "continue" | "undefined" | "error" | "this" | "unreachable"
681681*/
682682static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
......@@ -740,9 +740,21 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
740740 return node;
741741 } else if (token->id == TokenIdAtSign) {
742742 *token_index += 1;
743 Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
743 Token *name_tok = &pc->tokens->at(*token_index);
744 Buf *name_buf;
745 if (name_tok->id == TokenIdKeywordExport) {
746 name_buf = buf_create_from_str("export");
747 *token_index += 1;
748 } else if (name_tok->id == TokenIdSymbol) {
749 name_buf = token_buf(name_tok);
750 *token_index += 1;
751 } else {
752 ast_expect_token(pc, name_tok, TokenIdSymbol);
753 zig_unreachable();
754 }
755
744756 AstNode *name_node = ast_create_node(pc, NodeTypeSymbol, name_tok);
745 name_node->data.symbol_expr.symbol = token_buf(name_tok);
757 name_node->data.symbol_expr.symbol = name_buf;
746758
747759 AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, token);
748760 node->data.fn_call_expr.fn_ref_expr = name_node;
......@@ -791,13 +803,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
791803 if (container_decl)
792804 return container_decl;
793805
794 if (token->id == TokenIdKeywordExtern) {
795 *token_index += 1;
796 AstNode *node = ast_parse_fn_proto(pc, token_index, true, VisibModPrivate);
797 node->data.fn_proto.is_extern = true;
798 return node;
799 }
800
801806 if (!mandatory)
802807 return nullptr;
803808
......@@ -1534,38 +1539,20 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {
15341539}
15351540
15361541/*
1537VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") "=" Expression
1542VariableDeclaration = ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") "=" Expression
15381543*/
15391544static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *token_index, bool mandatory,
1540 VisibMod visib_mod)
1545 VisibMod visib_mod, bool is_comptime, bool is_export)
15411546{
15421547 Token *first_token = &pc->tokens->at(*token_index);
15431548 Token *var_token;
15441549
15451550 bool is_const;
1546 bool is_comptime;
1547 if (first_token->id == TokenIdKeywordCompTime) {
1548 is_comptime = true;
1549 var_token = &pc->tokens->at(*token_index + 1);
1550
1551 if (var_token->id == TokenIdKeywordVar) {
1552 is_const = false;
1553 } else if (var_token->id == TokenIdKeywordConst) {
1554 is_const = true;
1555 } else if (mandatory) {
1556 ast_invalid_token_error(pc, var_token);
1557 } else {
1558 return nullptr;
1559 }
1560
1561 *token_index += 2;
1562 } else if (first_token->id == TokenIdKeywordVar) {
1563 is_comptime = false;
1551 if (first_token->id == TokenIdKeywordVar) {
15641552 is_const = false;
15651553 var_token = first_token;
15661554 *token_index += 1;
15671555 } else if (first_token->id == TokenIdKeywordConst) {
1568 is_comptime = false;
15691556 is_const = true;
15701557 var_token = first_token;
15711558 *token_index += 1;
......@@ -1577,7 +1564,8 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
15771564
15781565 AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, var_token);
15791566
1580 node->data.variable_declaration.is_inline = is_comptime;
1567 node->data.variable_declaration.is_comptime = is_comptime;
1568 node->data.variable_declaration.is_export = is_export;
15811569 node->data.variable_declaration.is_const = is_const;
15821570 node->data.variable_declaration.visib_mod = visib_mod;
15831571
......@@ -1600,6 +1588,14 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
16001588 next_token = &pc->tokens->at(*token_index);
16011589 }
16021590
1591 if (next_token->id == TokenIdKeywordSection) {
1592 *token_index += 1;
1593 ast_eat_token(pc, token_index, TokenIdLParen);
1594 node->data.variable_declaration.section_expr = ast_parse_expression(pc, token_index, true);
1595 ast_eat_token(pc, token_index, TokenIdRParen);
1596 next_token = &pc->tokens->at(*token_index);
1597 }
1598
16031599 if (next_token->id == TokenIdEq) {
16041600 *token_index += 1;
16051601 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
......@@ -1612,6 +1608,50 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
16121608 return node;
16131609}
16141610
1611/*
1612GlobalVarDecl = option("export") VariableDeclaration ";"
1613*/
1614static AstNode *ast_parse_global_var_decl(ParseContext *pc, size_t *token_index, VisibMod visib_mod) {
1615 Token *first_token = &pc->tokens->at(*token_index);
1616
1617 bool is_export = false;;
1618 if (first_token->id == TokenIdKeywordExport) {
1619 *token_index += 1;
1620 is_export = true;
1621 }
1622
1623 AstNode *node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod, false, is_export);
1624 if (node == nullptr) {
1625 if (is_export) {
1626 *token_index -= 1;
1627 }
1628 return nullptr;
1629 }
1630 return node;
1631}
1632
1633/*
1634LocalVarDecl = option("comptime") VariableDeclaration
1635*/
1636static AstNode *ast_parse_local_var_decl(ParseContext *pc, size_t *token_index) {
1637 Token *first_token = &pc->tokens->at(*token_index);
1638
1639 bool is_comptime = false;;
1640 if (first_token->id == TokenIdKeywordCompTime) {
1641 *token_index += 1;
1642 is_comptime = true;
1643 }
1644
1645 AstNode *node = ast_parse_variable_declaration_expr(pc, token_index, false, VisibModPrivate, is_comptime, false);
1646 if (node == nullptr) {
1647 if (is_comptime) {
1648 *token_index -= 1;
1649 }
1650 return nullptr;
1651 }
1652 return node;
1653}
1654
16151655/*
16161656BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression
16171657*/
......@@ -2144,7 +2184,7 @@ static bool statement_terminates_without_semicolon(AstNode *node) {
21442184
21452185/*
21462186Block = "{" many(Statement) option(Expression) "}"
2147Statement = Label | VariableDeclaration ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"
2187Statement = Label | VariableDeclaration ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";" | ExportDecl
21482188*/
21492189static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mandatory) {
21502190 Token *last_token = &pc->tokens->at(*token_index);
......@@ -2163,7 +2203,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
21632203 for (;;) {
21642204 AstNode *statement_node = ast_parse_label(pc, token_index, false);
21652205 if (!statement_node)
2166 statement_node = ast_parse_variable_declaration_expr(pc, token_index, false, VisibModPrivate);
2206 statement_node = ast_parse_local_var_decl(pc, token_index);
21672207 if (!statement_node)
21682208 statement_node = ast_parse_defer_expr(pc, token_index);
21692209 if (!statement_node)
......@@ -2205,13 +2245,14 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
22052245}
22062246
22072247/*
2208FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("->" TypeExpr)
2248FnProto = option("coldcc" | "nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("-&gt;" TypeExpr)
22092249*/
22102250static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
22112251 Token *first_token = &pc->tokens->at(*token_index);
22122252 Token *fn_token;
22132253
22142254 CallingConvention cc;
2255 bool is_extern = false;
22152256 if (first_token->id == TokenIdKeywordColdCC) {
22162257 *token_index += 1;
22172258 fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn);
......@@ -2224,6 +2265,21 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
22242265 *token_index += 1;
22252266 fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn);
22262267 cc = CallingConventionStdcall;
2268 } else if (first_token->id == TokenIdKeywordExtern) {
2269 is_extern = true;
2270 *token_index += 1;
2271 Token *next_token = &pc->tokens->at(*token_index);
2272 if (next_token->id == TokenIdKeywordFn) {
2273 fn_token = next_token;
2274 *token_index += 1;
2275 } else if (mandatory) {
2276 ast_expect_token(pc, next_token, TokenIdKeywordFn);
2277 zig_unreachable();
2278 } else {
2279 *token_index -= 1;
2280 return nullptr;
2281 }
2282 cc = CallingConventionC;
22272283 } else if (first_token->id == TokenIdKeywordFn) {
22282284 fn_token = first_token;
22292285 *token_index += 1;
......@@ -2238,6 +2294,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
22382294 AstNode *node = ast_create_node(pc, NodeTypeFnProto, fn_token);
22392295 node->data.fn_proto.visib_mod = visib_mod;
22402296 node->data.fn_proto.cc = cc;
2297 node->data.fn_proto.is_extern = is_extern;
22412298
22422299 Token *fn_name = &pc->tokens->at(*token_index);
22432300
......@@ -2259,6 +2316,14 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
22592316 ast_eat_token(pc, token_index, TokenIdRParen);
22602317 next_token = &pc->tokens->at(*token_index);
22612318 }
2319 if (next_token->id == TokenIdKeywordSection) {
2320 *token_index += 1;
2321 ast_eat_token(pc, token_index, TokenIdLParen);
2322
2323 node->data.fn_proto.section_expr = ast_parse_expression(pc, token_index, true);
2324 ast_eat_token(pc, token_index, TokenIdRParen);
2325 next_token = &pc->tokens->at(*token_index);
2326 }
22622327 if (next_token->id == TokenIdArrow) {
22632328 *token_index += 1;
22642329 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, false);
......@@ -2270,35 +2335,35 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
22702335}
22712336
22722337/*
2273FnDef = option("inline" | "extern") FnProto Block
2338FnDef = option("inline" | "export") FnProto Block
22742339*/
22752340static AstNode *ast_parse_fn_def(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
22762341 Token *first_token = &pc->tokens->at(*token_index);
22772342 bool is_inline;
2278 bool is_extern;
2343 bool is_export;
22792344 if (first_token->id == TokenIdKeywordInline) {
22802345 *token_index += 1;
22812346 is_inline = true;
2282 is_extern = false;
2283 } else if (first_token->id == TokenIdKeywordExtern) {
2347 is_export = false;
2348 } else if (first_token->id == TokenIdKeywordExport) {
22842349 *token_index += 1;
2285 is_extern = true;
2350 is_export = true;
22862351 is_inline = false;
22872352 } else {
22882353 is_inline = false;
2289 is_extern = false;
2354 is_export = false;
22902355 }
22912356
22922357 AstNode *fn_proto = ast_parse_fn_proto(pc, token_index, mandatory, visib_mod);
22932358 if (!fn_proto) {
2294 if (is_inline || is_extern) {
2359 if (is_inline || is_export) {
22952360 *token_index -= 1;
22962361 }
22972362 return nullptr;
22982363 }
22992364
23002365 fn_proto->data.fn_proto.is_inline = is_inline;
2301 fn_proto->data.fn_proto.is_extern = is_extern;
2366 fn_proto->data.fn_proto.is_export = is_export;
23022367
23032368 Token *semi_token = &pc->tokens->at(*token_index);
23042369 if (semi_token->id == TokenIdSemicolon) {
......@@ -2344,7 +2409,7 @@ static AstNode *ast_parse_extern_decl(ParseContext *pc, size_t *token_index, boo
23442409 return fn_proto_node;
23452410 }
23462411
2347 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod);
2412 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod, false, false);
23482413 if (var_decl_node) {
23492414 ast_eat_token(pc, token_index, TokenIdSemicolon);
23502415
......@@ -2447,9 +2512,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
24472512 if (visib_tok->id == TokenIdKeywordPub) {
24482513 *token_index += 1;
24492514 visib_mod = VisibModPub;
2450 } else if (visib_tok->id == TokenIdKeywordExport) {
2451 *token_index += 1;
2452 visib_mod = VisibModExport;
24532515 } else {
24542516 visib_mod = VisibModPrivate;
24552517 }
......@@ -2460,7 +2522,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
24602522 continue;
24612523 }
24622524
2463 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod);
2525 AstNode *var_decl_node = ast_parse_global_var_decl(pc, token_index, visib_mod);
24642526 if (var_decl_node) {
24652527 ast_eat_token(pc, token_index, TokenIdSemicolon);
24662528 node->data.container_decl.decls.append(var_decl_node);
......@@ -2553,7 +2615,7 @@ static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index)
25532615
25542616/*
25552617TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestDecl
2556TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | UseDecl)
2618TopLevelDecl = option("pub") (FnDef | ExternDecl | GlobalVarDecl | UseDecl)
25572619*/
25582620static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) {
25592621 for (;;) {
......@@ -2580,9 +2642,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig
25802642 if (visib_tok->id == TokenIdKeywordPub) {
25812643 *token_index += 1;
25822644 visib_mod = VisibModPub;
2583 } else if (visib_tok->id == TokenIdKeywordExport) {
2584 *token_index += 1;
2585 visib_mod = VisibModExport;
25862645 } else {
25872646 visib_mod = VisibModPrivate;
25882647 }
......@@ -2605,7 +2664,7 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig
26052664 continue;
26062665 }
26072666
2608 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod);
2667 AstNode *var_decl_node = ast_parse_global_var_decl(pc, token_index, visib_mod);
26092668 if (var_decl_node) {
26102669 ast_eat_token(pc, token_index, TokenIdSemicolon);
26112670 top_level_decls->append(var_decl_node);
......@@ -2669,6 +2728,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
26692728 visit_field(&node->data.fn_proto.return_type, visit, context);
26702729 visit_node_list(&node->data.fn_proto.params, visit, context);
26712730 visit_field(&node->data.fn_proto.align_expr, visit, context);
2731 visit_field(&node->data.fn_proto.section_expr, visit, context);
26722732 break;
26732733 case NodeTypeFnDef:
26742734 visit_field(&node->data.fn_def.fn_proto, visit, context);
......@@ -2696,6 +2756,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
26962756 visit_field(&node->data.variable_declaration.type, visit, context);
26972757 visit_field(&node->data.variable_declaration.expr, visit, context);
26982758 visit_field(&node->data.variable_declaration.align_expr, visit, context);
2759 visit_field(&node->data.variable_declaration.section_expr, visit, context);
26992760 break;
27002761 case NodeTypeErrorValueDecl:
27012762 // none
src/tokenizer.cpp+2
......@@ -134,6 +134,7 @@ static const struct ZigKeyword zig_keywords[] = {
134134 {"packed", TokenIdKeywordPacked},
135135 {"pub", TokenIdKeywordPub},
136136 {"return", TokenIdKeywordReturn},
137 {"section", TokenIdKeywordSection},
137138 {"stdcallcc", TokenIdKeywordStdcallCC},
138139 {"struct", TokenIdKeywordStruct},
139140 {"switch", TokenIdKeywordSwitch},
......@@ -1533,6 +1534,7 @@ const char * token_name(TokenId id) {
15331534 case TokenIdKeywordPacked: return "packed";
15341535 case TokenIdKeywordPub: return "pub";
15351536 case TokenIdKeywordReturn: return "return";
1537 case TokenIdKeywordSection: return "section";
15361538 case TokenIdKeywordStdcallCC: return "stdcallcc";
15371539 case TokenIdKeywordStruct: return "struct";
15381540 case TokenIdKeywordSwitch: return "switch";
src/tokenizer.hpp+1
......@@ -47,6 +47,7 @@ enum TokenId {
4747 TokenIdFloatLiteral,
4848 TokenIdIntLiteral,
4949 TokenIdKeywordAlign,
50 TokenIdKeywordSection,
5051 TokenIdKeywordAnd,
5152 TokenIdKeywordAsm,
5253 TokenIdKeywordBreak,
src/translate_c.cpp+5-4
......@@ -73,7 +73,7 @@ struct Context {
7373 ImportTableEntry *import;
7474 ZigList<ErrorMsg *> *errors;
7575 VisibMod visib_mod;
76 VisibMod export_visib_mod;
76 bool want_export;
7777 AstNode *root;
7878 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
7979 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
......@@ -3251,7 +3251,8 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
32513251
32523252 StorageClass sc = fn_decl->getStorageClass();
32533253 if (sc == SC_None) {
3254 proto_node->data.fn_proto.visib_mod = fn_decl->hasBody() ? c->export_visib_mod : c->visib_mod;
3254 proto_node->data.fn_proto.visib_mod = c->visib_mod;
3255 proto_node->data.fn_proto.is_export = fn_decl->hasBody() ? c->want_export : false;
32553256 } else if (sc == SC_Extern || sc == SC_Static) {
32563257 proto_node->data.fn_proto.visib_mod = c->visib_mod;
32573258 } else if (sc == SC_PrivateExtern) {
......@@ -4274,10 +4275,10 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
42744275 c->errors = errors;
42754276 if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) {
42764277 c->visib_mod = VisibModPub;
4277 c->export_visib_mod = VisibModPub;
4278 c->want_export = false;
42784279 } else {
42794280 c->visib_mod = VisibModPub;
4280 c->export_visib_mod = VisibModExport;
4281 c->want_export = true;
42814282 }
42824283 c->decl_table.init(8);
42834284 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/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+12-24
......@@ -5,20 +5,20 @@ 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 const strong_linkage = builtin.GlobalLinkage.Strong;
12 if (builtin.link_libc) {
13 @export("main", main, strong_linkage);
14 } else if (builtin.os == builtin.Os.windows) {
15 @export("WinMainCRTStartup", WinMainCRTStartup, strong_linkage);
16 } else {
17 @export("_start", _start, strong_linkage);
2018 }
19}
2120
21nakedcc fn _start() -> noreturn {
2222 switch (builtin.arch) {
2323 builtin.Arch.x86_64 => {
2424 argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize));
......@@ -33,14 +33,9 @@ export nakedcc fn _start() -> noreturn {
3333 @noInlineCall(posixCallMainAndExit);
3434}
3535
36export fn WinMainCRTStartup() -> noreturn {
37 if (!want_WinMainCRTStartup) {
38 @setGlobalLinkage(WinMainCRTStartup, builtin.GlobalLinkage.Internal);
39 unreachable;
40 }
36extern fn WinMainCRTStartup() -> noreturn {
4137 @setAlignStack(16);
4238
43 std.debug.user_main_fn = root.main;
4439 root.main() %% std.os.windows.ExitProcess(1);
4540 std.os.windows.ExitProcess(0);
4641}
......@@ -60,17 +55,10 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void {
6055 while (envp[env_count] != null) : (env_count += 1) {}
6156 std.os.posix_environ_raw = @ptrCast(&&u8, envp)[0..env_count];
6257
63 std.debug.user_main_fn = root.main;
64
6558 return root.main();
6659}
6760
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
61extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 {
7462 callMain(usize(c_argc), c_argv, c_envp) %% return 1;
7563 return 0;
7664}
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+5-4
......@@ -35,11 +35,12 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {
3535 (??dest)[index] = (??src)[index];
3636}
3737
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;
38comptime {
39 if (builtin.mode != builtin.Mode.ReleaseFast and builtin.os != builtin.Os.windows) {
40 @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong);
4241 }
42}
43extern fn __stack_chk_fail() -> noreturn {
4344 @panic("stack smashing detected");
4445}
4546
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 @export("__letf2", @import("comparetf2.zig").__letf2, linkage);
9 @export("__getf2", @import("comparetf2.zig").__getf2, linkage);
10
11 if (!is_test) {
12 // only create these aliases when not testing
13 @export("__cmptf2", @import("comparetf2.zig").__letf2, linkage);
14 @export("__eqtf2", @import("comparetf2.zig").__letf2, linkage);
15 @export("__lttf2", @import("comparetf2.zig").__letf2, linkage);
16 @export("__netf2", @import("comparetf2.zig").__letf2, linkage);
17 @export("__gttf2", @import("comparetf2.zig").__getf2, linkage);
18 }
19
20 @export("__unordtf2", @import("comparetf2.zig").__unordtf2, linkage);
21
22 @export("__fixunssfsi", @import("fixunssfsi.zig").__fixunssfsi, linkage);
23 @export("__fixunssfdi", @import("fixunssfdi.zig").__fixunssfdi, linkage);
24 @export("__fixunssfti", @import("fixunssfti.zig").__fixunssfti, linkage);
25
26 @export("__fixunsdfsi", @import("fixunsdfsi.zig").__fixunsdfsi, linkage);
27 @export("__fixunsdfdi", @import("fixunsdfdi.zig").__fixunsdfdi, linkage);
28 @export("__fixunsdfti", @import("fixunsdfti.zig").__fixunsdfti, linkage);
29
30 @export("__fixunstfsi", @import("fixunstfsi.zig").__fixunstfsi, linkage);
31 @export("__fixunstfdi", @import("fixunstfdi.zig").__fixunstfdi, linkage);
32 @export("__fixunstfti", @import("fixunstfti.zig").__fixunstfti, linkage);
33
34 @export("__udivmoddi4", @import("udivmoddi4.zig").__udivmoddi4, linkage);
35 @export("__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 @export("__udivti3", @import("udivti3.zig").__udivti3, linkage);
38 @export("__umodti3", @import("umodti3.zig").__umodti3, linkage);
39
40 @export("__udivsi3", __udivsi3, linkage);
41 @export("__udivdi3", __udivdi3, linkage);
42 @export("__umoddi3", __umoddi3, linkage);
43 @export("__udivmodsi4", __udivmodsi4, linkage);
44
45 if (isArmArch()) {
46 @export("__aeabi_uldivmod", __aeabi_uldivmod, linkage);
47 @export("__aeabi_uidivmod", __aeabi_uidivmod, linkage);
48 @export("__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 @export("_chkstk", _chkstk, strong_linkage);
55 @export("__chkstk_ms", __chkstk_ms, linkage);
56 }
57 @export("_aulldiv", @import("aulldiv.zig")._aulldiv, strong_linkage);
58 @export("_aullrem", @import("aullrem.zig")._aullrem, strong_linkage);
59 },
60 builtin.Arch.x86_64 => {
61 if (!builtin.link_libc) {
62 @export("__chkstk", __chkstk, strong_linkage);
63 @export("___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/misc.zig+5-2
......@@ -12,8 +12,11 @@ test "empty function with comments" {
1212 emptyFunctionWithComments();
1313}
1414
15export fn disabledExternFn() {
16 @setGlobalLinkage(disabledExternFn, builtin.GlobalLinkage.Internal);
15comptime {
16 @export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal);
17}
18
19extern fn disabledExternFn() {
1720}
1821
1922test "call disabled extern fn" {
test/compile_errors.zig+24-17
......@@ -1468,7 +1468,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
14681468 \\}
14691469 ,
14701470 "foo.zig:1:8: error: exported symbol collision: 'bar'",
1471 ".tmp_source.zig:3:8: note: other symbol is here");
1471 ".tmp_source.zig:3:8: note: other symbol here");
14721472
14731473 tc.addSourceFile("foo.zig",
14741474 \\export fn bar() {}
......@@ -1611,23 +1611,29 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16111611 "error: 'main' is private",
16121612 ".tmp_source.zig:1:1: note: declared here");
16131613
1614 cases.add("@setGlobalSection extern variable",
1615 \\extern var foo: i32;
1616 \\comptime {
1617 \\ @setGlobalSection(foo, ".text2");
1614 cases.add("setting a section on an extern variable",
1615 \\extern var foo: i32 section(".text2");
1616 \\export fn entry() -> i32 {
1617 \\ return foo;
16181618 \\}
16191619 ,
1620 ".tmp_source.zig:3:5: error: cannot set section of external variable 'foo'",
1621 ".tmp_source.zig:1:8: note: declared here");
1620 ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'");
16221621
1623 cases.add("@setGlobalSection extern fn",
1624 \\extern fn foo();
1625 \\comptime {
1626 \\ @setGlobalSection(foo, ".text2");
1622 cases.add("setting a section on a local variable",
1623 \\export fn entry() -> i32 {
1624 \\ var foo: i32 section(".text2") = 1234;
1625 \\ return foo;
16271626 \\}
16281627 ,
1629 ".tmp_source.zig:3:5: error: cannot set section of external function 'foo'",
1630 ".tmp_source.zig:1:8: note: declared here");
1628 ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'");
1629
1630 cases.add("setting a section on an extern fn",
1631 \\extern fn foo() section(".text2");
1632 \\export fn entry() {
1633 \\ foo();
1634 \\}
1635 ,
1636 ".tmp_source.zig:1:25: error: cannot set section of external function 'foo'");
16311637
16321638 cases.add("returning address of local variable - simple",
16331639 \\export fn foo() -> &i32 {
......@@ -2120,12 +2126,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
21202126 ,
21212127 ".tmp_source.zig:3:41: error: expected type 'AtomicOrder', found 'u32'");
21222128
2123 cases.add("wrong types given to setGlobalLinkage",
2124 \\export fn entry() {
2125 \\ @setGlobalLinkage(entry, u32(1234));
2129 cases.add("wrong types given to @export",
2130 \\extern fn entry() { }
2131 \\comptime {
2132 \\ @export("entry", entry, u32(1234));
21262133 \\}
21272134 ,
2128 ".tmp_source.zig:2:33: error: expected type 'GlobalLinkage', found 'u32'");
2135 ".tmp_source.zig:3:32: error: expected type 'GlobalLinkage', found 'u32'");
21292136
21302137 cases.add("struct with invalid field",
21312138 \\const std = @import("std");
test/translate_c.zig+31-31
......@@ -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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export 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 export fn foo() {}
890 \\pub export fn baz() {}
891 \\pub export 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 export fn foo(x: ?&c_int) {
905905 \\ (*??x) = 1;
906906 \\}
907907 );