| author | |
| committer | |
| log | 2a8160e80fc0a03700b83ac9a715f97d1d637f02 |
| tree | ddaac9739e20717789574db9c200151dfb32a96c |
| parent | 3f658879740e3f7aee05be33532b5ba9aaa316bf |
| parent | 9d9201c3b48873e432dc6824d42b5ca96b236daa |
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 #42039 files changed, 1032 insertions(+), 933 deletions(-)
doc/langref.html.in+15-9| ... | @@ -136,6 +136,7 @@ | ... | @@ -136,6 +136,7 @@ |
| 136 | <li><a href="#builtin-divFloor">@divFloor</a></li> | 136 | <li><a href="#builtin-divFloor">@divFloor</a></li> |
| 137 | <li><a href="#builtin-divTrunc">@divTrunc</a></li> | 137 | <li><a href="#builtin-divTrunc">@divTrunc</a></li> |
| 138 | <li><a href="#builtin-embedFile">@embedFile</a></li> | 138 | <li><a href="#builtin-embedFile">@embedFile</a></li> |
| 139 | <li><a href="#builtin-export">@export</a></li> | ||
| 139 | <li><a href="#builtin-tagName">@tagName</a></li> | 140 | <li><a href="#builtin-tagName">@tagName</a></li> |
| 140 | <li><a href="#builtin-EnumTagType">@EnumTagType</a></li> | 141 | <li><a href="#builtin-EnumTagType">@EnumTagType</a></li> |
| 141 | <li><a href="#builtin-errorName">@errorName</a></li> | 142 | <li><a href="#builtin-errorName">@errorName</a></li> |
| ... | @@ -4368,6 +4369,11 @@ test.zig:6:2: error: found compile log statement | ... | @@ -4368,6 +4369,11 @@ test.zig:6:2: error: found compile log statement |
| 4368 | <ul> | 4369 | <ul> |
| 4369 | <li><a href="#builtin-import">@import</a></li> | 4370 | <li><a href="#builtin-import">@import</a></li> |
| 4370 | </ul> | 4371 | </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> | ||
| 4371 | <h3 id="builtin-tagName">@tagName</h3> | 4377 | <h3 id="builtin-tagName">@tagName</h3> |
| 4372 | <pre><code class="zig">@tagName(value: var) -&gt; []const u8</code></pre> | 4378 | <pre><code class="zig">@tagName(value: var) -&gt; []const u8</code></pre> |
| 4373 | <p> | 4379 | <p> |
| ... | @@ -5815,13 +5821,15 @@ TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestD | ... | @@ -5815,13 +5821,15 @@ TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestD |
| 5815 | 5821 | ||
| 5816 | TestDecl = "test" String Block | 5822 | TestDecl = "test" String Block |
| 5817 | 5823 | ||
| 5818 | TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | UseDecl) | 5824 | TopLevelDecl = option("pub") (FnDef | ExternDecl | GlobalVarDecl | UseDecl) |
| 5819 | 5825 | ||
| 5820 | ErrorValueDecl = "error" Symbol ";" | 5826 | ErrorValueDecl = "error" Symbol ";" |
| 5821 | 5827 | ||
| 5822 | GlobalVarDecl = VariableDeclaration ";" | 5828 | GlobalVarDecl = option("export") VariableDeclaration ";" |
| 5823 | 5829 | ||
| 5824 | VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") "=" Expression | 5830 | LocalVarDecl = option("comptime") VariableDeclaration |
| 5831 | |||
| 5832 | VariableDeclaration = ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") option("section" "(" Expression ")") "=" Expression | ||
| 5825 | 5833 | ||
| 5826 | ContainerMember = (ContainerField | FnDef | GlobalVarDecl) | 5834 | ContainerMember = (ContainerField | FnDef | GlobalVarDecl) |
| 5827 | 5835 | ||
| ... | @@ -5831,11 +5839,9 @@ UseDecl = "use" Expression ";" | ... | @@ -5831,11 +5839,9 @@ UseDecl = "use" Expression ";" |
| 5831 | 5839 | ||
| 5832 | ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";" | 5840 | ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";" |
| 5833 | 5841 | ||
| 5834 | FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("-&gt;" TypeExpr) | 5842 | FnProto = option("coldcc" | "nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("-&gt;" TypeExpr) |
| 5835 | |||
| 5836 | VisibleMod = "pub" | "export" | ||
| 5837 | 5843 | ||
| 5838 | FnDef = option("inline" | "extern") FnProto Block | 5844 | FnDef = option("inline" | "export") FnProto Block |
| 5839 | 5845 | ||
| 5840 | ParamDeclList = "(" list(ParamDecl, ",") ")" | 5846 | ParamDeclList = "(" list(ParamDecl, ",") ")" |
| 5841 | 5847 | ||
| ... | @@ -5843,7 +5849,7 @@ ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "...") | ... | @@ -5843,7 +5849,7 @@ ParamDecl = option("noalias" | "comptime") option(Symbol ":") (TypeExpr | "...") |
| 5843 | 5849 | ||
| 5844 | Block = "{" many(Statement) option(Expression) "}" | 5850 | Block = "{" many(Statement) option(Expression) "}" |
| 5845 | 5851 | ||
| 5846 | Statement = Label | VariableDeclaration ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";" | 5852 | Statement = Label | LocalVarDecl ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";" |
| 5847 | 5853 | ||
| 5848 | Label = Symbol ":" | 5854 | Label = Symbol ":" |
| 5849 | 5855 | ||
| ... | @@ -5949,7 +5955,7 @@ StructLiteralField = "." Symbol "=" Expression | ... | @@ -5949,7 +5955,7 @@ StructLiteralField = "." Symbol "=" Expression |
| 5949 | 5955 | ||
| 5950 | PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | 5956 | PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" |
| 5951 | 5957 | ||
| 5952 | PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl | 5958 | PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl |
| 5953 | 5959 | ||
| 5954 | ArrayType : "[" option(Expression) "]" option("align" "(" Expression option(":" Integer ":" Integer) ")")) option("const") option("volatile") TypeExpr | 5960 | ArrayType : "[" option(Expression) "]" option("align" "(" Expression option(":" Integer ":" Integer) ")")) option("const") option("volatile") TypeExpr |
| 5955 | 5961 |
src/all_types.hpp+28-29| ... | @@ -37,6 +37,7 @@ struct IrBasicBlock; | ... | @@ -37,6 +37,7 @@ struct IrBasicBlock; |
| 37 | struct ScopeDecls; | 37 | struct ScopeDecls; |
| 38 | struct ZigWindowsSDK; | 38 | struct ZigWindowsSDK; |
| 39 | struct Tld; | 39 | struct Tld; |
| 40 | struct TldExport; | ||
| 40 | 41 | ||
| 41 | struct IrGotoItem { | 42 | struct IrGotoItem { |
| 42 | AstNode *source_node; | 43 | AstNode *source_node; |
| ... | @@ -272,7 +273,6 @@ enum ReturnKnowledge { | ... | @@ -272,7 +273,6 @@ enum ReturnKnowledge { |
| 272 | enum VisibMod { | 273 | enum VisibMod { |
| 273 | VisibModPrivate, | 274 | VisibModPrivate, |
| 274 | VisibModPub, | 275 | VisibModPub, |
| 275 | VisibModExport, | ||
| 276 | }; | 276 | }; |
| 277 | 277 | ||
| 278 | enum GlobalLinkageId { | 278 | enum GlobalLinkageId { |
| ... | @@ -313,11 +313,8 @@ struct TldVar { | ... | @@ -313,11 +313,8 @@ struct TldVar { |
| 313 | Tld base; | 313 | Tld base; |
| 314 | 314 | ||
| 315 | VariableTableEntry *var; | 315 | VariableTableEntry *var; |
| 316 | AstNode *set_global_section_node; | ||
| 317 | Buf *section_name; | ||
| 318 | AstNode *set_global_linkage_node; | ||
| 319 | GlobalLinkageId linkage; | ||
| 320 | Buf *extern_lib_name; | 316 | Buf *extern_lib_name; |
| 317 | Buf *section_name; | ||
| 321 | }; | 318 | }; |
| 322 | 319 | ||
| 323 | struct TldFn { | 320 | struct TldFn { |
| ... | @@ -425,6 +422,7 @@ struct AstNodeFnProto { | ... | @@ -425,6 +422,7 @@ struct AstNodeFnProto { |
| 425 | AstNode *return_type; | 422 | AstNode *return_type; |
| 426 | bool is_var_args; | 423 | bool is_var_args; |
| 427 | bool is_extern; | 424 | bool is_extern; |
| 425 | bool is_export; | ||
| 428 | bool is_inline; | 426 | bool is_inline; |
| 429 | CallingConvention cc; | 427 | CallingConvention cc; |
| 430 | AstNode *fn_def_node; | 428 | AstNode *fn_def_node; |
| ... | @@ -432,6 +430,8 @@ struct AstNodeFnProto { | ... | @@ -432,6 +430,8 @@ struct AstNodeFnProto { |
| 432 | Buf *lib_name; | 430 | Buf *lib_name; |
| 433 | // populated if the "align A" is present | 431 | // populated if the "align A" is present |
| 434 | AstNode *align_expr; | 432 | AstNode *align_expr; |
| 433 | // populated if the "section(S)" is present | ||
| 434 | AstNode *section_expr; | ||
| 435 | }; | 435 | }; |
| 436 | 436 | ||
| 437 | struct AstNodeFnDef { | 437 | struct AstNodeFnDef { |
| ... | @@ -480,15 +480,18 @@ struct AstNodeVariableDeclaration { | ... | @@ -480,15 +480,18 @@ struct AstNodeVariableDeclaration { |
| 480 | VisibMod visib_mod; | 480 | VisibMod visib_mod; |
| 481 | Buf *symbol; | 481 | Buf *symbol; |
| 482 | bool is_const; | 482 | bool is_const; |
| 483 | bool is_inline; | 483 | bool is_comptime; |
| 484 | bool is_export; | ||
| 484 | bool is_extern; | 485 | bool is_extern; |
| 485 | // one or both of type and expr will be non null | 486 | // one or both of type and expr will be non null |
| 486 | AstNode *type; | 487 | AstNode *type; |
| 487 | AstNode *expr; | 488 | AstNode *expr; |
| 488 | // populated if this is an extern declaration | 489 | // populated if this is an extern declaration |
| 489 | Buf *lib_name; | 490 | Buf *lib_name; |
| 490 | // populated if the "align A" is present | 491 | // populated if the "align(A)" is present |
| 491 | AstNode *align_expr; | 492 | AstNode *align_expr; |
| 493 | // populated if the "section(S)" is present | ||
| 494 | AstNode *section_expr; | ||
| 492 | }; | 495 | }; |
| 493 | 496 | ||
| 494 | struct AstNodeErrorValueDecl { | 497 | struct AstNodeErrorValueDecl { |
| ... | @@ -1177,6 +1180,11 @@ enum FnInline { | ... | @@ -1177,6 +1180,11 @@ enum FnInline { |
| 1177 | FnInlineNever, | 1180 | FnInlineNever, |
| 1178 | }; | 1181 | }; |
| 1179 | 1182 | ||
| 1183 | struct FnExport { | ||
| 1184 | Buf name; | ||
| 1185 | GlobalLinkageId linkage; | ||
| 1186 | }; | ||
| 1187 | |||
| 1180 | struct FnTableEntry { | 1188 | struct FnTableEntry { |
| 1181 | LLVMValueRef llvm_value; | 1189 | LLVMValueRef llvm_value; |
| 1182 | const char *llvm_name; | 1190 | const char *llvm_name; |
| ... | @@ -1204,12 +1212,11 @@ struct FnTableEntry { | ... | @@ -1204,12 +1212,11 @@ struct FnTableEntry { |
| 1204 | ZigList<IrInstruction *> alloca_list; | 1212 | ZigList<IrInstruction *> alloca_list; |
| 1205 | ZigList<VariableTableEntry *> variable_list; | 1213 | ZigList<VariableTableEntry *> variable_list; |
| 1206 | 1214 | ||
| 1207 | AstNode *set_global_section_node; | ||
| 1208 | Buf *section_name; | 1215 | Buf *section_name; |
| 1209 | AstNode *set_global_linkage_node; | ||
| 1210 | GlobalLinkageId linkage; | ||
| 1211 | AstNode *set_alignstack_node; | 1216 | AstNode *set_alignstack_node; |
| 1212 | uint32_t alignstack_value; | 1217 | uint32_t alignstack_value; |
| 1218 | |||
| 1219 | ZigList<FnExport> export_list; | ||
| 1213 | }; | 1220 | }; |
| 1214 | 1221 | ||
| 1215 | uint32_t fn_table_entry_hash(FnTableEntry*); | 1222 | uint32_t fn_table_entry_hash(FnTableEntry*); |
| ... | @@ -1258,8 +1265,6 @@ enum BuiltinFnId { | ... | @@ -1258,8 +1265,6 @@ enum BuiltinFnId { |
| 1258 | BuiltinFnIdSetFloatMode, | 1265 | BuiltinFnIdSetFloatMode, |
| 1259 | BuiltinFnIdTypeName, | 1266 | BuiltinFnIdTypeName, |
| 1260 | BuiltinFnIdCanImplicitCast, | 1267 | BuiltinFnIdCanImplicitCast, |
| 1261 | BuiltinFnIdSetGlobalSection, | ||
| 1262 | BuiltinFnIdSetGlobalLinkage, | ||
| 1263 | BuiltinFnIdPanic, | 1268 | BuiltinFnIdPanic, |
| 1264 | BuiltinFnIdPtrCast, | 1269 | BuiltinFnIdPtrCast, |
| 1265 | BuiltinFnIdBitCast, | 1270 | BuiltinFnIdBitCast, |
| ... | @@ -1279,6 +1284,7 @@ enum BuiltinFnId { | ... | @@ -1279,6 +1284,7 @@ enum BuiltinFnId { |
| 1279 | BuiltinFnIdOpaqueType, | 1284 | BuiltinFnIdOpaqueType, |
| 1280 | BuiltinFnIdSetAlignStack, | 1285 | BuiltinFnIdSetAlignStack, |
| 1281 | BuiltinFnIdArgType, | 1286 | BuiltinFnIdArgType, |
| 1287 | BuiltinFnIdExport, | ||
| 1282 | }; | 1288 | }; |
| 1283 | 1289 | ||
| 1284 | struct BuiltinFnEntry { | 1290 | struct BuiltinFnEntry { |
| ... | @@ -1425,7 +1431,7 @@ struct CodeGen { | ... | @@ -1425,7 +1431,7 @@ struct CodeGen { |
| 1425 | HashMap<GenericFnTypeId *, FnTableEntry *, generic_fn_type_id_hash, generic_fn_type_id_eql> generic_table; | 1431 | HashMap<GenericFnTypeId *, FnTableEntry *, generic_fn_type_id_hash, generic_fn_type_id_eql> generic_table; |
| 1426 | HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table; | 1432 | HashMap<Scope *, IrInstruction *, fn_eval_hash, fn_eval_eql> memoized_fn_eval_table; |
| 1427 | HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table; | 1433 | 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; |
| 1429 | HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes; | 1435 | HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes; |
| 1430 | 1436 | ||
| 1431 | 1437 | ||
| ... | @@ -1886,8 +1892,6 @@ enum IrInstructionId { | ... | @@ -1886,8 +1892,6 @@ enum IrInstructionId { |
| 1886 | IrInstructionIdCheckStatementIsVoid, | 1892 | IrInstructionIdCheckStatementIsVoid, |
| 1887 | IrInstructionIdTypeName, | 1893 | IrInstructionIdTypeName, |
| 1888 | IrInstructionIdCanImplicitCast, | 1894 | IrInstructionIdCanImplicitCast, |
| 1889 | IrInstructionIdSetGlobalSection, | ||
| 1890 | IrInstructionIdSetGlobalLinkage, | ||
| 1891 | IrInstructionIdDeclRef, | 1895 | IrInstructionIdDeclRef, |
| 1892 | IrInstructionIdPanic, | 1896 | IrInstructionIdPanic, |
| 1893 | IrInstructionIdTagName, | 1897 | IrInstructionIdTagName, |
| ... | @@ -1901,6 +1905,7 @@ enum IrInstructionId { | ... | @@ -1901,6 +1905,7 @@ enum IrInstructionId { |
| 1901 | IrInstructionIdOpaqueType, | 1905 | IrInstructionIdOpaqueType, |
| 1902 | IrInstructionIdSetAlignStack, | 1906 | IrInstructionIdSetAlignStack, |
| 1903 | IrInstructionIdArgType, | 1907 | IrInstructionIdArgType, |
| 1908 | IrInstructionIdExport, | ||
| 1904 | }; | 1909 | }; |
| 1905 | 1910 | ||
| 1906 | struct IrInstruction { | 1911 | struct IrInstruction { |
| ... | @@ -2626,20 +2631,6 @@ struct IrInstructionCanImplicitCast { | ... | @@ -2626,20 +2631,6 @@ struct IrInstructionCanImplicitCast { |
| 2626 | IrInstruction *target_value; | 2631 | IrInstruction *target_value; |
| 2627 | }; | 2632 | }; |
| 2628 | 2633 | ||
| 2629 | struct IrInstructionSetGlobalSection { | ||
| 2630 | IrInstruction base; | ||
| 2631 | |||
| 2632 | Tld *tld; | ||
| 2633 | IrInstruction *value; | ||
| 2634 | }; | ||
| 2635 | |||
| 2636 | struct IrInstructionSetGlobalLinkage { | ||
| 2637 | IrInstruction base; | ||
| 2638 | |||
| 2639 | Tld *tld; | ||
| 2640 | IrInstruction *value; | ||
| 2641 | }; | ||
| 2642 | |||
| 2643 | struct IrInstructionDeclRef { | 2634 | struct IrInstructionDeclRef { |
| 2644 | IrInstruction base; | 2635 | IrInstruction base; |
| 2645 | 2636 | ||
| ... | @@ -2728,6 +2719,14 @@ struct IrInstructionArgType { | ... | @@ -2728,6 +2719,14 @@ struct IrInstructionArgType { |
| 2728 | IrInstruction *arg_index; | 2719 | IrInstruction *arg_index; |
| 2729 | }; | 2720 | }; |
| 2730 | 2721 | ||
| 2722 | struct IrInstructionExport { | ||
| 2723 | IrInstruction base; | ||
| 2724 | |||
| 2725 | IrInstruction *name; | ||
| 2726 | IrInstruction *linkage; | ||
| 2727 | IrInstruction *target; | ||
| 2728 | }; | ||
| 2729 | |||
| 2731 | static const size_t slice_ptr_index = 0; | 2730 | static const size_t slice_ptr_index = 0; |
| 2732 | static const size_t slice_len_index = 1; | 2731 | static const size_t slice_len_index = 1; |
| 2733 | 2732 |
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 | ... | @@ -1062,7 +1062,7 @@ void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_cou |
| 1062 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; | 1062 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; |
| 1063 | 1063 | ||
| 1064 | if (fn_proto->cc == CallingConventionUnspecified) { | 1064 | if (fn_proto->cc == CallingConventionUnspecified) { |
| 1065 | bool extern_abi = fn_proto->is_extern || (fn_proto->visib_mod == VisibModExport); | 1065 | bool extern_abi = fn_proto->is_extern || fn_proto->is_export; |
| 1066 | fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified; | 1066 | fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified; |
| 1067 | } else { | 1067 | } else { |
| 1068 | fn_type_id->cc = fn_proto->cc; | 1068 | fn_type_id->cc = fn_proto->cc; |
| ... | @@ -1093,6 +1093,38 @@ static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_ | ... | @@ -1093,6 +1093,38 @@ static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_ |
| 1093 | return true; | 1093 | return true; |
| 1094 | } | 1094 | } |
| 1095 | 1095 | ||
| 1096 | static 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 | |||
| 1096 | static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) { | 1128 | static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) { |
| 1097 | assert(proto_node->type == NodeTypeFnProto); | 1129 | assert(proto_node->type == NodeTypeFnProto); |
| 1098 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; | 1130 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; |
| ... | @@ -2472,7 +2504,7 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) { | ... | @@ -2472,7 +2504,7 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) { |
| 2472 | buf_append_buf(buf, tld->name); | 2504 | buf_append_buf(buf, tld->name); |
| 2473 | } | 2505 | } |
| 2474 | 2506 | ||
| 2475 | FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) { | 2507 | FnTableEntry *create_fn_raw(FnInline inline_value) { |
| 2476 | FnTableEntry *fn_entry = allocate<FnTableEntry>(1); | 2508 | FnTableEntry *fn_entry = allocate<FnTableEntry>(1); |
| 2477 | 2509 | ||
| 2478 | fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc; | 2510 | fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc; |
| ... | @@ -2480,7 +2512,6 @@ FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) { | ... | @@ -2480,7 +2512,6 @@ FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) { |
| 2480 | fn_entry->analyzed_executable.fn_entry = fn_entry; | 2512 | fn_entry->analyzed_executable.fn_entry = fn_entry; |
| 2481 | fn_entry->ir_executable.fn_entry = fn_entry; | 2513 | fn_entry->ir_executable.fn_entry = fn_entry; |
| 2482 | fn_entry->fn_inline = inline_value; | 2514 | fn_entry->fn_inline = inline_value; |
| 2483 | fn_entry->linkage = linkage; | ||
| 2484 | 2515 | ||
| 2485 | return fn_entry; | 2516 | return fn_entry; |
| 2486 | } | 2517 | } |
| ... | @@ -2490,9 +2521,7 @@ FnTableEntry *create_fn(AstNode *proto_node) { | ... | @@ -2490,9 +2521,7 @@ FnTableEntry *create_fn(AstNode *proto_node) { |
| 2490 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; | 2521 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; |
| 2491 | 2522 | ||
| 2492 | FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto; | 2523 | FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto; |
| 2493 | GlobalLinkageId linkage = (fn_proto->visib_mod == VisibModExport || proto_node->data.fn_proto.is_extern) ? | 2524 | FnTableEntry *fn_entry = create_fn_raw(inline_value); |
| 2494 | GlobalLinkageIdStrong : GlobalLinkageIdInternal; | ||
| 2495 | FnTableEntry *fn_entry = create_fn_raw(inline_value, linkage); | ||
| 2496 | 2525 | ||
| 2497 | fn_entry->proto_node = proto_node; | 2526 | fn_entry->proto_node = proto_node; |
| 2498 | fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr : | 2527 | fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr : |
| ... | @@ -2548,6 +2577,34 @@ TypeTableEntry *get_test_fn_type(CodeGen *g) { | ... | @@ -2548,6 +2577,34 @@ TypeTableEntry *get_test_fn_type(CodeGen *g) { |
| 2548 | return g->test_fn_type; | 2577 | return g->test_fn_type; |
| 2549 | } | 2578 | } |
| 2550 | 2579 | ||
| 2580 | void 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 | |||
| 2551 | static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | 2608 | static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2552 | ImportTableEntry *import = tld_fn->base.import; | 2609 | ImportTableEntry *import = tld_fn->base.import; |
| 2553 | AstNode *source_node = tld_fn->base.source_node; | 2610 | AstNode *source_node = tld_fn->base.source_node; |
| ... | @@ -2559,6 +2616,11 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -2559,6 +2616,11 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2559 | FnTableEntry *fn_table_entry = create_fn(source_node); | 2616 | FnTableEntry *fn_table_entry = create_fn(source_node); |
| 2560 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); | 2617 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); |
| 2561 | 2618 | ||
| 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 | |||
| 2562 | tld_fn->fn_entry = fn_table_entry; | 2624 | tld_fn->fn_entry = fn_table_entry; |
| 2563 | 2625 | ||
| 2564 | if (fn_table_entry->body_node) { | 2626 | if (fn_table_entry->body_node) { |
| ... | @@ -2572,7 +2634,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -2572,7 +2634,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2572 | add_node_error(g, param_node, buf_sprintf("missing parameter name")); | 2634 | add_node_error(g, param_node, buf_sprintf("missing parameter name")); |
| 2573 | } | 2635 | } |
| 2574 | } | 2636 | } |
| 2575 | } else if (fn_table_entry->linkage != GlobalLinkageIdInternal) { | 2637 | } else { |
| 2576 | g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base); | 2638 | g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base); |
| 2577 | } | 2639 | } |
| 2578 | 2640 | ||
| ... | @@ -2580,6 +2642,15 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -2580,6 +2642,15 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2580 | 2642 | ||
| 2581 | fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope); | 2643 | fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope); |
| 2582 | 2644 | ||
| 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 | |||
| 2583 | if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) { | 2654 | if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) { |
| 2584 | tld_fn->base.resolution = TldResolutionInvalid; | 2655 | tld_fn->base.resolution = TldResolutionInvalid; |
| 2585 | return; | 2656 | return; |
| ... | @@ -2594,15 +2665,12 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -2594,15 +2665,12 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2594 | { | 2665 | { |
| 2595 | if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) { | 2666 | if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) { |
| 2596 | g->main_fn = fn_table_entry; | 2667 | g->main_fn = fn_table_entry; |
| 2597 | 2668 | TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); | |
| 2598 | if (tld_fn->base.visib_mod != VisibModExport) { | 2669 | TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; |
| 2599 | TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); | 2670 | if (actual_return_type != err_void) { |
| 2600 | TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; | 2671 | add_node_error(g, fn_proto->return_type, |
| 2601 | if (actual_return_type != err_void) { | 2672 | buf_sprintf("expected return type of main to be '%%void', instead is '%s'", |
| 2602 | add_node_error(g, fn_proto->return_type, | 2673 | buf_ptr(&actual_return_type->name))); |
| 2603 | buf_sprintf("expected return type of main to be '%%void', instead is '%s'", | ||
| 2604 | buf_ptr(&actual_return_type->name))); | ||
| 2605 | } | ||
| 2606 | } | 2674 | } |
| 2607 | } else if ((import->package == g->panic_package || g->have_pub_panic) && | 2675 | } else if ((import->package == g->panic_package || g->have_pub_panic) && |
| 2608 | buf_eql_str(&fn_table_entry->symbol_name, "panic")) | 2676 | buf_eql_str(&fn_table_entry->symbol_name, "panic")) |
| ... | @@ -2613,7 +2681,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -2613,7 +2681,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2613 | } | 2681 | } |
| 2614 | } | 2682 | } |
| 2615 | } else if (source_node->type == NodeTypeTestDecl) { | 2683 | } 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); |
| 2617 | 2685 | ||
| 2618 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); | 2686 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); |
| 2619 | 2687 | ||
| ... | @@ -2640,17 +2708,23 @@ static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) { | ... | @@ -2640,17 +2708,23 @@ static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) { |
| 2640 | } | 2708 | } |
| 2641 | 2709 | ||
| 2642 | static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { | 2710 | static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { |
| 2643 | if (tld->visib_mod == VisibModExport) { | 2711 | bool is_export = false; |
| 2644 | g->resolve_queue.append(tld); | 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; | ||
| 2645 | } | 2718 | } |
| 2719 | if (is_export) { | ||
| 2720 | g->resolve_queue.append(tld); | ||
| 2646 | 2721 | ||
| 2647 | if (tld->visib_mod == VisibModExport) { | 2722 | auto entry = g->exported_symbol_names.put_unique(tld->name, tld->source_node); |
| 2648 | auto entry = g->exported_symbol_names.put_unique(tld->name, tld); | ||
| 2649 | if (entry) { | 2723 | if (entry) { |
| 2650 | Tld *other_tld = entry->value; | 2724 | AstNode *other_source_node = entry->value; |
| 2651 | ErrorMsg *msg = add_node_error(g, tld->source_node, | 2725 | ErrorMsg *msg = add_node_error(g, tld->source_node, |
| 2652 | buf_sprintf("exported symbol collision: '%s'", buf_ptr(tld->name))); | 2726 | 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")); |
| 2654 | } | 2728 | } |
| 2655 | } | 2729 | } |
| 2656 | 2730 | ||
| ... | @@ -2729,7 +2803,6 @@ static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_s | ... | @@ -2729,7 +2803,6 @@ static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_s |
| 2729 | g->resolve_queue.append(&tld_comptime->base); | 2803 | g->resolve_queue.append(&tld_comptime->base); |
| 2730 | } | 2804 | } |
| 2731 | 2805 | ||
| 2732 | |||
| 2733 | void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node, | 2806 | void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node, |
| 2734 | Scope *parent_scope) | 2807 | Scope *parent_scope) |
| 2735 | { | 2808 | { |
| ... | @@ -2985,8 +3058,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | ... | @@ -2985,8 +3058,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 2985 | AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration; | 3058 | AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration; |
| 2986 | 3059 | ||
| 2987 | bool is_const = var_decl->is_const; | 3060 | bool is_const = var_decl->is_const; |
| 2988 | bool is_export = (tld_var->base.visib_mod == VisibModExport); | ||
| 2989 | bool is_extern = var_decl->is_extern; | 3061 | bool is_extern = var_decl->is_extern; |
| 3062 | bool is_export = var_decl->is_export; | ||
| 2990 | 3063 | ||
| 2991 | TypeTableEntry *explicit_type = nullptr; | 3064 | TypeTableEntry *explicit_type = nullptr; |
| 2992 | if (var_decl->type) { | 3065 | if (var_decl->type) { |
| ... | @@ -2994,9 +3067,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | ... | @@ -2994,9 +3067,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 2994 | explicit_type = validate_var_type(g, var_decl->type, proposed_type); | 3067 | explicit_type = validate_var_type(g, var_decl->type, proposed_type); |
| 2995 | } | 3068 | } |
| 2996 | 3069 | ||
| 2997 | if (is_export && is_extern) { | 3070 | assert(!is_export || !is_extern); |
| 2998 | add_node_error(g, source_node, buf_sprintf("variable is both export and extern")); | ||
| 2999 | } | ||
| 3000 | 3071 | ||
| 3001 | VarLinkage linkage; | 3072 | VarLinkage linkage; |
| 3002 | if (is_export) { | 3073 | if (is_export) { |
| ... | @@ -3007,7 +3078,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | ... | @@ -3007,7 +3078,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 3007 | linkage = VarLinkageInternal; | 3078 | linkage = VarLinkageInternal; |
| 3008 | } | 3079 | } |
| 3009 | 3080 | ||
| 3010 | |||
| 3011 | IrInstruction *init_value = nullptr; | 3081 | IrInstruction *init_value = nullptr; |
| 3012 | 3082 | ||
| 3013 | // TODO more validation for types that can't be used for export/extern variables | 3083 | // 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) { | ... | @@ -3056,6 +3126,15 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 3056 | } | 3126 | } |
| 3057 | } | 3127 | } |
| 3058 | 3128 | ||
| 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 | |||
| 3059 | g->global_vars.append(tld_var); | 3138 | g->global_vars.append(tld_var); |
| 3060 | } | 3139 | } |
| 3061 | 3140 | ||
| ... | @@ -3724,8 +3803,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a | ... | @@ -3724,8 +3803,10 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a |
| 3724 | Buf *proto_name = proto_node->data.fn_proto.name; | 3803 | Buf *proto_name = proto_node->data.fn_proto.name; |
| 3725 | 3804 | ||
| 3726 | bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub); | 3805 | 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); | ||
| 3727 | 3808 | ||
| 3728 | if (is_pub) { | 3809 | if (is_pub && ok_cc) { |
| 3729 | if (buf_eql_str(proto_name, "main")) { | 3810 | if (buf_eql_str(proto_name, "main")) { |
| 3730 | g->have_pub_main = true; | 3811 | g->have_pub_main = true; |
| 3731 | g->windows_subsystem_windows = false; | 3812 | g->windows_subsystem_windows = false; |
| ... | @@ -3733,28 +3814,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a | ... | @@ -3733,28 +3814,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a |
| 3733 | } else if (buf_eql_str(proto_name, "panic")) { | 3814 | } else if (buf_eql_str(proto_name, "panic")) { |
| 3734 | g->have_pub_panic = true; | 3815 | g->have_pub_panic = true; |
| 3735 | } | 3816 | } |
| 3736 | } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && buf_eql_str(proto_name, "main") && | ||
| 3737 | g->libc_link_lib != nullptr) | ||
| 3738 | { | ||
| 3739 | g->have_c_main = true; | ||
| 3740 | g->windows_subsystem_windows = false; | ||
| 3741 | g->windows_subsystem_console = true; | ||
| 3742 | } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && buf_eql_str(proto_name, "WinMain") && | ||
| 3743 | g->zig_target.os == ZigLLVM_Win32) | ||
| 3744 | { | ||
| 3745 | g->have_winmain = true; | ||
| 3746 | g->windows_subsystem_windows = true; | ||
| 3747 | g->windows_subsystem_console = false; | ||
| 3748 | } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && | ||
| 3749 | buf_eql_str(proto_name, "WinMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32) | ||
| 3750 | { | ||
| 3751 | g->have_winmain_crt_startup = true; | ||
| 3752 | } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && | ||
| 3753 | buf_eql_str(proto_name, "DllMainCRTStartup") && g->zig_target.os == ZigLLVM_Win32) | ||
| 3754 | { | ||
| 3755 | g->have_dllmain_crt_startup = true; | ||
| 3756 | } | 3817 | } |
| 3757 | |||
| 3758 | } | 3818 | } |
| 3759 | } | 3819 | } |
| 3760 | 3820 | ||
| ... | @@ -5445,3 +5505,4 @@ uint32_t type_ptr_hash(const TypeTableEntry *ptr) { | ... | @@ -5445,3 +5505,4 @@ uint32_t type_ptr_hash(const TypeTableEntry *ptr) { |
| 5445 | bool type_ptr_eql(const TypeTableEntry *a, const TypeTableEntry *b) { | 5505 | bool type_ptr_eql(const TypeTableEntry *a, const TypeTableEntry *b) { |
| 5446 | return a == b; | 5506 | return a == b; |
| 5447 | } | 5507 | } |
| 5508 |
src/analyze.hpp+3| ... | @@ -182,4 +182,7 @@ uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry); | ... | @@ -182,4 +182,7 @@ uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry); |
| 182 | TypeTableEntry *get_align_amt_type(CodeGen *g); | 182 | TypeTableEntry *get_align_amt_type(CodeGen *g); |
| 183 | PackageTableEntry *new_anonymous_package(void); | 183 | PackageTableEntry *new_anonymous_package(void); |
| 184 | 184 | ||
| 185 | Buf *const_value_to_buffer(ConstExprValue *const_val); | ||
| 186 | void add_fn_export(CodeGen *g, FnTableEntry *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc); | ||
| 187 | |||
| 185 | #endif | 188 | #endif |
src/ast_render.cpp+26-2| ... | @@ -78,7 +78,6 @@ static const char *visib_mod_string(VisibMod mod) { | ... | @@ -78,7 +78,6 @@ static const char *visib_mod_string(VisibMod mod) { |
| 78 | switch (mod) { | 78 | switch (mod) { |
| 79 | case VisibModPub: return "pub "; | 79 | case VisibModPub: return "pub "; |
| 80 | case VisibModPrivate: return ""; | 80 | case VisibModPrivate: return ""; |
| 81 | case VisibModExport: return "export "; | ||
| 82 | } | 81 | } |
| 83 | zig_unreachable(); | 82 | zig_unreachable(); |
| 84 | } | 83 | } |
| ... | @@ -112,6 +111,10 @@ static const char *extern_string(bool is_extern) { | ... | @@ -112,6 +111,10 @@ static const char *extern_string(bool is_extern) { |
| 112 | return is_extern ? "extern " : ""; | 111 | return is_extern ? "extern " : ""; |
| 113 | } | 112 | } |
| 114 | 113 | ||
| 114 | static const char *export_string(bool is_export) { | ||
| 115 | return is_export ? "export " : ""; | ||
| 116 | } | ||
| 117 | |||
| 115 | //static const char *calling_convention_string(CallingConvention cc) { | 118 | //static const char *calling_convention_string(CallingConvention cc) { |
| 116 | // switch (cc) { | 119 | // switch (cc) { |
| 117 | // case CallingConventionUnspecified: return ""; | 120 | // case CallingConventionUnspecified: return ""; |
| ... | @@ -411,8 +414,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { | ... | @@ -411,8 +414,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 411 | { | 414 | { |
| 412 | const char *pub_str = visib_mod_string(node->data.fn_proto.visib_mod); | 415 | const char *pub_str = visib_mod_string(node->data.fn_proto.visib_mod); |
| 413 | const char *extern_str = extern_string(node->data.fn_proto.is_extern); | 416 | 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); | ||
| 414 | const char *inline_str = inline_string(node->data.fn_proto.is_inline); | 418 | 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); |
| 416 | if (node->data.fn_proto.name != nullptr) { | 420 | if (node->data.fn_proto.name != nullptr) { |
| 417 | fprintf(ar->f, " "); | 421 | fprintf(ar->f, " "); |
| 418 | print_symbol(ar, node->data.fn_proto.name); | 422 | print_symbol(ar, node->data.fn_proto.name); |
| ... | @@ -440,6 +444,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { | ... | @@ -440,6 +444,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 440 | } | 444 | } |
| 441 | } | 445 | } |
| 442 | fprintf(ar->f, ")"); | 446 | 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 | } | ||
| 443 | 457 | ||
| 444 | AstNode *return_type_node = node->data.fn_proto.return_type; | 458 | AstNode *return_type_node = node->data.fn_proto.return_type; |
| 445 | if (return_type_node != nullptr) { | 459 | if (return_type_node != nullptr) { |
| ... | @@ -526,6 +540,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { | ... | @@ -526,6 +540,16 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 526 | fprintf(ar->f, ": "); | 540 | fprintf(ar->f, ": "); |
| 527 | render_node_grouped(ar, node->data.variable_declaration.type); | 541 | render_node_grouped(ar, node->data.variable_declaration.type); |
| 528 | } | 542 | } |
| 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 | } | ||
| 529 | if (node->data.variable_declaration.expr) { | 553 | if (node->data.variable_declaration.expr) { |
| 530 | fprintf(ar->f, " = "); | 554 | fprintf(ar->f, " = "); |
| 531 | render_node_grouped(ar, node->data.variable_declaration.expr); | 555 | 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) { | ... | @@ -391,24 +391,51 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) { |
| 391 | } | 391 | } |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | static 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 | |||
| 394 | static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { | 408 | static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 395 | if (fn_table_entry->llvm_value) | 409 | if (fn_table_entry->llvm_value) |
| 396 | return fn_table_entry->llvm_value; | 410 | return fn_table_entry->llvm_value; |
| 397 | 411 | ||
| 398 | bool external_linkage = (fn_table_entry->linkage != GlobalLinkageIdInternal); | 412 | Buf *unmangled_name = &fn_table_entry->symbol_name; |
| 399 | Buf *symbol_name = get_mangled_name(g, &fn_table_entry->symbol_name, external_linkage); | 413 | Buf *symbol_name; |
| 414 | GlobalLinkageId linkage; | ||
| 415 | if (fn_table_entry->body_node == nullptr) { | ||
| 416 | symbol_name = unmangled_name; | ||
| 417 | linkage = GlobalLinkageIdStrong; | ||
| 418 | } else if (fn_table_entry->export_list.length == 0) { | ||
| 419 | symbol_name = get_mangled_name(g, unmangled_name, false); | ||
| 420 | linkage = GlobalLinkageIdInternal; | ||
| 421 | } else { | ||
| 422 | FnExport *fn_export = &fn_table_entry->export_list.items[0]; | ||
| 423 | symbol_name = &fn_export->name; | ||
| 424 | linkage = fn_export->linkage; | ||
| 425 | } | ||
| 400 | 426 | ||
| 427 | bool external_linkage = linkage != GlobalLinkageIdInternal; | ||
| 401 | if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall && external_linkage && | 428 | if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall && external_linkage && |
| 402 | g->zig_target.arch.arch == ZigLLVM_x86) | 429 | g->zig_target.arch.arch == ZigLLVM_x86) |
| 403 | { | 430 | { |
| 404 | // prevent name mangling | 431 | // prevent llvm name mangling |
| 405 | symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name)); | 432 | symbol_name = buf_sprintf("\x01_%s", buf_ptr(symbol_name)); |
| 406 | } | 433 | } |
| 407 | 434 | ||
| 408 | 435 | ||
| 409 | TypeTableEntry *fn_type = fn_table_entry->type_entry; | 436 | TypeTableEntry *fn_type = fn_table_entry->type_entry; |
| 410 | LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref; | 437 | LLVMTypeRef fn_llvm_type = fn_type->data.fn.raw_type_ref; |
| 411 | if (external_linkage && fn_table_entry->body_node == nullptr) { | 438 | if (fn_table_entry->body_node == nullptr) { |
| 412 | LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name)); | 439 | LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name)); |
| 413 | if (existing_llvm_fn) { | 440 | if (existing_llvm_fn) { |
| 414 | fn_table_entry->llvm_value = LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0)); | 441 | fn_table_entry->llvm_value = LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0)); |
| ... | @@ -418,6 +445,12 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { | ... | @@ -418,6 +445,12 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 418 | } | 445 | } |
| 419 | } else { | 446 | } else { |
| 420 | fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type); | 447 | fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type); |
| 448 | |||
| 449 | for (size_t i = 1; i < fn_table_entry->export_list.length; i += 1) { | ||
| 450 | FnExport *fn_export = &fn_table_entry->export_list.items[i]; | ||
| 451 | LLVMAddAlias(g->module, LLVMTypeOf(fn_table_entry->llvm_value), | ||
| 452 | fn_table_entry->llvm_value, buf_ptr(&fn_export->name)); | ||
| 453 | } | ||
| 421 | } | 454 | } |
| 422 | fn_table_entry->llvm_name = LLVMGetValueName(fn_table_entry->llvm_value); | 455 | fn_table_entry->llvm_name = LLVMGetValueName(fn_table_entry->llvm_value); |
| 423 | 456 | ||
| ... | @@ -445,20 +478,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { | ... | @@ -445,20 +478,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 445 | } | 478 | } |
| 446 | } | 479 | } |
| 447 | 480 | ||
| 448 | switch (fn_table_entry->linkage) { | 481 | LLVMSetLinkage(fn_table_entry->llvm_value, to_llvm_linkage(linkage)); |
| 449 | case GlobalLinkageIdInternal: | 482 | |
| 450 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMInternalLinkage); | 483 | if (linkage == GlobalLinkageIdInternal) { |
| 451 | LLVMSetUnnamedAddr(fn_table_entry->llvm_value, true); | 484 | LLVMSetUnnamedAddr(fn_table_entry->llvm_value, true); |
| 452 | break; | ||
| 453 | case GlobalLinkageIdStrong: | ||
| 454 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMExternalLinkage); | ||
| 455 | break; | ||
| 456 | case GlobalLinkageIdWeak: | ||
| 457 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakODRLinkage); | ||
| 458 | break; | ||
| 459 | case GlobalLinkageIdLinkOnce: | ||
| 460 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceODRLinkage); | ||
| 461 | break; | ||
| 462 | } | 485 | } |
| 463 | 486 | ||
| 464 | if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdUnreachable) { | 487 | if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdUnreachable) { |
| ... | @@ -565,7 +588,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) { | ... | @@ -565,7 +588,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) { |
| 565 | bool is_definition = fn_table_entry->body_node != nullptr; | 588 | bool is_definition = fn_table_entry->body_node != nullptr; |
| 566 | unsigned flags = 0; | 589 | unsigned flags = 0; |
| 567 | bool is_optimized = g->build_mode != BuildModeDebug; | 590 | bool is_optimized = g->build_mode != BuildModeDebug; |
| 568 | bool is_internal_linkage = (fn_table_entry->linkage == GlobalLinkageIdInternal); | 591 | bool is_internal_linkage = (fn_table_entry->body_node != nullptr && |
| 592 | fn_table_entry->export_list.length == 0); | ||
| 569 | ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder, | 593 | ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder, |
| 570 | get_di_scope(g, scope->parent), buf_ptr(&fn_table_entry->symbol_name), "", | 594 | get_di_scope(g, scope->parent), buf_ptr(&fn_table_entry->symbol_name), "", |
| 571 | import->di_file, line_number, | 595 | import->di_file, line_number, |
| ... | @@ -3487,8 +3511,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -3487,8 +3511,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 3487 | case IrInstructionIdCheckStatementIsVoid: | 3511 | case IrInstructionIdCheckStatementIsVoid: |
| 3488 | case IrInstructionIdTypeName: | 3512 | case IrInstructionIdTypeName: |
| 3489 | case IrInstructionIdCanImplicitCast: | 3513 | case IrInstructionIdCanImplicitCast: |
| 3490 | case IrInstructionIdSetGlobalSection: | ||
| 3491 | case IrInstructionIdSetGlobalLinkage: | ||
| 3492 | case IrInstructionIdDeclRef: | 3514 | case IrInstructionIdDeclRef: |
| 3493 | case IrInstructionIdSwitchVar: | 3515 | case IrInstructionIdSwitchVar: |
| 3494 | case IrInstructionIdOffsetOf: | 3516 | case IrInstructionIdOffsetOf: |
| ... | @@ -3499,6 +3521,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -3499,6 +3521,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 3499 | case IrInstructionIdSetAlignStack: | 3521 | case IrInstructionIdSetAlignStack: |
| 3500 | case IrInstructionIdArgType: | 3522 | case IrInstructionIdArgType: |
| 3501 | case IrInstructionIdTagType: | 3523 | case IrInstructionIdTagType: |
| 3524 | case IrInstructionIdExport: | ||
| 3502 | zig_unreachable(); | 3525 | zig_unreachable(); |
| 3503 | case IrInstructionIdReturn: | 3526 | case IrInstructionIdReturn: |
| 3504 | return ir_render_return(g, executable, (IrInstructionReturn *)instruction); | 3527 | return ir_render_return(g, executable, (IrInstructionReturn *)instruction); |
| ... | @@ -4969,8 +4992,6 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -4969,8 +4992,6 @@ static void define_builtin_fns(CodeGen *g) { |
| 4969 | create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int | 4992 | create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int |
| 4970 | create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2); | 4993 | create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2); |
| 4971 | create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2); | 4994 | create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2); |
| 4972 | create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2); | ||
| 4973 | create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2); | ||
| 4974 | create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1); | 4995 | create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1); |
| 4975 | create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2); | 4996 | create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2); |
| 4976 | create_builtin_fn(g, BuiltinFnIdBitCast, "bitCast", 2); | 4997 | create_builtin_fn(g, BuiltinFnIdBitCast, "bitCast", 2); |
| ... | @@ -4995,6 +5016,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -4995,6 +5016,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 4995 | create_builtin_fn(g, BuiltinFnIdOpaqueType, "OpaqueType", 0); | 5016 | create_builtin_fn(g, BuiltinFnIdOpaqueType, "OpaqueType", 0); |
| 4996 | create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1); | 5017 | create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1); |
| 4997 | create_builtin_fn(g, BuiltinFnIdArgType, "ArgType", 2); | 5018 | create_builtin_fn(g, BuiltinFnIdArgType, "ArgType", 2); |
| 5019 | create_builtin_fn(g, BuiltinFnIdExport, "export", 3); | ||
| 4998 | } | 5020 | } |
| 4999 | 5021 | ||
| 5000 | static const char *bool_to_str(bool b) { | 5022 | static const char *bool_to_str(bool b) { |
| ... | @@ -5433,6 +5455,27 @@ static void gen_root_source(CodeGen *g) { | ... | @@ -5433,6 +5455,27 @@ static void gen_root_source(CodeGen *g) { |
| 5433 | assert(g->root_out_name); | 5455 | assert(g->root_out_name); |
| 5434 | assert(g->out_type != OutTypeUnknown); | 5456 | assert(g->out_type != OutTypeUnknown); |
| 5435 | 5457 | ||
| 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 | |||
| 5436 | if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS && | 5479 | if (!g->is_test_build && g->zig_target.os != ZigLLVM_UnknownOS && |
| 5437 | !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && | 5480 | !g->have_c_main && !g->have_winmain && !g->have_winmain_crt_startup && |
| 5438 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) | 5481 | ((g->have_pub_main && g->out_type == OutTypeObj) || g->out_type == OutTypeExe)) |
| ... | @@ -5442,20 +5485,6 @@ static void gen_root_source(CodeGen *g) { | ... | @@ -5442,20 +5485,6 @@ static void gen_root_source(CodeGen *g) { |
| 5442 | if (g->zig_target.os == ZigLLVM_Win32 && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) { | 5485 | if (g->zig_target.os == ZigLLVM_Win32 && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) { |
| 5443 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig"); | 5486 | g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig"); |
| 5444 | } | 5487 | } |
| 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 | } | ||
| 5459 | 5488 | ||
| 5460 | if (!g->error_during_imports) { | 5489 | if (!g->error_during_imports) { |
| 5461 | semantic_analyze(g); | 5490 | semantic_analyze(g); |
| ... | @@ -5682,7 +5711,7 @@ static void gen_h_file(CodeGen *g) { | ... | @@ -5682,7 +5711,7 @@ static void gen_h_file(CodeGen *g) { |
| 5682 | for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) { | 5711 | for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) { |
| 5683 | FnTableEntry *fn_table_entry = g->fn_defs.at(fn_def_i); | 5712 | FnTableEntry *fn_table_entry = g->fn_defs.at(fn_def_i); |
| 5684 | 5713 | ||
| 5685 | if (fn_table_entry->linkage == GlobalLinkageIdInternal) | 5714 | if (fn_table_entry->export_list.length == 0) |
| 5686 | continue; | 5715 | continue; |
| 5687 | 5716 | ||
| 5688 | FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id; | 5717 | 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 *) { | ... | @@ -207,6 +207,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVar *) { |
| 207 | return IrInstructionIdDeclVar; | 207 | return IrInstructionIdDeclVar; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | static constexpr IrInstructionId ir_instruction_id(IrInstructionExport *) { | ||
| 211 | return IrInstructionIdExport; | ||
| 212 | } | ||
| 213 | |||
| 210 | static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) { | 214 | static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) { |
| 211 | return IrInstructionIdLoadPtr; | 215 | return IrInstructionIdLoadPtr; |
| 212 | } | 216 | } |
| ... | @@ -523,14 +527,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCanImplicitCast | ... | @@ -523,14 +527,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCanImplicitCast |
| 523 | return IrInstructionIdCanImplicitCast; | 527 | return IrInstructionIdCanImplicitCast; |
| 524 | } | 528 | } |
| 525 | 529 | ||
| 526 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalSection *) { | ||
| 527 | return IrInstructionIdSetGlobalSection; | ||
| 528 | } | ||
| 529 | |||
| 530 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalLinkage *) { | ||
| 531 | return IrInstructionIdSetGlobalLinkage; | ||
| 532 | } | ||
| 533 | |||
| 534 | static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) { | 530 | static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) { |
| 535 | return IrInstructionIdDeclRef; | 531 | return IrInstructionIdDeclRef; |
| 536 | } | 532 | } |
| ... | @@ -1205,6 +1201,24 @@ static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_ | ... | @@ -1205,6 +1201,24 @@ static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_ |
| 1205 | return new_instruction; | 1201 | return new_instruction; |
| 1206 | } | 1202 | } |
| 1207 | 1203 | ||
| 1204 | static 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 | |||
| 1208 | static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { | 1222 | static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { |
| 1209 | IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node); | 1223 | IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node); |
| 1210 | instruction->ptr = ptr; | 1224 | instruction->ptr = ptr; |
| ... | @@ -2159,32 +2173,6 @@ static IrInstruction *ir_build_can_implicit_cast(IrBuilder *irb, Scope *scope, A | ... | @@ -2159,32 +2173,6 @@ static IrInstruction *ir_build_can_implicit_cast(IrBuilder *irb, Scope *scope, A |
| 2159 | return &instruction->base; | 2173 | return &instruction->base; |
| 2160 | } | 2174 | } |
| 2161 | 2175 | ||
| 2162 | static 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 | |||
| 2175 | static 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 | |||
| 2188 | static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, | 2176 | static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2189 | Tld *tld, LVal lval) | 2177 | Tld *tld, LVal lval) |
| 2190 | { | 2178 | { |
| ... | @@ -2396,6 +2384,21 @@ static IrInstruction *ir_instruction_declvar_get_dep(IrInstructionDeclVar *instr | ... | @@ -2396,6 +2384,21 @@ static IrInstruction *ir_instruction_declvar_get_dep(IrInstructionDeclVar *instr |
| 2396 | return nullptr; | 2384 | return nullptr; |
| 2397 | } | 2385 | } |
| 2398 | 2386 | ||
| 2387 | static 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 | |||
| 2399 | static IrInstruction *ir_instruction_loadptr_get_dep(IrInstructionLoadPtr *instruction, size_t index) { | 2402 | static IrInstruction *ir_instruction_loadptr_get_dep(IrInstructionLoadPtr *instruction, size_t index) { |
| 2400 | switch (index) { | 2403 | switch (index) { |
| 2401 | case 0: return instruction->ptr; | 2404 | case 0: return instruction->ptr; |
| ... | @@ -2979,20 +2982,6 @@ static IrInstruction *ir_instruction_canimplicitcast_get_dep(IrInstructionCanImp | ... | @@ -2979,20 +2982,6 @@ static IrInstruction *ir_instruction_canimplicitcast_get_dep(IrInstructionCanImp |
| 2979 | } | 2982 | } |
| 2980 | } | 2983 | } |
| 2981 | 2984 | ||
| 2982 | static 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 | |||
| 2989 | static 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 | |||
| 2996 | static IrInstruction *ir_instruction_declref_get_dep(IrInstructionDeclRef *instruction, size_t index) { | 2985 | static IrInstruction *ir_instruction_declref_get_dep(IrInstructionDeclRef *instruction, size_t index) { |
| 2997 | return nullptr; | 2986 | return nullptr; |
| 2998 | } | 2987 | } |
| ... | @@ -3106,6 +3095,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t | ... | @@ -3106,6 +3095,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 3106 | return ir_instruction_binop_get_dep((IrInstructionBinOp *) instruction, index); | 3095 | return ir_instruction_binop_get_dep((IrInstructionBinOp *) instruction, index); |
| 3107 | case IrInstructionIdDeclVar: | 3096 | case IrInstructionIdDeclVar: |
| 3108 | return ir_instruction_declvar_get_dep((IrInstructionDeclVar *) instruction, index); | 3097 | return ir_instruction_declvar_get_dep((IrInstructionDeclVar *) instruction, index); |
| 3098 | case IrInstructionIdExport: | ||
| 3099 | return ir_instruction_export_get_dep((IrInstructionExport *) instruction, index); | ||
| 3109 | case IrInstructionIdLoadPtr: | 3100 | case IrInstructionIdLoadPtr: |
| 3110 | return ir_instruction_loadptr_get_dep((IrInstructionLoadPtr *) instruction, index); | 3101 | return ir_instruction_loadptr_get_dep((IrInstructionLoadPtr *) instruction, index); |
| 3111 | case IrInstructionIdStorePtr: | 3102 | case IrInstructionIdStorePtr: |
| ... | @@ -3264,10 +3255,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t | ... | @@ -3264,10 +3255,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 3264 | return ir_instruction_typename_get_dep((IrInstructionTypeName *) instruction, index); | 3255 | return ir_instruction_typename_get_dep((IrInstructionTypeName *) instruction, index); |
| 3265 | case IrInstructionIdCanImplicitCast: | 3256 | case IrInstructionIdCanImplicitCast: |
| 3266 | return ir_instruction_canimplicitcast_get_dep((IrInstructionCanImplicitCast *) instruction, index); | 3257 | return ir_instruction_canimplicitcast_get_dep((IrInstructionCanImplicitCast *) instruction, index); |
| 3267 | case IrInstructionIdSetGlobalSection: | ||
| 3268 | return ir_instruction_setglobalsection_get_dep((IrInstructionSetGlobalSection *) instruction, index); | ||
| 3269 | case IrInstructionIdSetGlobalLinkage: | ||
| 3270 | return ir_instruction_setgloballinkage_get_dep((IrInstructionSetGlobalLinkage *) instruction, index); | ||
| 3271 | case IrInstructionIdDeclRef: | 3258 | case IrInstructionIdDeclRef: |
| 3272 | return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index); | 3259 | return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index); |
| 3273 | case IrInstructionIdPanic: | 3260 | case IrInstructionIdPanic: |
| ... | @@ -4528,39 +4515,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4528,39 +4515,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4528 | 4515 | ||
| 4529 | return ir_build_can_implicit_cast(irb, scope, node, arg0_value, arg1_value); | 4516 | return ir_build_can_implicit_cast(irb, scope, node, arg0_value, arg1_value); |
| 4530 | } | 4517 | } |
| 4531 | case BuiltinFnIdSetGlobalSection: | ||
| 4532 | case BuiltinFnIdSetGlobalLinkage: | ||
| 4533 | { | ||
| 4534 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4535 | if (arg0_node->type != NodeTypeSymbol) { | ||
| 4536 | add_node_error(irb->codegen, arg0_node, buf_sprintf("expected identifier")); | ||
| 4537 | return irb->codegen->invalid_instruction; | ||
| 4538 | } | ||
| 4539 | Buf *variable_name = arg0_node->data.symbol_expr.symbol; | ||
| 4540 | Tld *tld = find_decl(irb->codegen, scope, variable_name); | ||
| 4541 | if (!tld) { | ||
| 4542 | add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", | ||
| 4543 | buf_ptr(variable_name))); | ||
| 4544 | return irb->codegen->invalid_instruction; | ||
| 4545 | } | ||
| 4546 | if (tld->id != TldIdVar && tld->id != TldIdFn) { | ||
| 4547 | add_node_error(irb->codegen, node, buf_sprintf("'%s' must be global variable or function", | ||
| 4548 | buf_ptr(variable_name))); | ||
| 4549 | return irb->codegen->invalid_instruction; | ||
| 4550 | } | ||
| 4551 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 4552 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 4553 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 4554 | return arg1_value; | ||
| 4555 | |||
| 4556 | if (builtin_fn->id == BuiltinFnIdSetGlobalSection) { | ||
| 4557 | return ir_build_set_global_section(irb, scope, node, tld, arg1_value); | ||
| 4558 | } else if (builtin_fn->id == BuiltinFnIdSetGlobalLinkage) { | ||
| 4559 | return ir_build_set_global_linkage(irb, scope, node, tld, arg1_value); | ||
| 4560 | } else { | ||
| 4561 | zig_unreachable(); | ||
| 4562 | } | ||
| 4563 | } | ||
| 4564 | case BuiltinFnIdPanic: | 4518 | case BuiltinFnIdPanic: |
| 4565 | { | 4519 | { |
| 4566 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 4520 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | @@ -4784,6 +4738,25 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4784,6 +4738,25 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4784 | 4738 | ||
| 4785 | return ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); | 4739 | return ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); |
| 4786 | } | 4740 | } |
| 4741 | case BuiltinFnIdExport: | ||
| 4742 | { | ||
| 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 | } | ||
| 4787 | } | 4760 | } |
| 4788 | zig_unreachable(); | 4761 | zig_unreachable(); |
| 4789 | } | 4762 | } |
| ... | @@ -5087,7 +5060,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -5087,7 +5060,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5087 | bool is_const = variable_declaration->is_const; | 5060 | bool is_const = variable_declaration->is_const; |
| 5088 | bool is_extern = variable_declaration->is_extern; | 5061 | bool is_extern = variable_declaration->is_extern; |
| 5089 | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, | 5062 | 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); |
| 5091 | VariableTableEntry *var = ir_create_var(irb, node, scope, variable_declaration->symbol, | 5064 | VariableTableEntry *var = ir_create_var(irb, node, scope, variable_declaration->symbol, |
| 5092 | is_const, is_const, is_shadowable, is_comptime); | 5065 | is_const, is_const, is_shadowable, is_comptime); |
| 5093 | // we detect IrInstructionIdDeclVar in gen_block to make sure the next node | 5066 | // 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 | ... | @@ -5106,6 +5079,11 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5106 | return align_value; | 5079 | return align_value; |
| 5107 | } | 5080 | } |
| 5108 | 5081 | ||
| 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 | |||
| 5109 | IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope); | 5087 | IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope); |
| 5110 | if (init_value == irb->codegen->invalid_instruction) | 5088 | if (init_value == irb->codegen->invalid_instruction) |
| 5111 | return init_value; | 5089 | return init_value; |
| ... | @@ -6355,6 +6333,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop | ... | @@ -6355,6 +6333,10 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 6355 | case NodeTypeSwitchRange: | 6333 | case NodeTypeSwitchRange: |
| 6356 | case NodeTypeStructField: | 6334 | case NodeTypeStructField: |
| 6357 | case NodeTypeLabel: | 6335 | case NodeTypeLabel: |
| 6336 | case NodeTypeFnDef: | ||
| 6337 | case NodeTypeFnDecl: | ||
| 6338 | case NodeTypeErrorValueDecl: | ||
| 6339 | case NodeTypeTestDecl: | ||
| 6358 | zig_unreachable(); | 6340 | zig_unreachable(); |
| 6359 | case NodeTypeBlock: | 6341 | case NodeTypeBlock: |
| 6360 | return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); | 6342 | 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 | ... | @@ -6436,14 +6418,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 6436 | return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval); | 6418 | return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval); |
| 6437 | case NodeTypeFnProto: | 6419 | case NodeTypeFnProto: |
| 6438 | return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval); | 6420 | return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval); |
| 6439 | case NodeTypeFnDef: | ||
| 6440 | zig_panic("TODO IR gen NodeTypeFnDef"); | ||
| 6441 | case NodeTypeFnDecl: | ||
| 6442 | zig_panic("TODO IR gen NodeTypeFnDecl"); | ||
| 6443 | case NodeTypeErrorValueDecl: | ||
| 6444 | zig_panic("TODO IR gen NodeTypeErrorValueDecl"); | ||
| 6445 | case NodeTypeTestDecl: | ||
| 6446 | zig_panic("TODO IR gen NodeTypeTestDecl"); | ||
| 6447 | } | 6421 | } |
| 6448 | zig_unreachable(); | 6422 | zig_unreachable(); |
| 6449 | } | 6423 | } |
| ... | @@ -10481,6 +10455,170 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -10481,6 +10455,170 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 10481 | return ira->codegen->builtin_types.entry_void; | 10455 | return ira->codegen->builtin_types.entry_void; |
| 10482 | } | 10456 | } |
| 10483 | 10457 | ||
| 10458 | static 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 | |||
| 10484 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, | 10622 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| 10485 | IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) | 10623 | IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) |
| 10486 | { | 10624 | { |
| ... | @@ -12399,102 +12537,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, | ... | @@ -12399,102 +12537,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, |
| 12399 | return ira->codegen->builtin_types.entry_type; | 12537 | return ira->codegen->builtin_types.entry_type; |
| 12400 | } | 12538 | } |
| 12401 | 12539 | ||
| 12402 | static 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 | |||
| 12459 | static 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 | |||
| 12498 | static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira, | 12540 | static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira, |
| 12499 | IrInstructionSetDebugSafety *set_debug_safety_instruction) | 12541 | IrInstructionSetDebugSafety *set_debug_safety_instruction) |
| 12500 | { | 12542 | { |
| ... | @@ -16165,10 +16207,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -16165,10 +16207,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 16165 | return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); | 16207 | return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); |
| 16166 | case IrInstructionIdPtrTypeChild: | 16208 | case IrInstructionIdPtrTypeChild: |
| 16167 | return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); | 16209 | return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); |
| 16168 | case IrInstructionIdSetGlobalSection: | ||
| 16169 | return ir_analyze_instruction_set_global_section(ira, (IrInstructionSetGlobalSection *)instruction); | ||
| 16170 | case IrInstructionIdSetGlobalLinkage: | ||
| 16171 | return ir_analyze_instruction_set_global_linkage(ira, (IrInstructionSetGlobalLinkage *)instruction); | ||
| 16172 | case IrInstructionIdSetDebugSafety: | 16210 | case IrInstructionIdSetDebugSafety: |
| 16173 | return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction); | 16211 | return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction); |
| 16174 | case IrInstructionIdSetFloatMode: | 16212 | case IrInstructionIdSetFloatMode: |
| ... | @@ -16311,6 +16349,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -16311,6 +16349,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 16311 | return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction); | 16349 | return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction); |
| 16312 | case IrInstructionIdTagType: | 16350 | case IrInstructionIdTagType: |
| 16313 | return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction); | 16351 | return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction); |
| 16352 | case IrInstructionIdExport: | ||
| 16353 | return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction); | ||
| 16314 | } | 16354 | } |
| 16315 | zig_unreachable(); | 16355 | zig_unreachable(); |
| 16316 | } | 16356 | } |
| ... | @@ -16418,12 +16458,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -16418,12 +16458,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 16418 | case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free | 16458 | case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free |
| 16419 | case IrInstructionIdCheckSwitchProngs: | 16459 | case IrInstructionIdCheckSwitchProngs: |
| 16420 | case IrInstructionIdCheckStatementIsVoid: | 16460 | case IrInstructionIdCheckStatementIsVoid: |
| 16421 | case IrInstructionIdSetGlobalSection: | ||
| 16422 | case IrInstructionIdSetGlobalLinkage: | ||
| 16423 | case IrInstructionIdPanic: | 16461 | case IrInstructionIdPanic: |
| 16424 | case IrInstructionIdSetEvalBranchQuota: | 16462 | case IrInstructionIdSetEvalBranchQuota: |
| 16425 | case IrInstructionIdPtrTypeOf: | 16463 | case IrInstructionIdPtrTypeOf: |
| 16426 | case IrInstructionIdSetAlignStack: | 16464 | case IrInstructionIdSetAlignStack: |
| 16465 | case IrInstructionIdExport: | ||
| 16427 | return true; | 16466 | return true; |
| 16428 | case IrInstructionIdPhi: | 16467 | case IrInstructionIdPhi: |
| 16429 | case IrInstructionIdUnOp: | 16468 | case IrInstructionIdUnOp: |
src/ir_print.cpp+21-19| ... | @@ -899,19 +899,6 @@ static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instructi | ... | @@ -899,19 +899,6 @@ static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instructi |
| 899 | ir_print_other_instruction(irp, instruction->child_type); | 899 | ir_print_other_instruction(irp, instruction->child_type); |
| 900 | } | 900 | } |
| 901 | 901 | ||
| 902 | static 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 | |||
| 908 | static 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 | |||
| 915 | static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) { | 902 | static void ir_print_decl_ref(IrPrint *irp, IrInstructionDeclRef *instruction) { |
| 916 | const char *ptr_str = instruction->lval.is_ptr ? "ptr " : ""; | 903 | const char *ptr_str = instruction->lval.is_ptr ? "ptr " : ""; |
| 917 | const char *const_str = instruction->lval.is_const ? "const " : ""; | 904 | const char *const_str = instruction->lval.is_const ? "const " : ""; |
| ... | @@ -991,6 +978,24 @@ static void ir_print_enum_tag_type(IrPrint *irp, IrInstructionTagType *instructi | ... | @@ -991,6 +978,24 @@ static void ir_print_enum_tag_type(IrPrint *irp, IrInstructionTagType *instructi |
| 991 | fprintf(irp->f, ")"); | 978 | fprintf(irp->f, ")"); |
| 992 | } | 979 | } |
| 993 | 980 | ||
| 981 | static 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 | |||
| 994 | 999 | ||
| 995 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | 1000 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 996 | ir_print_prefix(irp, instruction); | 1001 | ir_print_prefix(irp, instruction); |
| ... | @@ -1267,12 +1272,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1267,12 +1272,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1267 | case IrInstructionIdPtrTypeOf: | 1272 | case IrInstructionIdPtrTypeOf: |
| 1268 | ir_print_ptr_type_of(irp, (IrInstructionPtrTypeOf *)instruction); | 1273 | ir_print_ptr_type_of(irp, (IrInstructionPtrTypeOf *)instruction); |
| 1269 | break; | 1274 | break; |
| 1270 | case IrInstructionIdSetGlobalSection: | ||
| 1271 | ir_print_set_global_section(irp, (IrInstructionSetGlobalSection *)instruction); | ||
| 1272 | break; | ||
| 1273 | case IrInstructionIdSetGlobalLinkage: | ||
| 1274 | ir_print_set_global_linkage(irp, (IrInstructionSetGlobalLinkage *)instruction); | ||
| 1275 | break; | ||
| 1276 | case IrInstructionIdDeclRef: | 1275 | case IrInstructionIdDeclRef: |
| 1277 | ir_print_decl_ref(irp, (IrInstructionDeclRef *)instruction); | 1276 | ir_print_decl_ref(irp, (IrInstructionDeclRef *)instruction); |
| 1278 | break; | 1277 | break; |
| ... | @@ -1306,6 +1305,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1306,6 +1305,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1306 | case IrInstructionIdTagType: | 1305 | case IrInstructionIdTagType: |
| 1307 | ir_print_enum_tag_type(irp, (IrInstructionTagType *)instruction); | 1306 | ir_print_enum_tag_type(irp, (IrInstructionTagType *)instruction); |
| 1308 | break; | 1307 | break; |
| 1308 | case IrInstructionIdExport: | ||
| 1309 | ir_print_export(irp, (IrInstructionExport *)instruction); | ||
| 1310 | break; | ||
| 1309 | } | 1311 | } |
| 1310 | fprintf(irp->f, "\n"); | 1312 | fprintf(irp->f, "\n"); |
| 1311 | } | 1313 | } |
src/parser.cpp+114-53| ... | @@ -676,7 +676,7 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b | ... | @@ -676,7 +676,7 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b |
| 676 | } | 676 | } |
| 677 | 677 | ||
| 678 | /* | 678 | /* |
| 679 | PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl | 679 | PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl |
| 680 | KeywordLiteral = "true" | "false" | "null" | "continue" | "undefined" | "error" | "this" | "unreachable" | 680 | KeywordLiteral = "true" | "false" | "null" | "continue" | "undefined" | "error" | "this" | "unreachable" |
| 681 | */ | 681 | */ |
| 682 | static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) { | 682 | static 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 | ... | @@ -740,9 +740,21 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo |
| 740 | return node; | 740 | return node; |
| 741 | } else if (token->id == TokenIdAtSign) { | 741 | } else if (token->id == TokenIdAtSign) { |
| 742 | *token_index += 1; | 742 | *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 | |||
| 744 | AstNode *name_node = ast_create_node(pc, NodeTypeSymbol, name_tok); | 756 | 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; |
| 746 | 758 | ||
| 747 | AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, token); | 759 | AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, token); |
| 748 | node->data.fn_call_expr.fn_ref_expr = name_node; | 760 | 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 | ... | @@ -791,13 +803,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo |
| 791 | if (container_decl) | 803 | if (container_decl) |
| 792 | return container_decl; | 804 | return container_decl; |
| 793 | 805 | ||
| 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 | |||
| 801 | if (!mandatory) | 806 | if (!mandatory) |
| 802 | return nullptr; | 807 | return nullptr; |
| 803 | 808 | ||
| ... | @@ -1534,38 +1539,20 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) { | ... | @@ -1534,38 +1539,20 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) { |
| 1534 | } | 1539 | } |
| 1535 | 1540 | ||
| 1536 | /* | 1541 | /* |
| 1537 | VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") "=" Expression | 1542 | VariableDeclaration = ("var" | "const") Symbol option(":" TypeExpr) option("align" "(" Expression ")") "=" Expression |
| 1538 | */ | 1543 | */ |
| 1539 | static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *token_index, bool mandatory, | 1544 | static 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) |
| 1541 | { | 1546 | { |
| 1542 | Token *first_token = &pc->tokens->at(*token_index); | 1547 | Token *first_token = &pc->tokens->at(*token_index); |
| 1543 | Token *var_token; | 1548 | Token *var_token; |
| 1544 | 1549 | ||
| 1545 | bool is_const; | 1550 | bool is_const; |
| 1546 | bool is_comptime; | 1551 | if (first_token->id == TokenIdKeywordVar) { |
| 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; | ||
| 1564 | is_const = false; | 1552 | is_const = false; |
| 1565 | var_token = first_token; | 1553 | var_token = first_token; |
| 1566 | *token_index += 1; | 1554 | *token_index += 1; |
| 1567 | } else if (first_token->id == TokenIdKeywordConst) { | 1555 | } else if (first_token->id == TokenIdKeywordConst) { |
| 1568 | is_comptime = false; | ||
| 1569 | is_const = true; | 1556 | is_const = true; |
| 1570 | var_token = first_token; | 1557 | var_token = first_token; |
| 1571 | *token_index += 1; | 1558 | *token_index += 1; |
| ... | @@ -1577,7 +1564,8 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to | ... | @@ -1577,7 +1564,8 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to |
| 1577 | 1564 | ||
| 1578 | AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, var_token); | 1565 | AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, var_token); |
| 1579 | 1566 | ||
| 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; | ||
| 1581 | node->data.variable_declaration.is_const = is_const; | 1569 | node->data.variable_declaration.is_const = is_const; |
| 1582 | node->data.variable_declaration.visib_mod = visib_mod; | 1570 | node->data.variable_declaration.visib_mod = visib_mod; |
| 1583 | 1571 | ||
| ... | @@ -1600,6 +1588,14 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to | ... | @@ -1600,6 +1588,14 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to |
| 1600 | next_token = &pc->tokens->at(*token_index); | 1588 | next_token = &pc->tokens->at(*token_index); |
| 1601 | } | 1589 | } |
| 1602 | 1590 | ||
| 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 | |||
| 1603 | if (next_token->id == TokenIdEq) { | 1599 | if (next_token->id == TokenIdEq) { |
| 1604 | *token_index += 1; | 1600 | *token_index += 1; |
| 1605 | node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true); | 1601 | 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 | ... | @@ -1612,6 +1608,50 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to |
| 1612 | return node; | 1608 | return node; |
| 1613 | } | 1609 | } |
| 1614 | 1610 | ||
| 1611 | /* | ||
| 1612 | GlobalVarDecl = option("export") VariableDeclaration ";" | ||
| 1613 | */ | ||
| 1614 | static 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 | /* | ||
| 1634 | LocalVarDecl = option("comptime") VariableDeclaration | ||
| 1635 | */ | ||
| 1636 | static 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 | |||
| 1615 | /* | 1655 | /* |
| 1616 | BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression | 1656 | BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression |
| 1617 | */ | 1657 | */ |
| ... | @@ -2144,7 +2184,7 @@ static bool statement_terminates_without_semicolon(AstNode *node) { | ... | @@ -2144,7 +2184,7 @@ static bool statement_terminates_without_semicolon(AstNode *node) { |
| 2144 | 2184 | ||
| 2145 | /* | 2185 | /* |
| 2146 | Block = "{" many(Statement) option(Expression) "}" | 2186 | Block = "{" many(Statement) option(Expression) "}" |
| 2147 | Statement = Label | VariableDeclaration ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";" | 2187 | Statement = Label | VariableDeclaration ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";" | ExportDecl |
| 2148 | */ | 2188 | */ |
| 2149 | static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mandatory) { | 2189 | static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 2150 | Token *last_token = &pc->tokens->at(*token_index); | 2190 | 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 | ... | @@ -2163,7 +2203,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand |
| 2163 | for (;;) { | 2203 | for (;;) { |
| 2164 | AstNode *statement_node = ast_parse_label(pc, token_index, false); | 2204 | AstNode *statement_node = ast_parse_label(pc, token_index, false); |
| 2165 | if (!statement_node) | 2205 | 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); |
| 2167 | if (!statement_node) | 2207 | if (!statement_node) |
| 2168 | statement_node = ast_parse_defer_expr(pc, token_index); | 2208 | statement_node = ast_parse_defer_expr(pc, token_index); |
| 2169 | if (!statement_node) | 2209 | if (!statement_node) |
| ... | @@ -2205,13 +2245,14 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand | ... | @@ -2205,13 +2245,14 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand |
| 2205 | } | 2245 | } |
| 2206 | 2246 | ||
| 2207 | /* | 2247 | /* |
| 2208 | FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("->" TypeExpr) | 2248 | FnProto = option("coldcc" | "nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("-&gt;" TypeExpr) |
| 2209 | */ | 2249 | */ |
| 2210 | static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) { | 2250 | static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) { |
| 2211 | Token *first_token = &pc->tokens->at(*token_index); | 2251 | Token *first_token = &pc->tokens->at(*token_index); |
| 2212 | Token *fn_token; | 2252 | Token *fn_token; |
| 2213 | 2253 | ||
| 2214 | CallingConvention cc; | 2254 | CallingConvention cc; |
| 2255 | bool is_extern = false; | ||
| 2215 | if (first_token->id == TokenIdKeywordColdCC) { | 2256 | if (first_token->id == TokenIdKeywordColdCC) { |
| 2216 | *token_index += 1; | 2257 | *token_index += 1; |
| 2217 | fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn); | 2258 | 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 | ... | @@ -2224,6 +2265,21 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m |
| 2224 | *token_index += 1; | 2265 | *token_index += 1; |
| 2225 | fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn); | 2266 | fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn); |
| 2226 | cc = CallingConventionStdcall; | 2267 | 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; | ||
| 2227 | } else if (first_token->id == TokenIdKeywordFn) { | 2283 | } else if (first_token->id == TokenIdKeywordFn) { |
| 2228 | fn_token = first_token; | 2284 | fn_token = first_token; |
| 2229 | *token_index += 1; | 2285 | *token_index += 1; |
| ... | @@ -2238,6 +2294,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m | ... | @@ -2238,6 +2294,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m |
| 2238 | AstNode *node = ast_create_node(pc, NodeTypeFnProto, fn_token); | 2294 | AstNode *node = ast_create_node(pc, NodeTypeFnProto, fn_token); |
| 2239 | node->data.fn_proto.visib_mod = visib_mod; | 2295 | node->data.fn_proto.visib_mod = visib_mod; |
| 2240 | node->data.fn_proto.cc = cc; | 2296 | node->data.fn_proto.cc = cc; |
| 2297 | node->data.fn_proto.is_extern = is_extern; | ||
| 2241 | 2298 | ||
| 2242 | Token *fn_name = &pc->tokens->at(*token_index); | 2299 | Token *fn_name = &pc->tokens->at(*token_index); |
| 2243 | 2300 | ||
| ... | @@ -2259,6 +2316,14 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m | ... | @@ -2259,6 +2316,14 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m |
| 2259 | ast_eat_token(pc, token_index, TokenIdRParen); | 2316 | ast_eat_token(pc, token_index, TokenIdRParen); |
| 2260 | next_token = &pc->tokens->at(*token_index); | 2317 | next_token = &pc->tokens->at(*token_index); |
| 2261 | } | 2318 | } |
| 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 | } | ||
| 2262 | if (next_token->id == TokenIdArrow) { | 2327 | if (next_token->id == TokenIdArrow) { |
| 2263 | *token_index += 1; | 2328 | *token_index += 1; |
| 2264 | node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, false); | 2329 | 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 | ... | @@ -2270,35 +2335,35 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m |
| 2270 | } | 2335 | } |
| 2271 | 2336 | ||
| 2272 | /* | 2337 | /* |
| 2273 | FnDef = option("inline" | "extern") FnProto Block | 2338 | FnDef = option("inline" | "export") FnProto Block |
| 2274 | */ | 2339 | */ |
| 2275 | static AstNode *ast_parse_fn_def(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) { | 2340 | static AstNode *ast_parse_fn_def(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) { |
| 2276 | Token *first_token = &pc->tokens->at(*token_index); | 2341 | Token *first_token = &pc->tokens->at(*token_index); |
| 2277 | bool is_inline; | 2342 | bool is_inline; |
| 2278 | bool is_extern; | 2343 | bool is_export; |
| 2279 | if (first_token->id == TokenIdKeywordInline) { | 2344 | if (first_token->id == TokenIdKeywordInline) { |
| 2280 | *token_index += 1; | 2345 | *token_index += 1; |
| 2281 | is_inline = true; | 2346 | is_inline = true; |
| 2282 | is_extern = false; | 2347 | is_export = false; |
| 2283 | } else if (first_token->id == TokenIdKeywordExtern) { | 2348 | } else if (first_token->id == TokenIdKeywordExport) { |
| 2284 | *token_index += 1; | 2349 | *token_index += 1; |
| 2285 | is_extern = true; | 2350 | is_export = true; |
| 2286 | is_inline = false; | 2351 | is_inline = false; |
| 2287 | } else { | 2352 | } else { |
| 2288 | is_inline = false; | 2353 | is_inline = false; |
| 2289 | is_extern = false; | 2354 | is_export = false; |
| 2290 | } | 2355 | } |
| 2291 | 2356 | ||
| 2292 | AstNode *fn_proto = ast_parse_fn_proto(pc, token_index, mandatory, visib_mod); | 2357 | AstNode *fn_proto = ast_parse_fn_proto(pc, token_index, mandatory, visib_mod); |
| 2293 | if (!fn_proto) { | 2358 | if (!fn_proto) { |
| 2294 | if (is_inline || is_extern) { | 2359 | if (is_inline || is_export) { |
| 2295 | *token_index -= 1; | 2360 | *token_index -= 1; |
| 2296 | } | 2361 | } |
| 2297 | return nullptr; | 2362 | return nullptr; |
| 2298 | } | 2363 | } |
| 2299 | 2364 | ||
| 2300 | fn_proto->data.fn_proto.is_inline = is_inline; | 2365 | 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; |
| 2302 | 2367 | ||
| 2303 | Token *semi_token = &pc->tokens->at(*token_index); | 2368 | Token *semi_token = &pc->tokens->at(*token_index); |
| 2304 | if (semi_token->id == TokenIdSemicolon) { | 2369 | if (semi_token->id == TokenIdSemicolon) { |
| ... | @@ -2344,7 +2409,7 @@ static AstNode *ast_parse_extern_decl(ParseContext *pc, size_t *token_index, boo | ... | @@ -2344,7 +2409,7 @@ static AstNode *ast_parse_extern_decl(ParseContext *pc, size_t *token_index, boo |
| 2344 | return fn_proto_node; | 2409 | return fn_proto_node; |
| 2345 | } | 2410 | } |
| 2346 | 2411 | ||
| 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); |
| 2348 | if (var_decl_node) { | 2413 | if (var_decl_node) { |
| 2349 | ast_eat_token(pc, token_index, TokenIdSemicolon); | 2414 | ast_eat_token(pc, token_index, TokenIdSemicolon); |
| 2350 | 2415 | ||
| ... | @@ -2447,9 +2512,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, | ... | @@ -2447,9 +2512,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, |
| 2447 | if (visib_tok->id == TokenIdKeywordPub) { | 2512 | if (visib_tok->id == TokenIdKeywordPub) { |
| 2448 | *token_index += 1; | 2513 | *token_index += 1; |
| 2449 | visib_mod = VisibModPub; | 2514 | visib_mod = VisibModPub; |
| 2450 | } else if (visib_tok->id == TokenIdKeywordExport) { | ||
| 2451 | *token_index += 1; | ||
| 2452 | visib_mod = VisibModExport; | ||
| 2453 | } else { | 2515 | } else { |
| 2454 | visib_mod = VisibModPrivate; | 2516 | visib_mod = VisibModPrivate; |
| 2455 | } | 2517 | } |
| ... | @@ -2460,7 +2522,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, | ... | @@ -2460,7 +2522,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, |
| 2460 | continue; | 2522 | continue; |
| 2461 | } | 2523 | } |
| 2462 | 2524 | ||
| 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); |
| 2464 | if (var_decl_node) { | 2526 | if (var_decl_node) { |
| 2465 | ast_eat_token(pc, token_index, TokenIdSemicolon); | 2527 | ast_eat_token(pc, token_index, TokenIdSemicolon); |
| 2466 | node->data.container_decl.decls.append(var_decl_node); | 2528 | 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) | ... | @@ -2553,7 +2615,7 @@ static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index) |
| 2553 | 2615 | ||
| 2554 | /* | 2616 | /* |
| 2555 | TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestDecl | 2617 | TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestDecl |
| 2556 | TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | UseDecl) | 2618 | TopLevelDecl = option("pub") (FnDef | ExternDecl | GlobalVarDecl | UseDecl) |
| 2557 | */ | 2619 | */ |
| 2558 | static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) { | 2620 | static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) { |
| 2559 | for (;;) { | 2621 | for (;;) { |
| ... | @@ -2580,9 +2642,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig | ... | @@ -2580,9 +2642,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig |
| 2580 | if (visib_tok->id == TokenIdKeywordPub) { | 2642 | if (visib_tok->id == TokenIdKeywordPub) { |
| 2581 | *token_index += 1; | 2643 | *token_index += 1; |
| 2582 | visib_mod = VisibModPub; | 2644 | visib_mod = VisibModPub; |
| 2583 | } else if (visib_tok->id == TokenIdKeywordExport) { | ||
| 2584 | *token_index += 1; | ||
| 2585 | visib_mod = VisibModExport; | ||
| 2586 | } else { | 2645 | } else { |
| 2587 | visib_mod = VisibModPrivate; | 2646 | visib_mod = VisibModPrivate; |
| 2588 | } | 2647 | } |
| ... | @@ -2605,7 +2664,7 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig | ... | @@ -2605,7 +2664,7 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig |
| 2605 | continue; | 2664 | continue; |
| 2606 | } | 2665 | } |
| 2607 | 2666 | ||
| 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); |
| 2609 | if (var_decl_node) { | 2668 | if (var_decl_node) { |
| 2610 | ast_eat_token(pc, token_index, TokenIdSemicolon); | 2669 | ast_eat_token(pc, token_index, TokenIdSemicolon); |
| 2611 | top_level_decls->append(var_decl_node); | 2670 | top_level_decls->append(var_decl_node); |
| ... | @@ -2669,6 +2728,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont | ... | @@ -2669,6 +2728,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 2669 | visit_field(&node->data.fn_proto.return_type, visit, context); | 2728 | visit_field(&node->data.fn_proto.return_type, visit, context); |
| 2670 | visit_node_list(&node->data.fn_proto.params, visit, context); | 2729 | visit_node_list(&node->data.fn_proto.params, visit, context); |
| 2671 | visit_field(&node->data.fn_proto.align_expr, visit, context); | 2730 | visit_field(&node->data.fn_proto.align_expr, visit, context); |
| 2731 | visit_field(&node->data.fn_proto.section_expr, visit, context); | ||
| 2672 | break; | 2732 | break; |
| 2673 | case NodeTypeFnDef: | 2733 | case NodeTypeFnDef: |
| 2674 | visit_field(&node->data.fn_def.fn_proto, visit, context); | 2734 | 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 | ... | @@ -2696,6 +2756,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 2696 | visit_field(&node->data.variable_declaration.type, visit, context); | 2756 | visit_field(&node->data.variable_declaration.type, visit, context); |
| 2697 | visit_field(&node->data.variable_declaration.expr, visit, context); | 2757 | visit_field(&node->data.variable_declaration.expr, visit, context); |
| 2698 | visit_field(&node->data.variable_declaration.align_expr, visit, context); | 2758 | visit_field(&node->data.variable_declaration.align_expr, visit, context); |
| 2759 | visit_field(&node->data.variable_declaration.section_expr, visit, context); | ||
| 2699 | break; | 2760 | break; |
| 2700 | case NodeTypeErrorValueDecl: | 2761 | case NodeTypeErrorValueDecl: |
| 2701 | // none | 2762 | // none |
src/tokenizer.cpp+2| ... | @@ -134,6 +134,7 @@ static const struct ZigKeyword zig_keywords[] = { | ... | @@ -134,6 +134,7 @@ static const struct ZigKeyword zig_keywords[] = { |
| 134 | {"packed", TokenIdKeywordPacked}, | 134 | {"packed", TokenIdKeywordPacked}, |
| 135 | {"pub", TokenIdKeywordPub}, | 135 | {"pub", TokenIdKeywordPub}, |
| 136 | {"return", TokenIdKeywordReturn}, | 136 | {"return", TokenIdKeywordReturn}, |
| 137 | {"section", TokenIdKeywordSection}, | ||
| 137 | {"stdcallcc", TokenIdKeywordStdcallCC}, | 138 | {"stdcallcc", TokenIdKeywordStdcallCC}, |
| 138 | {"struct", TokenIdKeywordStruct}, | 139 | {"struct", TokenIdKeywordStruct}, |
| 139 | {"switch", TokenIdKeywordSwitch}, | 140 | {"switch", TokenIdKeywordSwitch}, |
| ... | @@ -1533,6 +1534,7 @@ const char * token_name(TokenId id) { | ... | @@ -1533,6 +1534,7 @@ const char * token_name(TokenId id) { |
| 1533 | case TokenIdKeywordPacked: return "packed"; | 1534 | case TokenIdKeywordPacked: return "packed"; |
| 1534 | case TokenIdKeywordPub: return "pub"; | 1535 | case TokenIdKeywordPub: return "pub"; |
| 1535 | case TokenIdKeywordReturn: return "return"; | 1536 | case TokenIdKeywordReturn: return "return"; |
| 1537 | case TokenIdKeywordSection: return "section"; | ||
| 1536 | case TokenIdKeywordStdcallCC: return "stdcallcc"; | 1538 | case TokenIdKeywordStdcallCC: return "stdcallcc"; |
| 1537 | case TokenIdKeywordStruct: return "struct"; | 1539 | case TokenIdKeywordStruct: return "struct"; |
| 1538 | case TokenIdKeywordSwitch: return "switch"; | 1540 | case TokenIdKeywordSwitch: return "switch"; |
src/tokenizer.hpp+1| ... | @@ -47,6 +47,7 @@ enum TokenId { | ... | @@ -47,6 +47,7 @@ enum TokenId { |
| 47 | TokenIdFloatLiteral, | 47 | TokenIdFloatLiteral, |
| 48 | TokenIdIntLiteral, | 48 | TokenIdIntLiteral, |
| 49 | TokenIdKeywordAlign, | 49 | TokenIdKeywordAlign, |
| 50 | TokenIdKeywordSection, | ||
| 50 | TokenIdKeywordAnd, | 51 | TokenIdKeywordAnd, |
| 51 | TokenIdKeywordAsm, | 52 | TokenIdKeywordAsm, |
| 52 | TokenIdKeywordBreak, | 53 | TokenIdKeywordBreak, |
src/translate_c.cpp+5-4| ... | @@ -73,7 +73,7 @@ struct Context { | ... | @@ -73,7 +73,7 @@ struct Context { |
| 73 | ImportTableEntry *import; | 73 | ImportTableEntry *import; |
| 74 | ZigList<ErrorMsg *> *errors; | 74 | ZigList<ErrorMsg *> *errors; |
| 75 | VisibMod visib_mod; | 75 | VisibMod visib_mod; |
| 76 | VisibMod export_visib_mod; | 76 | bool want_export; |
| 77 | AstNode *root; | 77 | AstNode *root; |
| 78 | HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table; | 78 | HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table; |
| 79 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; | 79 | 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) { | ... | @@ -3251,7 +3251,8 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 3251 | 3251 | ||
| 3252 | StorageClass sc = fn_decl->getStorageClass(); | 3252 | StorageClass sc = fn_decl->getStorageClass(); |
| 3253 | if (sc == SC_None) { | 3253 | 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; | ||
| 3255 | } else if (sc == SC_Extern || sc == SC_Static) { | 3256 | } else if (sc == SC_Extern || sc == SC_Static) { |
| 3256 | proto_node->data.fn_proto.visib_mod = c->visib_mod; | 3257 | proto_node->data.fn_proto.visib_mod = c->visib_mod; |
| 3257 | } else if (sc == SC_PrivateExtern) { | 3258 | } else if (sc == SC_PrivateExtern) { |
| ... | @@ -4274,10 +4275,10 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -4274,10 +4275,10 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 4274 | c->errors = errors; | 4275 | c->errors = errors; |
| 4275 | if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) { | 4276 | if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) { |
| 4276 | c->visib_mod = VisibModPub; | 4277 | c->visib_mod = VisibModPub; |
| 4277 | c->export_visib_mod = VisibModPub; | 4278 | c->want_export = false; |
| 4278 | } else { | 4279 | } else { |
| 4279 | c->visib_mod = VisibModPub; | 4280 | c->visib_mod = VisibModPub; |
| 4280 | c->export_visib_mod = VisibModExport; | 4281 | c->want_export = true; |
| 4281 | } | 4282 | } |
| 4282 | c->decl_table.init(8); | 4283 | c->decl_table.init(8); |
| 4283 | c->macro_table.init(8); | 4284 | c->macro_table.init(8); |
std/debug.zig-2| ... | @@ -96,8 +96,6 @@ const WHITE = "\x1b[37;1m"; | ... | @@ -96,8 +96,6 @@ const WHITE = "\x1b[37;1m"; |
| 96 | const DIM = "\x1b[2m"; | 96 | const DIM = "\x1b[2m"; |
| 97 | const RESET = "\x1b[0m"; | 97 | const RESET = "\x1b[0m"; |
| 98 | 98 | ||
| 99 | pub var user_main_fn: ?fn() -> %void = null; | ||
| 100 | |||
| 101 | error PathNotFound; | 99 | error PathNotFound; |
| 102 | error InvalidDebugInfo; | 100 | error InvalidDebugInfo; |
| 103 | 101 |
std/elf.zig+31-31| ... | @@ -188,39 +188,39 @@ pub const Elf = struct { | ... | @@ -188,39 +188,39 @@ pub const Elf = struct { |
| 188 | if (elf.is_64) { | 188 | if (elf.is_64) { |
| 189 | if (sh_entry_size != 64) return error.InvalidFormat; | 189 | if (sh_entry_size != 64) return error.InvalidFormat; |
| 190 | 190 | ||
| 191 | for (elf.section_headers) |*section| { | 191 | for (elf.section_headers) |*elf_section| { |
| 192 | section.name = %return in.readInt(elf.endian, u32); | 192 | elf_section.name = %return in.readInt(elf.endian, u32); |
| 193 | section.sh_type = %return in.readInt(elf.endian, u32); | 193 | elf_section.sh_type = %return in.readInt(elf.endian, u32); |
| 194 | section.flags = %return in.readInt(elf.endian, u64); | 194 | elf_section.flags = %return in.readInt(elf.endian, u64); |
| 195 | section.addr = %return in.readInt(elf.endian, u64); | 195 | elf_section.addr = %return in.readInt(elf.endian, u64); |
| 196 | section.offset = %return in.readInt(elf.endian, u64); | 196 | elf_section.offset = %return in.readInt(elf.endian, u64); |
| 197 | section.size = %return in.readInt(elf.endian, u64); | 197 | elf_section.size = %return in.readInt(elf.endian, u64); |
| 198 | section.link = %return in.readInt(elf.endian, u32); | 198 | elf_section.link = %return in.readInt(elf.endian, u32); |
| 199 | section.info = %return in.readInt(elf.endian, u32); | 199 | elf_section.info = %return in.readInt(elf.endian, u32); |
| 200 | section.addr_align = %return in.readInt(elf.endian, u64); | 200 | elf_section.addr_align = %return in.readInt(elf.endian, u64); |
| 201 | section.ent_size = %return in.readInt(elf.endian, u64); | 201 | elf_section.ent_size = %return in.readInt(elf.endian, u64); |
| 202 | } | 202 | } |
| 203 | } else { | 203 | } else { |
| 204 | if (sh_entry_size != 40) return error.InvalidFormat; | 204 | if (sh_entry_size != 40) return error.InvalidFormat; |
| 205 | 205 | ||
| 206 | for (elf.section_headers) |*section| { | 206 | for (elf.section_headers) |*elf_section| { |
| 207 | // TODO (multiple occurences) allow implicit cast from %u32 -> %u64 ? | 207 | // TODO (multiple occurences) allow implicit cast from %u32 -> %u64 ? |
| 208 | section.name = %return in.readInt(elf.endian, u32); | 208 | elf_section.name = %return in.readInt(elf.endian, u32); |
| 209 | section.sh_type = %return in.readInt(elf.endian, u32); | 209 | elf_section.sh_type = %return in.readInt(elf.endian, u32); |
| 210 | section.flags = u64(%return in.readInt(elf.endian, u32)); | 210 | elf_section.flags = u64(%return in.readInt(elf.endian, u32)); |
| 211 | section.addr = u64(%return in.readInt(elf.endian, u32)); | 211 | elf_section.addr = u64(%return in.readInt(elf.endian, u32)); |
| 212 | section.offset = u64(%return in.readInt(elf.endian, u32)); | 212 | elf_section.offset = u64(%return in.readInt(elf.endian, u32)); |
| 213 | section.size = u64(%return in.readInt(elf.endian, u32)); | 213 | elf_section.size = u64(%return in.readInt(elf.endian, u32)); |
| 214 | section.link = %return in.readInt(elf.endian, u32); | 214 | elf_section.link = %return in.readInt(elf.endian, u32); |
| 215 | section.info = %return in.readInt(elf.endian, u32); | 215 | elf_section.info = %return in.readInt(elf.endian, u32); |
| 216 | section.addr_align = u64(%return in.readInt(elf.endian, u32)); | 216 | elf_section.addr_align = u64(%return in.readInt(elf.endian, u32)); |
| 217 | section.ent_size = u64(%return in.readInt(elf.endian, u32)); | 217 | elf_section.ent_size = u64(%return in.readInt(elf.endian, u32)); |
| 218 | } | 218 | } |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | for (elf.section_headers) |*section| { | 221 | for (elf.section_headers) |*elf_section| { |
| 222 | if (section.sh_type != SHT_NOBITS) { | 222 | if (elf_section.sh_type != SHT_NOBITS) { |
| 223 | const file_end_offset = %return math.add(u64, section.offset, section.size); | 223 | const file_end_offset = %return math.add(u64, elf_section.offset, elf_section.size); |
| 224 | if (stream_end < file_end_offset) return error.InvalidFormat; | 224 | if (stream_end < file_end_offset) return error.InvalidFormat; |
| 225 | } | 225 | } |
| 226 | } | 226 | } |
| ... | @@ -243,10 +243,10 @@ pub const Elf = struct { | ... | @@ -243,10 +243,10 @@ pub const Elf = struct { |
| 243 | var file_stream = io.FileInStream.init(elf.in_file); | 243 | var file_stream = io.FileInStream.init(elf.in_file); |
| 244 | const in = &file_stream.stream; | 244 | const in = &file_stream.stream; |
| 245 | 245 | ||
| 246 | for (elf.section_headers) |*section| { | 246 | for (elf.section_headers) |*elf_section| { |
| 247 | if (section.sh_type == SHT_NULL) continue; | 247 | if (elf_section.sh_type == SHT_NULL) continue; |
| 248 | 248 | ||
| 249 | const name_offset = elf.string_section.offset + section.name; | 249 | const name_offset = elf.string_section.offset + elf_section.name; |
| 250 | %return elf.in_file.seekTo(name_offset); | 250 | %return elf.in_file.seekTo(name_offset); |
| 251 | 251 | ||
| 252 | for (name) |expected_c| { | 252 | for (name) |expected_c| { |
| ... | @@ -256,7 +256,7 @@ pub const Elf = struct { | ... | @@ -256,7 +256,7 @@ pub const Elf = struct { |
| 256 | 256 | ||
| 257 | { | 257 | { |
| 258 | const null_byte = %return in.readByte(); | 258 | const null_byte = %return in.readByte(); |
| 259 | if (null_byte == 0) return section; | 259 | if (null_byte == 0) return elf_section; |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | next_section: | 262 | next_section: |
| ... | @@ -265,7 +265,7 @@ pub const Elf = struct { | ... | @@ -265,7 +265,7 @@ pub const Elf = struct { |
| 265 | return null; | 265 | return null; |
| 266 | } | 266 | } |
| 267 | 267 | ||
| 268 | pub fn seekToSection(elf: &Elf, section: &SectionHeader) -> %void { | 268 | pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) -> %void { |
| 269 | %return elf.in_file.seekTo(section.offset); | 269 | %return elf.in_file.seekTo(elf_section.offset); |
| 270 | } | 270 | } |
| 271 | }; | 271 | }; |
std/os/linux.zig-22| ... | @@ -651,28 +651,6 @@ pub const iovec = extern struct { | ... | @@ -651,28 +651,6 @@ pub const iovec = extern struct { |
| 651 | iov_len: usize, | 651 | iov_len: usize, |
| 652 | }; | 652 | }; |
| 653 | 653 | ||
| 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 | |||
| 676 | pub fn getsockname(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize { | 654 | pub fn getsockname(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize { |
| 677 | arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len)) | 655 | arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len)) |
| 678 | } | 656 | } |
std/os/linux_i386.zig-10| ... | @@ -502,13 +502,3 @@ pub nakedcc fn restore_rt() { | ... | @@ -502,13 +502,3 @@ pub nakedcc fn restore_rt() { |
| 502 | : [number] "{eax}" (usize(SYS_rt_sigreturn)) | 502 | : [number] "{eax}" (usize(SYS_rt_sigreturn)) |
| 503 | : "rcx", "r11") | 503 | : "rcx", "r11") |
| 504 | } | 504 | } |
| 505 | |||
| 506 | export 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"); | ... | @@ -5,20 +5,20 @@ const root = @import("@root"); |
| 5 | const std = @import("std"); | 5 | const std = @import("std"); |
| 6 | const builtin = @import("builtin"); | 6 | const builtin = @import("builtin"); |
| 7 | 7 | ||
| 8 | const is_windows = builtin.os == builtin.Os.windows; | ||
| 9 | const want_main_symbol = builtin.link_libc; | ||
| 10 | const want_start_symbol = !want_main_symbol and !is_windows; | ||
| 11 | const want_WinMainCRTStartup = is_windows and !builtin.link_libc; | ||
| 12 | |||
| 13 | var argc_ptr: &usize = undefined; | 8 | var argc_ptr: &usize = undefined; |
| 14 | 9 | ||
| 15 | 10 | comptime { | |
| 16 | export nakedcc fn _start() -> noreturn { | 11 | const strong_linkage = builtin.GlobalLinkage.Strong; |
| 17 | if (!want_start_symbol) { | 12 | if (builtin.link_libc) { |
| 18 | @setGlobalLinkage(_start, builtin.GlobalLinkage.Internal); | 13 | @export("main", main, strong_linkage); |
| 19 | unreachable; | 14 | } else if (builtin.os == builtin.Os.windows) { |
| 15 | @export("WinMainCRTStartup", WinMainCRTStartup, strong_linkage); | ||
| 16 | } else { | ||
| 17 | @export("_start", _start, strong_linkage); | ||
| 20 | } | 18 | } |
| 19 | } | ||
| 21 | 20 | ||
| 21 | nakedcc fn _start() -> noreturn { | ||
| 22 | switch (builtin.arch) { | 22 | switch (builtin.arch) { |
| 23 | builtin.Arch.x86_64 => { | 23 | builtin.Arch.x86_64 => { |
| 24 | argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize)); | 24 | argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize)); |
| ... | @@ -33,14 +33,9 @@ export nakedcc fn _start() -> noreturn { | ... | @@ -33,14 +33,9 @@ export nakedcc fn _start() -> noreturn { |
| 33 | @noInlineCall(posixCallMainAndExit); | 33 | @noInlineCall(posixCallMainAndExit); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | export fn WinMainCRTStartup() -> noreturn { | 36 | extern fn WinMainCRTStartup() -> noreturn { |
| 37 | if (!want_WinMainCRTStartup) { | ||
| 38 | @setGlobalLinkage(WinMainCRTStartup, builtin.GlobalLinkage.Internal); | ||
| 39 | unreachable; | ||
| 40 | } | ||
| 41 | @setAlignStack(16); | 37 | @setAlignStack(16); |
| 42 | 38 | ||
| 43 | std.debug.user_main_fn = root.main; | ||
| 44 | root.main() %% std.os.windows.ExitProcess(1); | 39 | root.main() %% std.os.windows.ExitProcess(1); |
| 45 | std.os.windows.ExitProcess(0); | 40 | std.os.windows.ExitProcess(0); |
| 46 | } | 41 | } |
| ... | @@ -60,17 +55,10 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void { | ... | @@ -60,17 +55,10 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void { |
| 60 | while (envp[env_count] != null) : (env_count += 1) {} | 55 | while (envp[env_count] != null) : (env_count += 1) {} |
| 61 | std.os.posix_environ_raw = @ptrCast(&&u8, envp)[0..env_count]; | 56 | std.os.posix_environ_raw = @ptrCast(&&u8, envp)[0..env_count]; |
| 62 | 57 | ||
| 63 | std.debug.user_main_fn = root.main; | ||
| 64 | |||
| 65 | return root.main(); | 58 | return root.main(); |
| 66 | } | 59 | } |
| 67 | 60 | ||
| 68 | export fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 { | 61 | extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 { |
| 69 | if (!want_main_symbol) { | ||
| 70 | @setGlobalLinkage(main, builtin.GlobalLinkage.Internal); | ||
| 71 | unreachable; | ||
| 72 | } | ||
| 73 | |||
| 74 | callMain(usize(c_argc), c_argv, c_envp) %% return 1; | 62 | callMain(usize(c_argc), c_argv, c_envp) %% return 1; |
| 75 | return 0; | 63 | return 0; |
| 76 | } | 64 | } |
std/special/bootstrap_lib.zig+5-1| ... | @@ -2,7 +2,11 @@ | ... | @@ -2,7 +2,11 @@ |
| 2 | 2 | ||
| 3 | const std = @import("std"); | 3 | const std = @import("std"); |
| 4 | 4 | ||
| 5 | export stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD, | 5 | comptime { |
| 6 | @export("_DllMainCRTStartup", _DllMainCRTStartup); | ||
| 7 | } | ||
| 8 | |||
| 9 | stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD, | ||
| 6 | lpReserved: std.os.windows.LPVOID) -> std.os.windows.BOOL | 10 | lpReserved: std.os.windows.LPVOID) -> std.os.windows.BOOL |
| 7 | { | 11 | { |
| 8 | return std.os.windows.TRUE; | 12 | return std.os.windows.TRUE; |
std/special/builtin.zig+5-4| ... | @@ -35,11 +35,12 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) { | ... | @@ -35,11 +35,12 @@ export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) { |
| 35 | (??dest)[index] = (??src)[index]; | 35 | (??dest)[index] = (??src)[index]; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | export fn __stack_chk_fail() -> noreturn { | 38 | comptime { |
| 39 | if (builtin.mode == builtin.Mode.ReleaseFast or builtin.os == builtin.Os.windows) { | 39 | if (builtin.mode != builtin.Mode.ReleaseFast and builtin.os != builtin.Os.windows) { |
| 40 | @setGlobalLinkage(__stack_chk_fail, builtin.GlobalLinkage.Internal); | 40 | @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong); |
| 41 | unreachable; | ||
| 42 | } | 41 | } |
| 42 | } | ||
| 43 | extern fn __stack_chk_fail() -> noreturn { | ||
| 43 | @panic("stack smashing detected"); | 44 | @panic("stack smashing detected"); |
| 44 | } | 45 | } |
| 45 | 46 |
std/special/compiler_rt/aulldiv.zig+54-65| ... | @@ -1,66 +1,55 @@ | ... | @@ -1,66 +1,55 @@ |
| 1 | const builtin = @import("builtin"); | 1 | pub nakedcc fn _aulldiv() { |
| 2 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong; | 2 | @setDebugSafety(this, false); |
| 3 | const is_win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386; | 3 | asm volatile ( |
| 4 | 4 | \\.intel_syntax noprefix | |
| 5 | export nakedcc fn _aulldiv() { | 5 | \\ |
| 6 | if (is_win32) { | 6 | \\ push ebx |
| 7 | @setDebugSafety(this, false); | 7 | \\ push esi |
| 8 | @setGlobalLinkage(_aulldiv, linkage); | 8 | \\ mov eax,dword ptr [esp+18h] |
| 9 | asm volatile ( | 9 | \\ or eax,eax |
| 10 | \\.intel_syntax noprefix | 10 | \\ jne L1 |
| 11 | \\ | 11 | \\ mov ecx,dword ptr [esp+14h] |
| 12 | \\ push ebx | 12 | \\ mov eax,dword ptr [esp+10h] |
| 13 | \\ push esi | 13 | \\ xor edx,edx |
| 14 | \\ mov eax,dword ptr [esp+18h] | 14 | \\ div ecx |
| 15 | \\ or eax,eax | 15 | \\ mov ebx,eax |
| 16 | \\ jne L1 | 16 | \\ mov eax,dword ptr [esp+0Ch] |
| 17 | \\ mov ecx,dword ptr [esp+14h] | 17 | \\ div ecx |
| 18 | \\ mov eax,dword ptr [esp+10h] | 18 | \\ mov edx,ebx |
| 19 | \\ xor edx,edx | 19 | \\ jmp L2 |
| 20 | \\ div ecx | 20 | \\ L1: |
| 21 | \\ mov ebx,eax | 21 | \\ mov ecx,eax |
| 22 | \\ mov eax,dword ptr [esp+0Ch] | 22 | \\ mov ebx,dword ptr [esp+14h] |
| 23 | \\ div ecx | 23 | \\ mov edx,dword ptr [esp+10h] |
| 24 | \\ mov edx,ebx | 24 | \\ mov eax,dword ptr [esp+0Ch] |
| 25 | \\ jmp L2 | 25 | \\ L3: |
| 26 | \\ L1: | 26 | \\ shr ecx,1 |
| 27 | \\ mov ecx,eax | 27 | \\ rcr ebx,1 |
| 28 | \\ mov ebx,dword ptr [esp+14h] | 28 | \\ shr edx,1 |
| 29 | \\ mov edx,dword ptr [esp+10h] | 29 | \\ rcr eax,1 |
| 30 | \\ mov eax,dword ptr [esp+0Ch] | 30 | \\ or ecx,ecx |
| 31 | \\ L3: | 31 | \\ jne L3 |
| 32 | \\ shr ecx,1 | 32 | \\ div ebx |
| 33 | \\ rcr ebx,1 | 33 | \\ mov esi,eax |
| 34 | \\ shr edx,1 | 34 | \\ mul dword ptr [esp+18h] |
| 35 | \\ rcr eax,1 | 35 | \\ mov ecx,eax |
| 36 | \\ or ecx,ecx | 36 | \\ mov eax,dword ptr [esp+14h] |
| 37 | \\ jne L3 | 37 | \\ mul esi |
| 38 | \\ div ebx | 38 | \\ add edx,ecx |
| 39 | \\ mov esi,eax | 39 | \\ jb L4 |
| 40 | \\ mul dword ptr [esp+18h] | 40 | \\ cmp edx,dword ptr [esp+10h] |
| 41 | \\ mov ecx,eax | 41 | \\ ja L4 |
| 42 | \\ mov eax,dword ptr [esp+14h] | 42 | \\ jb L5 |
| 43 | \\ mul esi | 43 | \\ cmp eax,dword ptr [esp+0Ch] |
| 44 | \\ add edx,ecx | 44 | \\ jbe L5 |
| 45 | \\ jb L4 | 45 | \\ L4: |
| 46 | \\ cmp edx,dword ptr [esp+10h] | 46 | \\ dec esi |
| 47 | \\ ja L4 | 47 | \\ L5: |
| 48 | \\ jb L5 | 48 | \\ xor edx,edx |
| 49 | \\ cmp eax,dword ptr [esp+0Ch] | 49 | \\ mov eax,esi |
| 50 | \\ jbe L5 | 50 | \\ L2: |
| 51 | \\ L4: | 51 | \\ pop esi |
| 52 | \\ dec esi | 52 | \\ pop ebx |
| 53 | \\ L5: | 53 | \\ ret 10h |
| 54 | \\ xor edx,edx | 54 | ); |
| 55 | \\ mov eax,esi | ||
| 56 | \\ L2: | ||
| 57 | \\ pop esi | ||
| 58 | \\ pop ebx | ||
| 59 | \\ ret 10h | ||
| 60 | ); | ||
| 61 | unreachable; | ||
| 62 | } | ||
| 63 | |||
| 64 | @setGlobalLinkage(_aulldiv, builtin.GlobalLinkage.Internal); | ||
| 65 | unreachable; | ||
| 66 | } | 55 | } |
std/special/compiler_rt/aullrem.zig+55-66| ... | @@ -1,67 +1,56 @@ | ... | @@ -1,67 +1,56 @@ |
| 1 | const builtin = @import("builtin"); | 1 | pub nakedcc fn _aullrem() { |
| 2 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong; | 2 | @setDebugSafety(this, false); |
| 3 | const is_win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386; | 3 | asm volatile ( |
| 4 | 4 | \\.intel_syntax noprefix | |
| 5 | export nakedcc fn _aullrem() { | 5 | \\ |
| 6 | if (is_win32) { | 6 | \\ push ebx |
| 7 | @setDebugSafety(this, false); | 7 | \\ mov eax,dword ptr [esp+14h] |
| 8 | @setGlobalLinkage(_aullrem, linkage); | 8 | \\ or eax,eax |
| 9 | asm volatile ( | 9 | \\ jne L1a |
| 10 | \\.intel_syntax noprefix | 10 | \\ mov ecx,dword ptr [esp+10h] |
| 11 | \\ | 11 | \\ mov eax,dword ptr [esp+0Ch] |
| 12 | \\ push ebx | 12 | \\ xor edx,edx |
| 13 | \\ mov eax,dword ptr [esp+14h] | 13 | \\ div ecx |
| 14 | \\ or eax,eax | 14 | \\ mov eax,dword ptr [esp+8] |
| 15 | \\ jne L1a | 15 | \\ div ecx |
| 16 | \\ mov ecx,dword ptr [esp+10h] | 16 | \\ mov eax,edx |
| 17 | \\ mov eax,dword ptr [esp+0Ch] | 17 | \\ xor edx,edx |
| 18 | \\ xor edx,edx | 18 | \\ jmp L2a |
| 19 | \\ div ecx | 19 | \\ L1a: |
| 20 | \\ mov eax,dword ptr [esp+8] | 20 | \\ mov ecx,eax |
| 21 | \\ div ecx | 21 | \\ mov ebx,dword ptr [esp+10h] |
| 22 | \\ mov eax,edx | 22 | \\ mov edx,dword ptr [esp+0Ch] |
| 23 | \\ xor edx,edx | 23 | \\ mov eax,dword ptr [esp+8] |
| 24 | \\ jmp L2a | 24 | \\ L3a: |
| 25 | \\ L1a: | 25 | \\ shr ecx,1 |
| 26 | \\ mov ecx,eax | 26 | \\ rcr ebx,1 |
| 27 | \\ mov ebx,dword ptr [esp+10h] | 27 | \\ shr edx,1 |
| 28 | \\ mov edx,dword ptr [esp+0Ch] | 28 | \\ rcr eax,1 |
| 29 | \\ mov eax,dword ptr [esp+8] | 29 | \\ or ecx,ecx |
| 30 | \\ L3a: | 30 | \\ jne L3a |
| 31 | \\ shr ecx,1 | 31 | \\ div ebx |
| 32 | \\ rcr ebx,1 | 32 | \\ mov ecx,eax |
| 33 | \\ shr edx,1 | 33 | \\ mul dword ptr [esp+14h] |
| 34 | \\ rcr eax,1 | 34 | \\ xchg eax,ecx |
| 35 | \\ or ecx,ecx | 35 | \\ mul dword ptr [esp+10h] |
| 36 | \\ jne L3a | 36 | \\ add edx,ecx |
| 37 | \\ div ebx | 37 | \\ jb L4a |
| 38 | \\ mov ecx,eax | 38 | \\ cmp edx,dword ptr [esp+0Ch] |
| 39 | \\ mul dword ptr [esp+14h] | 39 | \\ ja L4a |
| 40 | \\ xchg eax,ecx | 40 | \\ jb L5a |
| 41 | \\ mul dword ptr [esp+10h] | 41 | \\ cmp eax,dword ptr [esp+8] |
| 42 | \\ add edx,ecx | 42 | \\ jbe L5a |
| 43 | \\ jb L4a | 43 | \\ L4a: |
| 44 | \\ cmp edx,dword ptr [esp+0Ch] | 44 | \\ sub eax,dword ptr [esp+10h] |
| 45 | \\ ja L4a | 45 | \\ sbb edx,dword ptr [esp+14h] |
| 46 | \\ jb L5a | 46 | \\ L5a: |
| 47 | \\ cmp eax,dword ptr [esp+8] | 47 | \\ sub eax,dword ptr [esp+8] |
| 48 | \\ jbe L5a | 48 | \\ sbb edx,dword ptr [esp+0Ch] |
| 49 | \\ L4a: | 49 | \\ neg edx |
| 50 | \\ sub eax,dword ptr [esp+10h] | 50 | \\ neg eax |
| 51 | \\ sbb edx,dword ptr [esp+14h] | 51 | \\ sbb edx,0 |
| 52 | \\ L5a: | 52 | \\ L2a: |
| 53 | \\ sub eax,dword ptr [esp+8] | 53 | \\ pop ebx |
| 54 | \\ sbb edx,dword ptr [esp+0Ch] | 54 | \\ ret 10h |
| 55 | \\ neg edx | 55 | ); |
| 56 | \\ neg eax | ||
| 57 | \\ sbb edx,0 | ||
| 58 | \\ L2a: | ||
| 59 | \\ pop ebx | ||
| 60 | \\ ret 10h | ||
| 61 | ); | ||
| 62 | unreachable; | ||
| 63 | } | ||
| 64 | |||
| 65 | @setGlobalLinkage(_aullrem, builtin.GlobalLinkage.Internal); | ||
| 66 | unreachable; | ||
| 67 | } | 56 | } |
std/special/compiler_rt/comparetf2.zig+3-42| ... | @@ -20,11 +20,9 @@ const infRep = exponentMask; | ... | @@ -20,11 +20,9 @@ const infRep = exponentMask; |
| 20 | 20 | ||
| 21 | const builtin = @import("builtin"); | 21 | const builtin = @import("builtin"); |
| 22 | const is_test = builtin.is_test; | 22 | const is_test = builtin.is_test; |
| 23 | const linkage = @import("index.zig").linkage; | ||
| 24 | 23 | ||
| 25 | export fn __letf2(a: f128, b: f128) -> c_int { | 24 | pub extern fn __letf2(a: f128, b: f128) -> c_int { |
| 26 | @setDebugSafety(this, is_test); | 25 | @setDebugSafety(this, is_test); |
| 27 | @setGlobalLinkage(__letf2, linkage); | ||
| 28 | 26 | ||
| 29 | const aInt = @bitCast(rep_t, a); | 27 | const aInt = @bitCast(rep_t, a); |
| 30 | const bInt = @bitCast(rep_t, b); | 28 | const bInt = @bitCast(rep_t, b); |
| ... | @@ -63,14 +61,6 @@ export fn __letf2(a: f128, b: f128) -> c_int { | ... | @@ -63,14 +61,6 @@ export fn __letf2(a: f128, b: f128) -> c_int { |
| 63 | }; | 61 | }; |
| 64 | } | 62 | } |
| 65 | 63 | ||
| 66 | // Alias for libgcc compatibility | ||
| 67 | // TODO https://github.com/zig-lang/zig/issues/420 | ||
| 68 | export fn __cmptf2(a: f128, b: f128) -> c_int { | ||
| 69 | @setGlobalLinkage(__cmptf2, linkage); | ||
| 70 | @setDebugSafety(this, is_test); | ||
| 71 | return __letf2(a, b); | ||
| 72 | } | ||
| 73 | |||
| 74 | // TODO https://github.com/zig-lang/zig/issues/305 | 64 | // TODO https://github.com/zig-lang/zig/issues/305 |
| 75 | // and then make the return types of some of these functions the enum instead of c_int | 65 | // and then make the return types of some of these functions the enum instead of c_int |
| 76 | const GE_LESS = c_int(-1); | 66 | const GE_LESS = c_int(-1); |
| ... | @@ -78,8 +68,7 @@ const GE_EQUAL = c_int(0); | ... | @@ -78,8 +68,7 @@ const GE_EQUAL = c_int(0); |
| 78 | const GE_GREATER = c_int(1); | 68 | const GE_GREATER = c_int(1); |
| 79 | const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED | 69 | const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED |
| 80 | 70 | ||
| 81 | export fn __getf2(a: f128, b: f128) -> c_int { | 71 | pub extern fn __getf2(a: f128, b: f128) -> c_int { |
| 82 | @setGlobalLinkage(__getf2, linkage); | ||
| 83 | @setDebugSafety(this, is_test); | 72 | @setDebugSafety(this, is_test); |
| 84 | 73 | ||
| 85 | const aInt = @bitCast(srep_t, a); | 74 | const aInt = @bitCast(srep_t, a); |
| ... | @@ -108,38 +97,10 @@ export fn __getf2(a: f128, b: f128) -> c_int { | ... | @@ -108,38 +97,10 @@ export fn __getf2(a: f128, b: f128) -> c_int { |
| 108 | }; | 97 | }; |
| 109 | } | 98 | } |
| 110 | 99 | ||
| 111 | export fn __unordtf2(a: f128, b: f128) -> c_int { | 100 | pub extern fn __unordtf2(a: f128, b: f128) -> c_int { |
| 112 | @setGlobalLinkage(__unordtf2, linkage); | ||
| 113 | @setDebugSafety(this, is_test); | 101 | @setDebugSafety(this, is_test); |
| 114 | 102 | ||
| 115 | const aAbs = @bitCast(rep_t, a) & absMask; | 103 | const aAbs = @bitCast(rep_t, a) & absMask; |
| 116 | const bAbs = @bitCast(rep_t, b) & absMask; | 104 | const bAbs = @bitCast(rep_t, b) & absMask; |
| 117 | return c_int(aAbs > infRep or bAbs > infRep); | 105 | return c_int(aAbs > infRep or bAbs > infRep); |
| 118 | } | 106 | } |
| 119 | |||
| 120 | // The following are alternative names for the preceding routines. | ||
| 121 | // TODO use aliases https://github.com/zig-lang/zig/issues/462 | ||
| 122 | |||
| 123 | export fn __eqtf2(a: f128, b: f128) -> c_int { | ||
| 124 | @setGlobalLinkage(__eqtf2, linkage); | ||
| 125 | @setDebugSafety(this, is_test); | ||
| 126 | return __letf2(a, b); | ||
| 127 | } | ||
| 128 | |||
| 129 | export fn __lttf2(a: f128, b: f128) -> c_int { | ||
| 130 | @setGlobalLinkage(__lttf2, linkage); | ||
| 131 | @setDebugSafety(this, is_test); | ||
| 132 | return __letf2(a, b); | ||
| 133 | } | ||
| 134 | |||
| 135 | export fn __netf2(a: f128, b: f128) -> c_int { | ||
| 136 | @setGlobalLinkage(__netf2, linkage); | ||
| 137 | @setDebugSafety(this, is_test); | ||
| 138 | return __letf2(a, b); | ||
| 139 | } | ||
| 140 | |||
| 141 | export fn __gttf2(a: f128, b: f128) -> c_int { | ||
| 142 | @setGlobalLinkage(__gttf2, linkage); | ||
| 143 | @setDebugSafety(this, is_test); | ||
| 144 | return __getf2(a, b); | ||
| 145 | } |
std/special/compiler_rt/fixunsdfdi.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const fixuint = @import("fixuint.zig").fixuint; | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __fixunsdfdi(a: f64) -> u64 { | 4 | pub extern fn __fixunsdfdi(a: f64) -> u64 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunsdfdi, linkage); | ||
| 8 | return fixuint(f64, u64, a); | 6 | return fixuint(f64, u64, a); |
| 9 | } | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunsdfsi.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const fixuint = @import("fixuint.zig").fixuint; | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __fixunsdfsi(a: f64) -> u32 { | 4 | pub extern fn __fixunsdfsi(a: f64) -> u32 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunsdfsi, linkage); | ||
| 8 | return fixuint(f64, u32, a); | 6 | return fixuint(f64, u32, a); |
| 9 | } | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunsdfti.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const fixuint = @import("fixuint.zig").fixuint; | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __fixunsdfti(a: f64) -> u128 { | 4 | pub extern fn __fixunsdfti(a: f64) -> u128 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunsdfti, linkage); | ||
| 8 | return fixuint(f64, u128, a); | 6 | return fixuint(f64, u128, a); |
| 9 | } | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunssfdi.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const fixuint = @import("fixuint.zig").fixuint; | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __fixunssfdi(a: f32) -> u64 { | 4 | pub extern fn __fixunssfdi(a: f32) -> u64 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunssfdi, linkage); | ||
| 8 | return fixuint(f32, u64, a); | 6 | return fixuint(f32, u64, a); |
| 9 | } | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunssfsi.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const fixuint = @import("fixuint.zig").fixuint; | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __fixunssfsi(a: f32) -> u32 { | 4 | pub extern fn __fixunssfsi(a: f32) -> u32 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunssfsi, linkage); | ||
| 8 | return fixuint(f32, u32, a); | 6 | return fixuint(f32, u32, a); |
| 9 | } | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunssfti.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const fixuint = @import("fixuint.zig").fixuint; | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __fixunssfti(a: f32) -> u128 { | 4 | pub extern fn __fixunssfti(a: f32) -> u128 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunssfti, linkage); | ||
| 8 | return fixuint(f32, u128, a); | 6 | return fixuint(f32, u128, a); |
| 9 | } | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunstfdi.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const fixuint = @import("fixuint.zig").fixuint; | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __fixunstfdi(a: f128) -> u64 { | 4 | pub extern fn __fixunstfdi(a: f128) -> u64 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunstfdi, linkage); | ||
| 8 | return fixuint(f128, u64, a); | 6 | return fixuint(f128, u64, a); |
| 9 | } | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunstfsi.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const fixuint = @import("fixuint.zig").fixuint; | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __fixunstfsi(a: f128) -> u32 { | 4 | pub extern fn __fixunstfsi(a: f128) -> u32 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunstfsi, linkage); | ||
| 8 | return fixuint(f128, u32, a); | 6 | return fixuint(f128, u32, a); |
| 9 | } | 7 | } |
| 10 | 8 |
std/special/compiler_rt/fixunstfti.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const fixuint = @import("fixuint.zig").fixuint; | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __fixunstfti(a: f128) -> u128 { | 4 | pub extern fn __fixunstfti(a: f128) -> u128 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__fixunstfti, linkage); | ||
| 8 | return fixuint(f128, u128, a); | 6 | return fixuint(f128, u128, a); |
| 9 | } | 7 | } |
| 10 | 8 |
std/special/compiler_rt/index.zig+165-176| ... | @@ -1,33 +1,74 @@ | ... | @@ -1,33 +1,74 @@ |
| 1 | comptime { | ||
| 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 | |||
| 20 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 21 | const is_test = builtin.is_test; | 2 | const is_test = builtin.is_test; |
| 22 | const assert = @import("../../debug.zig").assert; | ||
| 23 | 3 | ||
| 4 | comptime { | ||
| 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); | ||
| 24 | 36 | ||
| 25 | const win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.i386; | 37 | @export("__udivti3", @import("udivti3.zig").__udivti3, linkage); |
| 26 | const win64 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.x86_64; | 38 | @export("__umodti3", @import("umodti3.zig").__umodti3, linkage); |
| 27 | const win32_nocrt = win32 and !builtin.link_libc; | 39 | |
| 28 | const win64_nocrt = win64 and !builtin.link_libc; | 40 | @export("__udivsi3", __udivsi3, linkage); |
| 29 | pub const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak; | 41 | @export("__udivdi3", __udivdi3, linkage); |
| 30 | const strong_linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong; | 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 | |||
| 71 | const assert = @import("../../debug.zig").assert; | ||
| 31 | 72 | ||
| 32 | const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4; | 73 | const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4; |
| 33 | 74 | ||
| ... | @@ -41,15 +82,13 @@ pub coldcc fn panic(msg: []const u8) -> noreturn { | ... | @@ -41,15 +82,13 @@ pub coldcc fn panic(msg: []const u8) -> noreturn { |
| 41 | } | 82 | } |
| 42 | } | 83 | } |
| 43 | 84 | ||
| 44 | export fn __udivdi3(a: u64, b: u64) -> u64 { | 85 | extern fn __udivdi3(a: u64, b: u64) -> u64 { |
| 45 | @setDebugSafety(this, is_test); | 86 | @setDebugSafety(this, is_test); |
| 46 | @setGlobalLinkage(__udivdi3, linkage); | ||
| 47 | return __udivmoddi4(a, b, null); | 87 | return __udivmoddi4(a, b, null); |
| 48 | } | 88 | } |
| 49 | 89 | ||
| 50 | export fn __umoddi3(a: u64, b: u64) -> u64 { | 90 | extern fn __umoddi3(a: u64, b: u64) -> u64 { |
| 51 | @setDebugSafety(this, is_test); | 91 | @setDebugSafety(this, is_test); |
| 52 | @setGlobalLinkage(__umoddi3, linkage); | ||
| 53 | 92 | ||
| 54 | var r: u64 = undefined; | 93 | var r: u64 = undefined; |
| 55 | _ = __udivmoddi4(a, b, &r); | 94 | _ = __udivmoddi4(a, b, &r); |
| ... | @@ -60,17 +99,11 @@ const AeabiUlDivModResult = extern struct { | ... | @@ -60,17 +99,11 @@ const AeabiUlDivModResult = extern struct { |
| 60 | quot: u64, | 99 | quot: u64, |
| 61 | rem: u64, | 100 | rem: u64, |
| 62 | }; | 101 | }; |
| 63 | export fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult { | 102 | extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult { |
| 64 | @setDebugSafety(this, is_test); | 103 | @setDebugSafety(this, is_test); |
| 65 | if (comptime isArmArch()) { | 104 | var result: AeabiUlDivModResult = undefined; |
| 66 | @setGlobalLinkage(__aeabi_uldivmod, linkage); | 105 | result.quot = __udivmoddi4(numerator, denominator, &result.rem); |
| 67 | var result: AeabiUlDivModResult = undefined; | 106 | return result; |
| 68 | result.quot = __udivmoddi4(numerator, denominator, &result.rem); | ||
| 69 | return result; | ||
| 70 | } | ||
| 71 | |||
| 72 | @setGlobalLinkage(__aeabi_uldivmod, builtin.GlobalLinkage.Internal); | ||
| 73 | unreachable; | ||
| 74 | } | 107 | } |
| 75 | 108 | ||
| 76 | fn isArmArch() -> bool { | 109 | fn isArmArch() -> bool { |
| ... | @@ -98,156 +131,124 @@ fn isArmArch() -> bool { | ... | @@ -98,156 +131,124 @@ fn isArmArch() -> bool { |
| 98 | }; | 131 | }; |
| 99 | } | 132 | } |
| 100 | 133 | ||
| 101 | export nakedcc fn __aeabi_uidivmod() { | 134 | nakedcc fn __aeabi_uidivmod() { |
| 102 | @setDebugSafety(this, false); | 135 | @setDebugSafety(this, false); |
| 103 | 136 | asm volatile ( | |
| 104 | if (comptime isArmArch()) { | 137 | \\ push { lr } |
| 105 | @setGlobalLinkage(__aeabi_uidivmod, linkage); | 138 | \\ sub sp, sp, #4 |
| 106 | asm volatile ( | 139 | \\ mov r2, sp |
| 107 | \\ push { lr } | 140 | \\ bl __udivmodsi4 |
| 108 | \\ sub sp, sp, #4 | 141 | \\ ldr r1, [sp] |
| 109 | \\ mov r2, sp | 142 | \\ add sp, sp, #4 |
| 110 | \\ bl __udivmodsi4 | 143 | \\ pop { pc } |
| 111 | \\ ldr r1, [sp] | 144 | ::: "r2", "r1"); |
| 112 | \\ add sp, sp, #4 | ||
| 113 | \\ pop { pc } | ||
| 114 | ::: "r2", "r1"); | ||
| 115 | unreachable; | ||
| 116 | } | ||
| 117 | |||
| 118 | @setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.Internal); | ||
| 119 | } | 145 | } |
| 120 | 146 | ||
| 121 | // _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments, | 147 | // _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments, |
| 122 | // then decrement %esp by %eax. Preserves all registers except %esp and flags. | 148 | // then decrement %esp by %eax. Preserves all registers except %esp and flags. |
| 123 | // This routine is windows specific | 149 | // This routine is windows specific |
| 124 | // http://msdn.microsoft.com/en-us/library/ms648426.aspx | 150 | // http://msdn.microsoft.com/en-us/library/ms648426.aspx |
| 125 | export nakedcc fn _chkstk() align(4) { | 151 | nakedcc fn _chkstk() align(4) { |
| 126 | @setDebugSafety(this, false); | 152 | @setDebugSafety(this, false); |
| 127 | 153 | ||
| 128 | if (win32_nocrt) { | 154 | asm volatile ( |
| 129 | @setGlobalLinkage(_chkstk, strong_linkage); | 155 | \\ push %%ecx |
| 130 | asm volatile ( | 156 | \\ push %%eax |
| 131 | \\ push %%ecx | 157 | \\ cmp $0x1000,%%eax |
| 132 | \\ push %%eax | 158 | \\ lea 12(%%esp),%%ecx |
| 133 | \\ cmp $0x1000,%%eax | 159 | \\ jb 1f |
| 134 | \\ lea 12(%%esp),%%ecx | 160 | \\ 2: |
| 135 | \\ jb 1f | 161 | \\ sub $0x1000,%%ecx |
| 136 | \\ 2: | 162 | \\ test %%ecx,(%%ecx) |
| 137 | \\ sub $0x1000,%%ecx | 163 | \\ sub $0x1000,%%eax |
| 138 | \\ test %%ecx,(%%ecx) | 164 | \\ cmp $0x1000,%%eax |
| 139 | \\ sub $0x1000,%%eax | 165 | \\ ja 2b |
| 140 | \\ cmp $0x1000,%%eax | 166 | \\ 1: |
| 141 | \\ ja 2b | 167 | \\ sub %%eax,%%ecx |
| 142 | \\ 1: | 168 | \\ test %%ecx,(%%ecx) |
| 143 | \\ sub %%eax,%%ecx | 169 | \\ pop %%eax |
| 144 | \\ test %%ecx,(%%ecx) | 170 | \\ pop %%ecx |
| 145 | \\ pop %%eax | 171 | \\ ret |
| 146 | \\ pop %%ecx | 172 | ); |
| 147 | \\ ret | ||
| 148 | ); | ||
| 149 | unreachable; | ||
| 150 | } | ||
| 151 | |||
| 152 | @setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal); | ||
| 153 | } | 173 | } |
| 154 | 174 | ||
| 155 | export nakedcc fn __chkstk() align(4) { | 175 | nakedcc fn __chkstk() align(4) { |
| 156 | @setDebugSafety(this, false); | 176 | @setDebugSafety(this, false); |
| 157 | 177 | ||
| 158 | if (win64_nocrt) { | 178 | asm volatile ( |
| 159 | @setGlobalLinkage(__chkstk, strong_linkage); | 179 | \\ push %%rcx |
| 160 | asm volatile ( | 180 | \\ push %%rax |
| 161 | \\ push %%rcx | 181 | \\ cmp $0x1000,%%rax |
| 162 | \\ push %%rax | 182 | \\ lea 24(%%rsp),%%rcx |
| 163 | \\ cmp $0x1000,%%rax | 183 | \\ jb 1f |
| 164 | \\ lea 24(%%rsp),%%rcx | 184 | \\2: |
| 165 | \\ jb 1f | 185 | \\ sub $0x1000,%%rcx |
| 166 | \\2: | 186 | \\ test %%rcx,(%%rcx) |
| 167 | \\ sub $0x1000,%%rcx | 187 | \\ sub $0x1000,%%rax |
| 168 | \\ test %%rcx,(%%rcx) | 188 | \\ cmp $0x1000,%%rax |
| 169 | \\ sub $0x1000,%%rax | 189 | \\ ja 2b |
| 170 | \\ cmp $0x1000,%%rax | 190 | \\1: |
| 171 | \\ ja 2b | 191 | \\ sub %%rax,%%rcx |
| 172 | \\1: | 192 | \\ test %%rcx,(%%rcx) |
| 173 | \\ sub %%rax,%%rcx | 193 | \\ pop %%rax |
| 174 | \\ test %%rcx,(%%rcx) | 194 | \\ pop %%rcx |
| 175 | \\ pop %%rax | 195 | \\ ret |
| 176 | \\ pop %%rcx | 196 | ); |
| 177 | \\ ret | ||
| 178 | ); | ||
| 179 | unreachable; | ||
| 180 | } | ||
| 181 | |||
| 182 | @setGlobalLinkage(__chkstk, builtin.GlobalLinkage.Internal); | ||
| 183 | } | 197 | } |
| 184 | 198 | ||
| 185 | // _chkstk routine | 199 | // _chkstk routine |
| 186 | // This routine is windows specific | 200 | // This routine is windows specific |
| 187 | // http://msdn.microsoft.com/en-us/library/ms648426.aspx | 201 | // http://msdn.microsoft.com/en-us/library/ms648426.aspx |
| 188 | export nakedcc fn __chkstk_ms() align(4) { | 202 | nakedcc fn __chkstk_ms() align(4) { |
| 189 | @setDebugSafety(this, false); | 203 | @setDebugSafety(this, false); |
| 190 | 204 | ||
| 191 | if (win32_nocrt) { | 205 | asm volatile ( |
| 192 | @setGlobalLinkage(__chkstk_ms, linkage); | 206 | \\ push %%ecx |
| 193 | asm volatile ( | 207 | \\ push %%eax |
| 194 | \\ push %%ecx | 208 | \\ cmp $0x1000,%%eax |
| 195 | \\ push %%eax | 209 | \\ lea 12(%%esp),%%ecx |
| 196 | \\ cmp $0x1000,%%eax | 210 | \\ jb 1f |
| 197 | \\ lea 12(%%esp),%%ecx | 211 | \\ 2: |
| 198 | \\ jb 1f | 212 | \\ sub $0x1000,%%ecx |
| 199 | \\ 2: | 213 | \\ test %%ecx,(%%ecx) |
| 200 | \\ sub $0x1000,%%ecx | 214 | \\ sub $0x1000,%%eax |
| 201 | \\ test %%ecx,(%%ecx) | 215 | \\ cmp $0x1000,%%eax |
| 202 | \\ sub $0x1000,%%eax | 216 | \\ ja 2b |
| 203 | \\ cmp $0x1000,%%eax | 217 | \\ 1: |
| 204 | \\ ja 2b | 218 | \\ sub %%eax,%%ecx |
| 205 | \\ 1: | 219 | \\ test %%ecx,(%%ecx) |
| 206 | \\ sub %%eax,%%ecx | 220 | \\ pop %%eax |
| 207 | \\ test %%ecx,(%%ecx) | 221 | \\ pop %%ecx |
| 208 | \\ pop %%eax | 222 | \\ ret |
| 209 | \\ pop %%ecx | 223 | ); |
| 210 | \\ ret | ||
| 211 | ); | ||
| 212 | unreachable; | ||
| 213 | } | ||
| 214 | |||
| 215 | @setGlobalLinkage(__chkstk_ms, builtin.GlobalLinkage.Internal); | ||
| 216 | } | 224 | } |
| 217 | 225 | ||
| 218 | export nakedcc fn ___chkstk_ms() align(4) { | 226 | nakedcc fn ___chkstk_ms() align(4) { |
| 219 | @setDebugSafety(this, false); | 227 | @setDebugSafety(this, false); |
| 220 | 228 | ||
| 221 | if (win64_nocrt) { | 229 | asm volatile ( |
| 222 | @setGlobalLinkage(___chkstk_ms, linkage); | 230 | \\ push %%rcx |
| 223 | asm volatile ( | 231 | \\ push %%rax |
| 224 | \\ push %%rcx | 232 | \\ cmp $0x1000,%%rax |
| 225 | \\ push %%rax | 233 | \\ lea 24(%%rsp),%%rcx |
| 226 | \\ cmp $0x1000,%%rax | 234 | \\ jb 1f |
| 227 | \\ lea 24(%%rsp),%%rcx | 235 | \\2: |
| 228 | \\ jb 1f | 236 | \\ sub $0x1000,%%rcx |
| 229 | \\2: | 237 | \\ test %%rcx,(%%rcx) |
| 230 | \\ sub $0x1000,%%rcx | 238 | \\ sub $0x1000,%%rax |
| 231 | \\ test %%rcx,(%%rcx) | 239 | \\ cmp $0x1000,%%rax |
| 232 | \\ sub $0x1000,%%rax | 240 | \\ ja 2b |
| 233 | \\ cmp $0x1000,%%rax | 241 | \\1: |
| 234 | \\ ja 2b | 242 | \\ sub %%rax,%%rcx |
| 235 | \\1: | 243 | \\ test %%rcx,(%%rcx) |
| 236 | \\ sub %%rax,%%rcx | 244 | \\ pop %%rax |
| 237 | \\ test %%rcx,(%%rcx) | 245 | \\ pop %%rcx |
| 238 | \\ pop %%rax | 246 | \\ ret |
| 239 | \\ pop %%rcx | 247 | ); |
| 240 | \\ ret | ||
| 241 | ); | ||
| 242 | unreachable; | ||
| 243 | } | ||
| 244 | |||
| 245 | @setGlobalLinkage(___chkstk_ms, builtin.GlobalLinkage.Internal); | ||
| 246 | } | 248 | } |
| 247 | 249 | ||
| 248 | export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 { | 250 | extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 { |
| 249 | @setDebugSafety(this, is_test); | 251 | @setDebugSafety(this, is_test); |
| 250 | @setGlobalLinkage(__udivmodsi4, linkage); | ||
| 251 | 252 | ||
| 252 | const d = __udivsi3(a, b); | 253 | const d = __udivsi3(a, b); |
| 253 | *rem = u32(i32(a) -% (i32(d) * i32(b))); | 254 | *rem = u32(i32(a) -% (i32(d) * i32(b))); |
| ... | @@ -255,19 +256,8 @@ export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 { | ... | @@ -255,19 +256,8 @@ export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 { |
| 255 | } | 256 | } |
| 256 | 257 | ||
| 257 | 258 | ||
| 258 | // TODO make this an alias instead of an extra function call | 259 | extern fn __udivsi3(n: u32, d: u32) -> u32 { |
| 259 | // https://github.com/andrewrk/zig/issues/256 | ||
| 260 | |||
| 261 | export fn __aeabi_uidiv(n: u32, d: u32) -> u32 { | ||
| 262 | @setDebugSafety(this, is_test); | 260 | @setDebugSafety(this, is_test); |
| 263 | @setGlobalLinkage(__aeabi_uidiv, linkage); | ||
| 264 | |||
| 265 | return __udivsi3(n, d); | ||
| 266 | } | ||
| 267 | |||
| 268 | export fn __udivsi3(n: u32, d: u32) -> u32 { | ||
| 269 | @setDebugSafety(this, is_test); | ||
| 270 | @setGlobalLinkage(__udivsi3, linkage); | ||
| 271 | 261 | ||
| 272 | const n_uword_bits: c_uint = u32.bit_count; | 262 | const n_uword_bits: c_uint = u32.bit_count; |
| 273 | // special cases | 263 | // special cases |
| ... | @@ -463,4 +453,3 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) { | ... | @@ -463,4 +453,3 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) { |
| 463 | const q: u32 = __udivsi3(a, b); | 453 | const q: u32 = __udivsi3(a, b); |
| 464 | assert(q == expected_q); | 454 | assert(q == expected_q); |
| 465 | } | 455 | } |
| 466 |
std/special/compiler_rt/udivmoddi4.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const udivmod = @import("udivmod.zig").udivmod; | 1 | const udivmod = @import("udivmod.zig").udivmod; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 { | 4 | pub extern fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__udivmoddi4, linkage); | ||
| 8 | return udivmod(u64, a, b, maybe_rem); | 6 | return udivmod(u64, a, b, maybe_rem); |
| 9 | } | 7 | } |
| 10 | 8 |
std/special/compiler_rt/udivmodti4.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const udivmod = @import("udivmod.zig").udivmod; | 1 | const udivmod = @import("udivmod.zig").udivmod; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 { | 4 | pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__udivmodti4, linkage); | ||
| 8 | return udivmod(u128, a, b, maybe_rem); | 6 | return udivmod(u128, a, b, maybe_rem); |
| 9 | } | 7 | } |
| 10 | 8 |
std/special/compiler_rt/udivti3.zig+1-3| ... | @@ -1,9 +1,7 @@ | ... | @@ -1,9 +1,7 @@ |
| 1 | const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4; | 1 | const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __udivti3(a: u128, b: u128) -> u128 { | 4 | pub extern fn __udivti3(a: u128, b: u128) -> u128 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__udivti3, linkage); | ||
| 8 | return __udivmodti4(a, b, null); | 6 | return __udivmodti4(a, b, null); |
| 9 | } | 7 | } |
std/special/compiler_rt/umodti3.zig+1-3| ... | @@ -1,10 +1,8 @@ | ... | @@ -1,10 +1,8 @@ |
| 1 | const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4; | 1 | const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4; |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = @import("index.zig").linkage; | ||
| 4 | 3 | ||
| 5 | export fn __umodti3(a: u128, b: u128) -> u128 { | 4 | pub extern fn __umodti3(a: u128, b: u128) -> u128 { |
| 6 | @setDebugSafety(this, builtin.is_test); | 5 | @setDebugSafety(this, builtin.is_test); |
| 7 | @setGlobalLinkage(__umodti3, linkage); | ||
| 8 | var r: u128 = undefined; | 6 | var r: u128 = undefined; |
| 9 | _ = __udivmodti4(a, b, &r); | 7 | _ = __udivmodti4(a, b, &r); |
| 10 | return r; | 8 | return r; |
test/cases/misc.zig+5-2| ... | @@ -12,8 +12,11 @@ test "empty function with comments" { | ... | @@ -12,8 +12,11 @@ test "empty function with comments" { |
| 12 | emptyFunctionWithComments(); | 12 | emptyFunctionWithComments(); |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | export fn disabledExternFn() { | 15 | comptime { |
| 16 | @setGlobalLinkage(disabledExternFn, builtin.GlobalLinkage.Internal); | 16 | @export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal); |
| 17 | } | ||
| 18 | |||
| 19 | extern fn disabledExternFn() { | ||
| 17 | } | 20 | } |
| 18 | 21 | ||
| 19 | test "call disabled extern fn" { | 22 | test "call disabled extern fn" { |
test/compile_errors.zig+24-17| ... | @@ -1468,7 +1468,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { | ... | @@ -1468,7 +1468,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1468 | \\} | 1468 | \\} |
| 1469 | , | 1469 | , |
| 1470 | "foo.zig:1:8: error: exported symbol collision: 'bar'", | 1470 | "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"); |
| 1472 | 1472 | ||
| 1473 | tc.addSourceFile("foo.zig", | 1473 | tc.addSourceFile("foo.zig", |
| 1474 | \\export fn bar() {} | 1474 | \\export fn bar() {} |
| ... | @@ -1611,23 +1611,29 @@ pub fn addCases(cases: &tests.CompileErrorContext) { | ... | @@ -1611,23 +1611,29 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1611 | "error: 'main' is private", | 1611 | "error: 'main' is private", |
| 1612 | ".tmp_source.zig:1:1: note: declared here"); | 1612 | ".tmp_source.zig:1:1: note: declared here"); |
| 1613 | 1613 | ||
| 1614 | cases.add("@setGlobalSection extern variable", | 1614 | cases.add("setting a section on an extern variable", |
| 1615 | \\extern var foo: i32; | 1615 | \\extern var foo: i32 section(".text2"); |
| 1616 | \\comptime { | 1616 | \\export fn entry() -> i32 { |
| 1617 | \\ @setGlobalSection(foo, ".text2"); | 1617 | \\ return foo; |
| 1618 | \\} | 1618 | \\} |
| 1619 | , | 1619 | , |
| 1620 | ".tmp_source.zig:3:5: error: cannot set section of external variable 'foo'", | 1620 | ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'"); |
| 1621 | ".tmp_source.zig:1:8: note: declared here"); | ||
| 1622 | 1621 | ||
| 1623 | cases.add("@setGlobalSection extern fn", | 1622 | cases.add("setting a section on a local variable", |
| 1624 | \\extern fn foo(); | 1623 | \\export fn entry() -> i32 { |
| 1625 | \\comptime { | 1624 | \\ var foo: i32 section(".text2") = 1234; |
| 1626 | \\ @setGlobalSection(foo, ".text2"); | 1625 | \\ return foo; |
| 1627 | \\} | 1626 | \\} |
| 1628 | , | 1627 | , |
| 1629 | ".tmp_source.zig:3:5: error: cannot set section of external function 'foo'", | 1628 | ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'"); |
| 1630 | ".tmp_source.zig:1:8: note: declared here"); | 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'"); | ||
| 1631 | 1637 | ||
| 1632 | cases.add("returning address of local variable - simple", | 1638 | cases.add("returning address of local variable - simple", |
| 1633 | \\export fn foo() -> &i32 { | 1639 | \\export fn foo() -> &i32 { |
| ... | @@ -2120,12 +2126,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) { | ... | @@ -2120,12 +2126,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2120 | , | 2126 | , |
| 2121 | ".tmp_source.zig:3:41: error: expected type 'AtomicOrder', found 'u32'"); | 2127 | ".tmp_source.zig:3:41: error: expected type 'AtomicOrder', found 'u32'"); |
| 2122 | 2128 | ||
| 2123 | cases.add("wrong types given to setGlobalLinkage", | 2129 | cases.add("wrong types given to @export", |
| 2124 | \\export fn entry() { | 2130 | \\extern fn entry() { } |
| 2125 | \\ @setGlobalLinkage(entry, u32(1234)); | 2131 | \\comptime { |
| 2132 | \\ @export("entry", entry, u32(1234)); | ||
| 2126 | \\} | 2133 | \\} |
| 2127 | , | 2134 | , |
| 2128 | ".tmp_source.zig:2:33: error: expected type 'GlobalLinkage', found 'u32'"); | 2135 | ".tmp_source.zig:3:32: error: expected type 'GlobalLinkage', found 'u32'"); |
| 2129 | 2136 | ||
| 2130 | cases.add("struct with invalid field", | 2137 | cases.add("struct with invalid field", |
| 2131 | \\const std = @import("std"); | 2138 | \\const std = @import("std"); |
test/translate_c.zig+31-31| ... | @@ -325,12 +325,12 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -325,12 +325,12 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 325 | \\ return a; | 325 | \\ return a; |
| 326 | \\} | 326 | \\} |
| 327 | , | 327 | , |
| 328 | \\export fn foo1(_arg_a: c_uint) -> c_uint { | 328 | \\pub export fn foo1(_arg_a: c_uint) -> c_uint { |
| 329 | \\ var a = _arg_a; | 329 | \\ var a = _arg_a; |
| 330 | \\ a +%= 1; | 330 | \\ a +%= 1; |
| 331 | \\ return a; | 331 | \\ return a; |
| 332 | \\} | 332 | \\} |
| 333 | \\export fn foo2(_arg_a: c_int) -> c_int { | 333 | \\pub export fn foo2(_arg_a: c_int) -> c_int { |
| 334 | \\ var a = _arg_a; | 334 | \\ var a = _arg_a; |
| 335 | \\ a += 1; | 335 | \\ a += 1; |
| 336 | \\ return a; | 336 | \\ return a; |
| ... | @@ -346,7 +346,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -346,7 +346,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 346 | \\ return i; | 346 | \\ return i; |
| 347 | \\} | 347 | \\} |
| 348 | , | 348 | , |
| 349 | \\export fn log2(_arg_a: c_uint) -> c_int { | 349 | \\pub export fn log2(_arg_a: c_uint) -> c_int { |
| 350 | \\ var a = _arg_a; | 350 | \\ var a = _arg_a; |
| 351 | \\ var i: c_int = 0; | 351 | \\ var i: c_int = 0; |
| 352 | \\ while (a > c_uint(0)) { | 352 | \\ while (a > c_uint(0)) { |
| ... | @@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 367 | \\ return a; | 367 | \\ return a; |
| 368 | \\} | 368 | \\} |
| 369 | , | 369 | , |
| 370 | \\export fn max(a: c_int, b: c_int) -> c_int { | 370 | \\pub export fn max(a: c_int, b: c_int) -> c_int { |
| 371 | \\ if (a < b) return b; | 371 | \\ if (a < b) return b; |
| 372 | \\ if (a < b) return b else return a; | 372 | \\ if (a < b) return b else return a; |
| 373 | \\} | 373 | \\} |
| ... | @@ -382,7 +382,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -382,7 +382,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 382 | \\ return a; | 382 | \\ return a; |
| 383 | \\} | 383 | \\} |
| 384 | , | 384 | , |
| 385 | \\export fn max(a: c_int, b: c_int) -> c_int { | 385 | \\pub export fn max(a: c_int, b: c_int) -> c_int { |
| 386 | \\ if (a == b) return a; | 386 | \\ if (a == b) return a; |
| 387 | \\ if (a != b) return b; | 387 | \\ if (a != b) return b; |
| 388 | \\ return a; | 388 | \\ return a; |
| ... | @@ -407,7 +407,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -407,7 +407,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 407 | \\ c = a % b; | 407 | \\ c = a % b; |
| 408 | \\} | 408 | \\} |
| 409 | , | 409 | , |
| 410 | \\export fn s(a: c_int, b: c_int) -> c_int { | 410 | \\pub export fn s(a: c_int, b: c_int) -> c_int { |
| 411 | \\ var c: c_int; | 411 | \\ var c: c_int; |
| 412 | \\ c = (a + b); | 412 | \\ c = (a + b); |
| 413 | \\ c = (a - b); | 413 | \\ c = (a - b); |
| ... | @@ -415,7 +415,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -415,7 +415,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 415 | \\ c = @divTrunc(a, b); | 415 | \\ c = @divTrunc(a, b); |
| 416 | \\ c = @rem(a, b); | 416 | \\ c = @rem(a, b); |
| 417 | \\} | 417 | \\} |
| 418 | \\export fn u(a: c_uint, b: c_uint) -> c_uint { | 418 | \\pub export fn u(a: c_uint, b: c_uint) -> c_uint { |
| 419 | \\ var c: c_uint; | 419 | \\ var c: c_uint; |
| 420 | \\ c = (a +% b); | 420 | \\ c = (a +% b); |
| 421 | \\ c = (a -% b); | 421 | \\ c = (a -% b); |
| ... | @@ -430,7 +430,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -430,7 +430,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 430 | \\ return (a & b) ^ (a | b); | 430 | \\ return (a & b) ^ (a | b); |
| 431 | \\} | 431 | \\} |
| 432 | , | 432 | , |
| 433 | \\export fn max(a: c_int, b: c_int) -> c_int { | 433 | \\pub export fn max(a: c_int, b: c_int) -> c_int { |
| 434 | \\ return (a & b) ^ (a | b); | 434 | \\ return (a & b) ^ (a | b); |
| 435 | \\} | 435 | \\} |
| 436 | ); | 436 | ); |
| ... | @@ -444,7 +444,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -444,7 +444,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 444 | \\ return a; | 444 | \\ return a; |
| 445 | \\} | 445 | \\} |
| 446 | , | 446 | , |
| 447 | \\export fn max(a: c_int, b: c_int) -> c_int { | 447 | \\pub export fn max(a: c_int, b: c_int) -> c_int { |
| 448 | \\ if ((a < b) or (a == b)) return b; | 448 | \\ if ((a < b) or (a == b)) return b; |
| 449 | \\ if ((a >= b) and (a == b)) return a; | 449 | \\ if ((a >= b) and (a == b)) return a; |
| 450 | \\ return a; | 450 | \\ return a; |
| ... | @@ -458,7 +458,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -458,7 +458,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 458 | \\ a = tmp; | 458 | \\ a = tmp; |
| 459 | \\} | 459 | \\} |
| 460 | , | 460 | , |
| 461 | \\export fn max(_arg_a: c_int) -> c_int { | 461 | \\pub export fn max(_arg_a: c_int) -> c_int { |
| 462 | \\ var a = _arg_a; | 462 | \\ var a = _arg_a; |
| 463 | \\ var tmp: c_int; | 463 | \\ var tmp: c_int; |
| 464 | \\ tmp = a; | 464 | \\ tmp = a; |
| ... | @@ -472,7 +472,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -472,7 +472,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 472 | \\ c = b = a; | 472 | \\ c = b = a; |
| 473 | \\} | 473 | \\} |
| 474 | , | 474 | , |
| 475 | \\export fn max(a: c_int) { | 475 | \\pub export fn max(a: c_int) { |
| 476 | \\ var b: c_int; | 476 | \\ var b: c_int; |
| 477 | \\ var c: c_int; | 477 | \\ var c: c_int; |
| 478 | \\ c = { | 478 | \\ c = { |
| ... | @@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 493 | \\ return i; | 493 | \\ return i; |
| 494 | \\} | 494 | \\} |
| 495 | , | 495 | , |
| 496 | \\export fn log2(_arg_a: u32) -> c_int { | 496 | \\pub export fn log2(_arg_a: u32) -> c_int { |
| 497 | \\ var a = _arg_a; | 497 | \\ var a = _arg_a; |
| 498 | \\ var i: c_int = 0; | 498 | \\ var i: c_int = 0; |
| 499 | \\ while (a > c_uint(0)) { | 499 | \\ while (a > c_uint(0)) { |
| ... | @@ -518,7 +518,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -518,7 +518,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 518 | \\void foo(void) { bar(); } | 518 | \\void foo(void) { bar(); } |
| 519 | , | 519 | , |
| 520 | \\pub fn bar() {} | 520 | \\pub fn bar() {} |
| 521 | \\export fn foo() { | 521 | \\pub export fn foo() { |
| 522 | \\ bar(); | 522 | \\ bar(); |
| 523 | \\} | 523 | \\} |
| 524 | ); | 524 | ); |
| ... | @@ -534,7 +534,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -534,7 +534,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 534 | \\pub const struct_Foo = extern struct { | 534 | \\pub const struct_Foo = extern struct { |
| 535 | \\ field: c_int, | 535 | \\ field: c_int, |
| 536 | \\}; | 536 | \\}; |
| 537 | \\export fn read_field(foo: ?&struct_Foo) -> c_int { | 537 | \\pub export fn read_field(foo: ?&struct_Foo) -> c_int { |
| 538 | \\ return (??foo).field; | 538 | \\ return (??foo).field; |
| 539 | \\} | 539 | \\} |
| 540 | ); | 540 | ); |
| ... | @@ -544,7 +544,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -544,7 +544,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 544 | \\ ;;;;; | 544 | \\ ;;;;; |
| 545 | \\} | 545 | \\} |
| 546 | , | 546 | , |
| 547 | \\export fn foo() {} | 547 | \\pub export fn foo() {} |
| 548 | ); | 548 | ); |
| 549 | 549 | ||
| 550 | cases.add("undefined array global", | 550 | cases.add("undefined array global", |
| ... | @@ -560,7 +560,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -560,7 +560,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 560 | \\} | 560 | \\} |
| 561 | , | 561 | , |
| 562 | \\pub var array: [100]c_int = undefined; | 562 | \\pub var array: [100]c_int = undefined; |
| 563 | \\export fn foo(index: c_int) -> c_int { | 563 | \\pub export fn foo(index: c_int) -> c_int { |
| 564 | \\ return array[index]; | 564 | \\ return array[index]; |
| 565 | \\} | 565 | \\} |
| 566 | ); | 566 | ); |
| ... | @@ -571,7 +571,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -571,7 +571,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 571 | \\ return (int)a; | 571 | \\ return (int)a; |
| 572 | \\} | 572 | \\} |
| 573 | , | 573 | , |
| 574 | \\export fn float_to_int(a: f32) -> c_int { | 574 | \\pub export fn float_to_int(a: f32) -> c_int { |
| 575 | \\ return c_int(a); | 575 | \\ return c_int(a); |
| 576 | \\} | 576 | \\} |
| 577 | ); | 577 | ); |
| ... | @@ -581,7 +581,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -581,7 +581,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 581 | \\ return x; | 581 | \\ return x; |
| 582 | \\} | 582 | \\} |
| 583 | , | 583 | , |
| 584 | \\export fn foo(x: ?&c_ushort) -> ?&c_void { | 584 | \\pub export fn foo(x: ?&c_ushort) -> ?&c_void { |
| 585 | \\ return @ptrCast(?&c_void, x); | 585 | \\ return @ptrCast(?&c_void, x); |
| 586 | \\} | 586 | \\} |
| 587 | ); | 587 | ); |
| ... | @@ -592,7 +592,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -592,7 +592,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 592 | \\ return sizeof(int); | 592 | \\ return sizeof(int); |
| 593 | \\} | 593 | \\} |
| 594 | , | 594 | , |
| 595 | \\export fn size_of() -> usize { | 595 | \\pub export fn size_of() -> usize { |
| 596 | \\ return @sizeOf(c_int); | 596 | \\ return @sizeOf(c_int); |
| 597 | \\} | 597 | \\} |
| 598 | ); | 598 | ); |
| ... | @@ -602,7 +602,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -602,7 +602,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 602 | \\ return 0; | 602 | \\ return 0; |
| 603 | \\} | 603 | \\} |
| 604 | , | 604 | , |
| 605 | \\export fn foo() -> ?&c_int { | 605 | \\pub export fn foo() -> ?&c_int { |
| 606 | \\ return null; | 606 | \\ return null; |
| 607 | \\} | 607 | \\} |
| 608 | ); | 608 | ); |
| ... | @@ -612,7 +612,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -612,7 +612,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 612 | \\ return 1, 2; | 612 | \\ return 1, 2; |
| 613 | \\} | 613 | \\} |
| 614 | , | 614 | , |
| 615 | \\export fn foo() -> c_int { | 615 | \\pub export fn foo() -> c_int { |
| 616 | \\ return { | 616 | \\ return { |
| 617 | \\ _ = 1; | 617 | \\ _ = 1; |
| 618 | \\ 2 | 618 | \\ 2 |
| ... | @@ -625,7 +625,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -625,7 +625,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 625 | \\ return (1 << 2) >> 1; | 625 | \\ return (1 << 2) >> 1; |
| 626 | \\} | 626 | \\} |
| 627 | , | 627 | , |
| 628 | \\export fn foo() -> c_int { | 628 | \\pub export fn foo() -> c_int { |
| 629 | \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1); | 629 | \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1); |
| 630 | \\} | 630 | \\} |
| 631 | ); | 631 | ); |
| ... | @@ -643,7 +643,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -643,7 +643,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 643 | \\ a <<= (a <<= 1); | 643 | \\ a <<= (a <<= 1); |
| 644 | \\} | 644 | \\} |
| 645 | , | 645 | , |
| 646 | \\export fn foo() { | 646 | \\pub export fn foo() { |
| 647 | \\ var a: c_int = 0; | 647 | \\ var a: c_int = 0; |
| 648 | \\ a += { | 648 | \\ a += { |
| 649 | \\ const _ref = &a; | 649 | \\ const _ref = &a; |
| ... | @@ -701,7 +701,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -701,7 +701,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 701 | \\ a <<= (a <<= 1); | 701 | \\ a <<= (a <<= 1); |
| 702 | \\} | 702 | \\} |
| 703 | , | 703 | , |
| 704 | \\export fn foo() { | 704 | \\pub export fn foo() { |
| 705 | \\ var a: c_uint = c_uint(0); | 705 | \\ var a: c_uint = c_uint(0); |
| 706 | \\ a +%= { | 706 | \\ a +%= { |
| 707 | \\ const _ref = &a; | 707 | \\ const _ref = &a; |
| ... | @@ -771,7 +771,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -771,7 +771,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 771 | \\ u = u--; | 771 | \\ u = u--; |
| 772 | \\} | 772 | \\} |
| 773 | , | 773 | , |
| 774 | \\export fn foo() { | 774 | \\pub export fn foo() { |
| 775 | \\ var i: c_int = 0; | 775 | \\ var i: c_int = 0; |
| 776 | \\ var u: c_uint = c_uint(0); | 776 | \\ var u: c_uint = c_uint(0); |
| 777 | \\ i += 1; | 777 | \\ i += 1; |
| ... | @@ -819,7 +819,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -819,7 +819,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 819 | \\ u = --u; | 819 | \\ u = --u; |
| 820 | \\} | 820 | \\} |
| 821 | , | 821 | , |
| 822 | \\export fn foo() { | 822 | \\pub export fn foo() { |
| 823 | \\ var i: c_int = 0; | 823 | \\ var i: c_int = 0; |
| 824 | \\ var u: c_uint = c_uint(0); | 824 | \\ var u: c_uint = c_uint(0); |
| 825 | \\ i += 1; | 825 | \\ i += 1; |
| ... | @@ -862,7 +862,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -862,7 +862,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 862 | \\ while (b != 0); | 862 | \\ while (b != 0); |
| 863 | \\} | 863 | \\} |
| 864 | , | 864 | , |
| 865 | \\export fn foo() { | 865 | \\pub export fn foo() { |
| 866 | \\ var a: c_int = 2; | 866 | \\ var a: c_int = 2; |
| 867 | \\ while (true) { | 867 | \\ while (true) { |
| 868 | \\ a -= 1; | 868 | \\ a -= 1; |
| ... | @@ -886,9 +886,9 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -886,9 +886,9 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 886 | \\ baz(); | 886 | \\ baz(); |
| 887 | \\} | 887 | \\} |
| 888 | , | 888 | , |
| 889 | \\export fn foo() {} | 889 | \\pub export fn foo() {} |
| 890 | \\export fn baz() {} | 890 | \\pub export fn baz() {} |
| 891 | \\export fn bar() { | 891 | \\pub export fn bar() { |
| 892 | \\ var f: ?extern fn() = foo; | 892 | \\ var f: ?extern fn() = foo; |
| 893 | \\ (??f)(); | 893 | \\ (??f)(); |
| 894 | \\ (??f)(); | 894 | \\ (??f)(); |
| ... | @@ -901,7 +901,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { | ... | @@ -901,7 +901,7 @@ pub fn addCases(cases: &tests.TranslateCContext) { |
| 901 | \\ *x = 1; | 901 | \\ *x = 1; |
| 902 | \\} | 902 | \\} |
| 903 | , | 903 | , |
| 904 | \\export fn foo(x: ?&c_int) { | 904 | \\pub export fn foo(x: ?&c_int) { |
| 905 | \\ (*??x) = 1; | 905 | \\ (*??x) = 1; |
| 906 | \\} | 906 | \\} |
| 907 | ); | 907 | ); |