| author | |
| committer | |
| log | 2dd85d52cc4c4c6a32704f187b41a06401400f0c |
| tree | 9bb2423234eede3297d266c151f49bf89c0a89f0 |
| parent | 3cfbec3eef3e5949a457120287298233978cb236 |
libc hello world works now10 files changed, 663 insertions(+), 478 deletions(-)
src/all_types.hpp+30-1| ... | @@ -53,6 +53,7 @@ struct IrExecutable { | ... | @@ -53,6 +53,7 @@ struct IrExecutable { |
| 53 | ZigList<IrGotoItem> goto_list; | 53 | ZigList<IrGotoItem> goto_list; |
| 54 | bool is_inline; | 54 | bool is_inline; |
| 55 | FnTableEntry *fn_entry; | 55 | FnTableEntry *fn_entry; |
| 56 | Buf *c_import_buf; | ||
| 56 | }; | 57 | }; |
| 57 | 58 | ||
| 58 | enum OutType { | 59 | enum OutType { |
| ... | @@ -1226,6 +1227,7 @@ struct VariableTableEntry { | ... | @@ -1226,6 +1227,7 @@ struct VariableTableEntry { |
| 1226 | size_t mem_slot_index; | 1227 | size_t mem_slot_index; |
| 1227 | size_t ref_count; | 1228 | size_t ref_count; |
| 1228 | ConstExprValue *value; | 1229 | ConstExprValue *value; |
| 1230 | bool is_extern; | ||
| 1229 | }; | 1231 | }; |
| 1230 | 1232 | ||
| 1231 | struct ErrorTableEntry { | 1233 | struct ErrorTableEntry { |
| ... | @@ -1307,7 +1309,7 @@ struct ScopeVarDecl { | ... | @@ -1307,7 +1309,7 @@ struct ScopeVarDecl { |
| 1307 | struct ScopeCImport { | 1309 | struct ScopeCImport { |
| 1308 | Scope base; | 1310 | Scope base; |
| 1309 | 1311 | ||
| 1310 | Buf c_import_buf; | 1312 | Buf buf; |
| 1311 | }; | 1313 | }; |
| 1312 | 1314 | ||
| 1313 | // This scope is created for a loop such as for or while in order to | 1315 | // This scope is created for a loop such as for or while in order to |
| ... | @@ -1394,6 +1396,10 @@ enum IrInstructionId { | ... | @@ -1394,6 +1396,10 @@ enum IrInstructionId { |
| 1394 | IrInstructionIdCtz, | 1396 | IrInstructionIdCtz, |
| 1395 | IrInstructionIdStaticEval, | 1397 | IrInstructionIdStaticEval, |
| 1396 | IrInstructionIdImport, | 1398 | IrInstructionIdImport, |
| 1399 | IrInstructionIdCImport, | ||
| 1400 | IrInstructionIdCInclude, | ||
| 1401 | IrInstructionIdCDefine, | ||
| 1402 | IrInstructionIdCUndef, | ||
| 1397 | IrInstructionIdArrayLen, | 1403 | IrInstructionIdArrayLen, |
| 1398 | IrInstructionIdRef, | 1404 | IrInstructionIdRef, |
| 1399 | IrInstructionIdMinValue, | 1405 | IrInstructionIdMinValue, |
| ... | @@ -1823,6 +1829,29 @@ struct IrInstructionErrName { | ... | @@ -1823,6 +1829,29 @@ struct IrInstructionErrName { |
| 1823 | IrInstruction *value; | 1829 | IrInstruction *value; |
| 1824 | }; | 1830 | }; |
| 1825 | 1831 | ||
| 1832 | struct IrInstructionCImport { | ||
| 1833 | IrInstruction base; | ||
| 1834 | }; | ||
| 1835 | |||
| 1836 | struct IrInstructionCInclude { | ||
| 1837 | IrInstruction base; | ||
| 1838 | |||
| 1839 | IrInstruction *name; | ||
| 1840 | }; | ||
| 1841 | |||
| 1842 | struct IrInstructionCDefine { | ||
| 1843 | IrInstruction base; | ||
| 1844 | |||
| 1845 | IrInstruction *name; | ||
| 1846 | IrInstruction *value; | ||
| 1847 | }; | ||
| 1848 | |||
| 1849 | struct IrInstructionCUndef { | ||
| 1850 | IrInstruction base; | ||
| 1851 | |||
| 1852 | IrInstruction *name; | ||
| 1853 | }; | ||
| 1854 | |||
| 1826 | enum LValPurpose { | 1855 | enum LValPurpose { |
| 1827 | LValPurposeNone, | 1856 | LValPurposeNone, |
| 1828 | LValPurposeAssign, | 1857 | LValPurposeAssign, |
src/analyze.cpp+81-19| ... | @@ -13,7 +13,6 @@ | ... | @@ -13,7 +13,6 @@ |
| 13 | #include "ir.hpp" | 13 | #include "ir.hpp" |
| 14 | #include "ir_print.hpp" | 14 | #include "ir_print.hpp" |
| 15 | #include "os.hpp" | 15 | #include "os.hpp" |
| 16 | #include "parseh.hpp" | ||
| 17 | #include "parser.hpp" | 16 | #include "parser.hpp" |
| 18 | #include "zig_llvm.hpp" | 17 | #include "zig_llvm.hpp" |
| 19 | 18 | ||
| ... | @@ -136,8 +135,8 @@ void init_scope(Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) { | ... | @@ -136,8 +135,8 @@ void init_scope(Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) { |
| 136 | dest->parent = parent; | 135 | dest->parent = parent; |
| 137 | } | 136 | } |
| 138 | 137 | ||
| 139 | static ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *container_type, ImportTableEntry *import) { | 138 | ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *container_type, ImportTableEntry *import) { |
| 140 | assert(node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl); | 139 | assert(node == nullptr || node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr); |
| 141 | ScopeDecls *scope = allocate<ScopeDecls>(1); | 140 | ScopeDecls *scope = allocate<ScopeDecls>(1); |
| 142 | init_scope(&scope->base, ScopeIdDecls, node, parent); | 141 | init_scope(&scope->base, ScopeIdDecls, node, parent); |
| 143 | scope->decl_table.init(4); | 142 | scope->decl_table.init(4); |
| ... | @@ -168,12 +167,12 @@ Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var) { | ... | @@ -168,12 +167,12 @@ Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var) { |
| 168 | return &scope->base; | 167 | return &scope->base; |
| 169 | } | 168 | } |
| 170 | 169 | ||
| 171 | Scope *create_cimport_scope(AstNode *node, Scope *parent) { | 170 | ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent) { |
| 172 | assert(node->type == NodeTypeFnCallExpr); | 171 | assert(node->type == NodeTypeFnCallExpr); |
| 173 | ScopeCImport *scope = allocate<ScopeCImport>(1); | 172 | ScopeCImport *scope = allocate<ScopeCImport>(1); |
| 174 | init_scope(&scope->base, ScopeIdCImport, node, parent); | 173 | init_scope(&scope->base, ScopeIdCImport, node, parent); |
| 175 | buf_resize(&scope->c_import_buf, 0); | 174 | buf_resize(&scope->buf, 0); |
| 176 | return &scope->base; | 175 | return scope; |
| 177 | } | 176 | } |
| 178 | 177 | ||
| 179 | Scope *create_loop_scope(AstNode *node, Scope *parent) { | 178 | Scope *create_loop_scope(AstNode *node, Scope *parent) { |
| ... | @@ -877,7 +876,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *nod | ... | @@ -877,7 +876,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *nod |
| 877 | size_t backward_branch_count = 0; | 876 | size_t backward_branch_count = 0; |
| 878 | return ir_eval_const_value(g, scope, node, type_entry, | 877 | return ir_eval_const_value(g, scope, node, type_entry, |
| 879 | &backward_branch_count, default_backward_branch_quota, | 878 | &backward_branch_count, default_backward_branch_quota, |
| 880 | nullptr); | 879 | nullptr, nullptr); |
| 881 | } | 880 | } |
| 882 | 881 | ||
| 883 | TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { | 882 | TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { |
| ... | @@ -1367,21 +1366,31 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) { | ... | @@ -1367,21 +1366,31 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) { |
| 1367 | } | 1366 | } |
| 1368 | } | 1367 | } |
| 1369 | 1368 | ||
| 1370 | FnTableEntry *create_fn(CodeGen *g, AstNode *proto_node) { | 1369 | FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage) { |
| 1370 | FnTableEntry *fn_entry = allocate<FnTableEntry>(1); | ||
| 1371 | |||
| 1372 | fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc; | ||
| 1373 | fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota; | ||
| 1374 | fn_entry->analyzed_executable.fn_entry = fn_entry; | ||
| 1375 | fn_entry->ir_executable.fn_entry = fn_entry; | ||
| 1376 | fn_entry->fn_inline = inline_value; | ||
| 1377 | fn_entry->internal_linkage = internal_linkage; | ||
| 1378 | |||
| 1379 | return fn_entry; | ||
| 1380 | } | ||
| 1381 | |||
| 1382 | FnTableEntry *create_fn(AstNode *proto_node) { | ||
| 1371 | assert(proto_node->type == NodeTypeFnProto); | 1383 | assert(proto_node->type == NodeTypeFnProto); |
| 1372 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; | 1384 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; |
| 1373 | 1385 | ||
| 1374 | FnTableEntry *fn_table_entry = allocate<FnTableEntry>(1); | 1386 | FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto; |
| 1375 | fn_table_entry->analyzed_executable.backward_branch_count = &fn_table_entry->prealloc_bbc; | 1387 | bool internal_linkage = (fn_proto->visib_mod != VisibModExport); |
| 1376 | fn_table_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota; | 1388 | FnTableEntry *fn_entry = create_fn_raw(inline_value, internal_linkage); |
| 1377 | fn_table_entry->analyzed_executable.fn_entry = fn_table_entry; | 1389 | |
| 1378 | fn_table_entry->ir_executable.fn_entry = fn_table_entry; | 1390 | fn_entry->proto_node = proto_node; |
| 1379 | fn_table_entry->proto_node = proto_node; | 1391 | fn_entry->fn_def_node = proto_node->data.fn_proto.fn_def_node; |
| 1380 | fn_table_entry->fn_def_node = proto_node->data.fn_proto.fn_def_node; | ||
| 1381 | fn_table_entry->fn_inline = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto; | ||
| 1382 | fn_table_entry->internal_linkage = (fn_proto->visib_mod != VisibModExport); | ||
| 1383 | 1392 | ||
| 1384 | return fn_table_entry; | 1393 | return fn_entry; |
| 1385 | } | 1394 | } |
| 1386 | 1395 | ||
| 1387 | static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | 1396 | static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| ... | @@ -1399,7 +1408,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { | ... | @@ -1399,7 +1408,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 1399 | return; | 1408 | return; |
| 1400 | } | 1409 | } |
| 1401 | 1410 | ||
| 1402 | FnTableEntry *fn_table_entry = create_fn(g, tld_fn->base.source_node); | 1411 | FnTableEntry *fn_table_entry = create_fn(tld_fn->base.source_node); |
| 1403 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); | 1412 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); |
| 1404 | 1413 | ||
| 1405 | tld_fn->fn_entry = fn_table_entry; | 1414 | tld_fn->fn_entry = fn_table_entry; |
| ... | @@ -1801,6 +1810,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | ... | @@ -1801,6 +1810,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 1801 | 1810 | ||
| 1802 | tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, | 1811 | tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, |
| 1803 | var_decl->symbol, type, is_const, &init_value->static_value); | 1812 | var_decl->symbol, type, is_const, &init_value->static_value); |
| 1813 | tld_var->var->is_extern = is_extern; | ||
| 1804 | 1814 | ||
| 1805 | g->global_vars.append(tld_var->var); | 1815 | g->global_vars.append(tld_var->var); |
| 1806 | } | 1816 | } |
| ... | @@ -2736,3 +2746,55 @@ uint64_t get_memcpy_align(CodeGen *g, TypeTableEntry *type_entry) { | ... | @@ -2736,3 +2746,55 @@ uint64_t get_memcpy_align(CodeGen *g, TypeTableEntry *type_entry) { |
| 2736 | TypeTableEntry *first_type_in_mem = type_of_first_thing_in_memory(type_entry); | 2746 | TypeTableEntry *first_type_in_mem = type_of_first_thing_in_memory(type_entry); |
| 2737 | return LLVMABISizeOfType(g->target_data_ref, first_type_in_mem->type_ref); | 2747 | return LLVMABISizeOfType(g->target_data_ref, first_type_in_mem->type_ref); |
| 2738 | } | 2748 | } |
| 2749 | |||
| 2750 | void init_const_str_lit(ConstExprValue *const_val, Buf *str) { | ||
| 2751 | const_val->special = ConstValSpecialStatic; | ||
| 2752 | const_val->data.x_array.elements = allocate<ConstExprValue>(buf_len(str)); | ||
| 2753 | const_val->data.x_array.size = buf_len(str); | ||
| 2754 | |||
| 2755 | for (size_t i = 0; i < buf_len(str); i += 1) { | ||
| 2756 | ConstExprValue *this_char = &const_val->data.x_array.elements[i]; | ||
| 2757 | this_char->special = ConstValSpecialStatic; | ||
| 2758 | bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]); | ||
| 2759 | } | ||
| 2760 | } | ||
| 2761 | |||
| 2762 | ConstExprValue *create_const_str_lit(Buf *str) { | ||
| 2763 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | ||
| 2764 | init_const_str_lit(const_val, str); | ||
| 2765 | return const_val; | ||
| 2766 | } | ||
| 2767 | |||
| 2768 | void init_const_unsigned_negative(ConstExprValue *const_val, uint64_t x, bool negative) { | ||
| 2769 | const_val->special = ConstValSpecialStatic; | ||
| 2770 | bignum_init_unsigned(&const_val->data.x_bignum, x); | ||
| 2771 | const_val->data.x_bignum.is_negative = negative; | ||
| 2772 | } | ||
| 2773 | |||
| 2774 | ConstExprValue *create_const_unsigned_negative(uint64_t x, bool negative) { | ||
| 2775 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | ||
| 2776 | init_const_unsigned_negative(const_val, x, negative); | ||
| 2777 | return const_val; | ||
| 2778 | } | ||
| 2779 | |||
| 2780 | void init_const_signed(ConstExprValue *const_val, int64_t x) { | ||
| 2781 | const_val->special = ConstValSpecialStatic; | ||
| 2782 | bignum_init_signed(&const_val->data.x_bignum, x); | ||
| 2783 | } | ||
| 2784 | |||
| 2785 | ConstExprValue *create_const_signed(int64_t x) { | ||
| 2786 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | ||
| 2787 | init_const_signed(const_val, x); | ||
| 2788 | return const_val; | ||
| 2789 | } | ||
| 2790 | |||
| 2791 | void init_const_float(ConstExprValue *const_val, double value) { | ||
| 2792 | const_val->special = ConstValSpecialStatic; | ||
| 2793 | bignum_init_float(&const_val->data.x_bignum, value); | ||
| 2794 | } | ||
| 2795 | |||
| 2796 | ConstExprValue *create_const_float(double value) { | ||
| 2797 | ConstExprValue *const_val = allocate<ConstExprValue>(1); | ||
| 2798 | init_const_float(const_val, value); | ||
| 2799 | return const_val; | ||
| 2800 | } |
src/analyze.hpp+16-2| ... | @@ -70,15 +70,29 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source | ... | @@ -70,15 +70,29 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source |
| 70 | VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, | 70 | VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, |
| 71 | TypeTableEntry *type_entry, bool is_const, ConstExprValue *init_value); | 71 | TypeTableEntry *type_entry, bool is_const, ConstExprValue *init_value); |
| 72 | TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); | 72 | TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); |
| 73 | FnTableEntry *create_fn(CodeGen *g, AstNode *proto_node); | 73 | FnTableEntry *create_fn(AstNode *proto_node); |
| 74 | FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage); | ||
| 74 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node); | 75 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node); |
| 75 | AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index); | 76 | AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index); |
| 76 | 77 | ||
| 77 | Scope *create_block_scope(AstNode *node, Scope *parent); | 78 | Scope *create_block_scope(AstNode *node, Scope *parent); |
| 78 | ScopeDefer *create_defer_scope(AstNode *node, Scope *parent); | 79 | ScopeDefer *create_defer_scope(AstNode *node, Scope *parent); |
| 79 | Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var); | 80 | Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var); |
| 80 | Scope *create_cimport_scope(AstNode *node, Scope *parent); | 81 | ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent); |
| 81 | Scope *create_loop_scope(AstNode *node, Scope *parent); | 82 | Scope *create_loop_scope(AstNode *node, Scope *parent); |
| 82 | ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry); | 83 | ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry); |
| 84 | ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *container_type, ImportTableEntry *import); | ||
| 85 | |||
| 86 | void init_const_str_lit(ConstExprValue *const_val, Buf *str); | ||
| 87 | ConstExprValue *create_const_str_lit(Buf *str); | ||
| 88 | |||
| 89 | void init_const_unsigned_negative(ConstExprValue *const_val, uint64_t x, bool negative); | ||
| 90 | ConstExprValue *create_const_unsigned_negative(uint64_t x, bool negative); | ||
| 91 | |||
| 92 | void init_const_signed(ConstExprValue *const_val, int64_t x); | ||
| 93 | ConstExprValue *create_const_signed(int64_t x); | ||
| 94 | |||
| 95 | void init_const_float(ConstExprValue *const_val, double value); | ||
| 96 | ConstExprValue *create_const_float(double value); | ||
| 83 | 97 | ||
| 84 | #endif | 98 | #endif |
src/ast_render.cpp+1| ... | @@ -870,3 +870,4 @@ void ast_render(FILE *f, AstNode *node, int indent_size) { | ... | @@ -870,3 +870,4 @@ void ast_render(FILE *f, AstNode *node, int indent_size) { |
| 870 | 870 | ||
| 871 | render_node_grouped(&ar, node); | 871 | render_node_grouped(&ar, node); |
| 872 | } | 872 | } |
| 873 |
src/codegen.cpp+6-2| ... | @@ -1868,12 +1868,16 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -1868,12 +1868,16 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 1868 | case IrInstructionIdSizeOf: | 1868 | case IrInstructionIdSizeOf: |
| 1869 | case IrInstructionIdSwitchTarget: | 1869 | case IrInstructionIdSwitchTarget: |
| 1870 | case IrInstructionIdStaticEval: | 1870 | case IrInstructionIdStaticEval: |
| 1871 | case IrInstructionIdImport: | ||
| 1872 | case IrInstructionIdContainerInitFields: | 1871 | case IrInstructionIdContainerInitFields: |
| 1873 | case IrInstructionIdMinValue: | 1872 | case IrInstructionIdMinValue: |
| 1874 | case IrInstructionIdMaxValue: | 1873 | case IrInstructionIdMaxValue: |
| 1875 | case IrInstructionIdCompileErr: | 1874 | case IrInstructionIdCompileErr: |
| 1876 | case IrInstructionIdArrayLen: | 1875 | case IrInstructionIdArrayLen: |
| 1876 | case IrInstructionIdImport: | ||
| 1877 | case IrInstructionIdCImport: | ||
| 1878 | case IrInstructionIdCInclude: | ||
| 1879 | case IrInstructionIdCDefine: | ||
| 1880 | case IrInstructionIdCUndef: | ||
| 1877 | zig_unreachable(); | 1881 | zig_unreachable(); |
| 1878 | case IrInstructionIdReturn: | 1882 | case IrInstructionIdReturn: |
| 1879 | return ir_render_return(g, executable, (IrInstructionReturn *)instruction); | 1883 | return ir_render_return(g, executable, (IrInstructionReturn *)instruction); |
| ... | @@ -2346,7 +2350,7 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -2346,7 +2350,7 @@ static void do_code_gen(CodeGen *g) { |
| 2346 | assert(var->decl_node->type == NodeTypeVariableDeclaration); | 2350 | assert(var->decl_node->type == NodeTypeVariableDeclaration); |
| 2347 | 2351 | ||
| 2348 | LLVMValueRef global_value; | 2352 | LLVMValueRef global_value; |
| 2349 | if (var->decl_node->data.variable_declaration.is_extern) { | 2353 | if (var->is_extern) { |
| 2350 | global_value = LLVMAddGlobal(g->module, var->type->type_ref, buf_ptr(&var->name)); | 2354 | global_value = LLVMAddGlobal(g->module, var->type->type_ref, buf_ptr(&var->name)); |
| 2351 | 2355 | ||
| 2352 | // TODO debug info for the extern variable | 2356 | // TODO debug info for the extern variable |
src/ir.cpp+246-123| ... | @@ -12,6 +12,7 @@ | ... | @@ -12,6 +12,7 @@ |
| 12 | #include "ir.hpp" | 12 | #include "ir.hpp" |
| 13 | #include "ir_print.hpp" | 13 | #include "ir_print.hpp" |
| 14 | #include "os.hpp" | 14 | #include "os.hpp" |
| 15 | #include "parseh.hpp" | ||
| 15 | 16 | ||
| 16 | struct IrExecContext { | 17 | struct IrExecContext { |
| 17 | ConstExprValue *mem_slot_list; | 18 | ConstExprValue *mem_slot_list; |
| ... | @@ -88,6 +89,10 @@ static FnTableEntry *exec_fn_entry(IrExecutable *exec) { | ... | @@ -88,6 +89,10 @@ static FnTableEntry *exec_fn_entry(IrExecutable *exec) { |
| 88 | return exec->fn_entry; | 89 | return exec->fn_entry; |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 92 | static Buf *exec_c_import_buf(IrExecutable *exec) { | ||
| 93 | return exec->c_import_buf; | ||
| 94 | } | ||
| 95 | |||
| 91 | static void ir_link_new_instruction(IrInstruction *new_instruction, IrInstruction *old_instruction) { | 96 | static void ir_link_new_instruction(IrInstruction *new_instruction, IrInstruction *old_instruction) { |
| 92 | new_instruction->other = old_instruction; | 97 | new_instruction->other = old_instruction; |
| 93 | old_instruction->other = new_instruction; | 98 | old_instruction->other = new_instruction; |
| ... | @@ -294,6 +299,22 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) { | ... | @@ -294,6 +299,22 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) { |
| 294 | return IrInstructionIdImport; | 299 | return IrInstructionIdImport; |
| 295 | } | 300 | } |
| 296 | 301 | ||
| 302 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCImport *) { | ||
| 303 | return IrInstructionIdCImport; | ||
| 304 | } | ||
| 305 | |||
| 306 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCInclude *) { | ||
| 307 | return IrInstructionIdCInclude; | ||
| 308 | } | ||
| 309 | |||
| 310 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCDefine *) { | ||
| 311 | return IrInstructionIdCDefine; | ||
| 312 | } | ||
| 313 | |||
| 314 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCUndef *) { | ||
| 315 | return IrInstructionIdCUndef; | ||
| 316 | } | ||
| 317 | |||
| 297 | static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayLen *) { | 318 | static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayLen *) { |
| 298 | return IrInstructionIdArrayLen; | 319 | return IrInstructionIdArrayLen; |
| 299 | } | 320 | } |
| ... | @@ -512,18 +533,6 @@ static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, Scope *scope, AstN | ... | @@ -512,18 +533,6 @@ static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, Scope *scope, AstN |
| 512 | return &const_instruction->base; | 533 | return &const_instruction->base; |
| 513 | } | 534 | } |
| 514 | 535 | ||
| 515 | static void init_const_str_lit(ConstExprValue *const_val, Buf *str) { | ||
| 516 | const_val->special = ConstValSpecialStatic; | ||
| 517 | const_val->data.x_array.elements = allocate<ConstExprValue>(buf_len(str)); | ||
| 518 | const_val->data.x_array.size = buf_len(str); | ||
| 519 | |||
| 520 | for (size_t i = 0; i < buf_len(str); i += 1) { | ||
| 521 | ConstExprValue *this_char = &const_val->data.x_array.elements[i]; | ||
| 522 | this_char->special = ConstValSpecialStatic; | ||
| 523 | bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]); | ||
| 524 | } | ||
| 525 | } | ||
| 526 | |||
| 527 | static IrInstruction *ir_create_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { | 536 | static IrInstruction *ir_create_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { |
| 528 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, scope, source_node); | 537 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, scope, source_node); |
| 529 | TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8; | 538 | TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8; |
| ... | @@ -1301,6 +1310,39 @@ static IrInstruction *ir_build_err_name_from(IrBuilder *irb, IrInstruction *old_ | ... | @@ -1301,6 +1310,39 @@ static IrInstruction *ir_build_err_name_from(IrBuilder *irb, IrInstruction *old_ |
| 1301 | return new_instruction; | 1310 | return new_instruction; |
| 1302 | } | 1311 | } |
| 1303 | 1312 | ||
| 1313 | static IrInstruction *ir_build_c_import(IrBuilder *irb, Scope *scope, AstNode *source_node) { | ||
| 1314 | IrInstructionCImport *instruction = ir_build_instruction<IrInstructionCImport>(irb, scope, source_node); | ||
| 1315 | return &instruction->base; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | static IrInstruction *ir_build_c_include(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { | ||
| 1319 | IrInstructionCInclude *instruction = ir_build_instruction<IrInstructionCInclude>(irb, scope, source_node); | ||
| 1320 | instruction->name = name; | ||
| 1321 | |||
| 1322 | ir_ref_instruction(name); | ||
| 1323 | |||
| 1324 | return &instruction->base; | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | static IrInstruction *ir_build_c_define(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name, IrInstruction *value) { | ||
| 1328 | IrInstructionCDefine *instruction = ir_build_instruction<IrInstructionCDefine>(irb, scope, source_node); | ||
| 1329 | instruction->name = name; | ||
| 1330 | instruction->value = value; | ||
| 1331 | |||
| 1332 | ir_ref_instruction(name); | ||
| 1333 | ir_ref_instruction(value); | ||
| 1334 | |||
| 1335 | return &instruction->base; | ||
| 1336 | } | ||
| 1337 | |||
| 1338 | static IrInstruction *ir_build_c_undef(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { | ||
| 1339 | IrInstructionCUndef *instruction = ir_build_instruction<IrInstructionCUndef>(irb, scope, source_node); | ||
| 1340 | instruction->name = name; | ||
| 1341 | |||
| 1342 | ir_ref_instruction(name); | ||
| 1343 | |||
| 1344 | return &instruction->base; | ||
| 1345 | } | ||
| 1304 | 1346 | ||
| 1305 | static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, | 1347 | static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, |
| 1306 | bool gen_error_defers, bool gen_maybe_defers) | 1348 | bool gen_error_defers, bool gen_maybe_defers) |
| ... | @@ -1934,12 +1976,68 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -1934,12 +1976,68 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 1934 | return arg0_value; | 1976 | return arg0_value; |
| 1935 | 1977 | ||
| 1936 | if (exec_fn_entry(irb->exec)) { | 1978 | if (exec_fn_entry(irb->exec)) { |
| 1937 | add_node_error(irb->codegen, node, buf_sprintf("import valid only at top level scope")); | 1979 | add_node_error(irb->codegen, node, buf_sprintf("import valid only at global scope")); |
| 1938 | return irb->codegen->invalid_instruction; | 1980 | return irb->codegen->invalid_instruction; |
| 1939 | } | 1981 | } |
| 1940 | 1982 | ||
| 1941 | return ir_build_import(irb, scope, node, arg0_value); | 1983 | return ir_build_import(irb, scope, node, arg0_value); |
| 1942 | } | 1984 | } |
| 1985 | case BuiltinFnIdCImport: | ||
| 1986 | { | ||
| 1987 | if (exec_fn_entry(irb->exec)) { | ||
| 1988 | add_node_error(irb->codegen, node, buf_sprintf("C import valid only at global scope")); | ||
| 1989 | return irb->codegen->invalid_instruction; | ||
| 1990 | } | ||
| 1991 | |||
| 1992 | return ir_build_c_import(irb, scope, node); | ||
| 1993 | } | ||
| 1994 | case BuiltinFnIdCInclude: | ||
| 1995 | { | ||
| 1996 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 1997 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 1998 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 1999 | return arg0_value; | ||
| 2000 | |||
| 2001 | if (!exec_c_import_buf(irb->exec)) { | ||
| 2002 | add_node_error(irb->codegen, node, buf_sprintf("C include valid only inside C import block")); | ||
| 2003 | return irb->codegen->invalid_instruction; | ||
| 2004 | } | ||
| 2005 | |||
| 2006 | return ir_build_c_include(irb, scope, node, arg0_value); | ||
| 2007 | } | ||
| 2008 | case BuiltinFnIdCDefine: | ||
| 2009 | { | ||
| 2010 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 2011 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 2012 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 2013 | return arg0_value; | ||
| 2014 | |||
| 2015 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 2016 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 2017 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 2018 | return arg1_value; | ||
| 2019 | |||
| 2020 | if (!exec_c_import_buf(irb->exec)) { | ||
| 2021 | add_node_error(irb->codegen, node, buf_sprintf("C define valid only inside C import block")); | ||
| 2022 | return irb->codegen->invalid_instruction; | ||
| 2023 | } | ||
| 2024 | |||
| 2025 | return ir_build_c_define(irb, scope, node, arg0_value, arg1_value); | ||
| 2026 | } | ||
| 2027 | case BuiltinFnIdCUndef: | ||
| 2028 | { | ||
| 2029 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 2030 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 2031 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 2032 | return arg0_value; | ||
| 2033 | |||
| 2034 | if (!exec_c_import_buf(irb->exec)) { | ||
| 2035 | add_node_error(irb->codegen, node, buf_sprintf("C undef valid only inside C import block")); | ||
| 2036 | return irb->codegen->invalid_instruction; | ||
| 2037 | } | ||
| 2038 | |||
| 2039 | return ir_build_c_undef(irb, scope, node, arg0_value); | ||
| 2040 | } | ||
| 1943 | case BuiltinFnIdMaxValue: | 2041 | case BuiltinFnIdMaxValue: |
| 1944 | { | 2042 | { |
| 1945 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 2043 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | @@ -1984,10 +2082,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -1984,10 +2082,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 1984 | case BuiltinFnIdSubWithOverflow: | 2082 | case BuiltinFnIdSubWithOverflow: |
| 1985 | case BuiltinFnIdMulWithOverflow: | 2083 | case BuiltinFnIdMulWithOverflow: |
| 1986 | case BuiltinFnIdShlWithOverflow: | 2084 | case BuiltinFnIdShlWithOverflow: |
| 1987 | case BuiltinFnIdCInclude: | ||
| 1988 | case BuiltinFnIdCDefine: | ||
| 1989 | case BuiltinFnIdCUndef: | ||
| 1990 | case BuiltinFnIdCImport: | ||
| 1991 | case BuiltinFnIdBreakpoint: | 2085 | case BuiltinFnIdBreakpoint: |
| 1992 | case BuiltinFnIdReturnAddress: | 2086 | case BuiltinFnIdReturnAddress: |
| 1993 | case BuiltinFnIdFrameAddress: | 2087 | case BuiltinFnIdFrameAddress: |
| ... | @@ -3507,11 +3601,12 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value) { | ... | @@ -3507,11 +3601,12 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value) { |
| 3507 | 3601 | ||
| 3508 | IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, | 3602 | IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, |
| 3509 | TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, | 3603 | TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, |
| 3510 | FnTableEntry *fn_entry) | 3604 | FnTableEntry *fn_entry, Buf *c_import_buf) |
| 3511 | { | 3605 | { |
| 3512 | IrExecutable ir_executable = {0}; | 3606 | IrExecutable ir_executable = {0}; |
| 3513 | ir_executable.is_inline = true; | 3607 | ir_executable.is_inline = true; |
| 3514 | ir_executable.fn_entry = fn_entry; | 3608 | ir_executable.fn_entry = fn_entry; |
| 3609 | ir_executable.c_import_buf = c_import_buf; | ||
| 3515 | ir_gen(codegen, node, scope, &ir_executable); | 3610 | ir_gen(codegen, node, scope, &ir_executable); |
| 3516 | 3611 | ||
| 3517 | if (ir_executable.invalid) | 3612 | if (ir_executable.invalid) |
| ... | @@ -3527,6 +3622,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node | ... | @@ -3527,6 +3622,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node |
| 3527 | IrExecutable analyzed_executable = {0}; | 3622 | IrExecutable analyzed_executable = {0}; |
| 3528 | analyzed_executable.is_inline = true; | 3623 | analyzed_executable.is_inline = true; |
| 3529 | analyzed_executable.fn_entry = fn_entry; | 3624 | analyzed_executable.fn_entry = fn_entry; |
| 3625 | analyzed_executable.c_import_buf = c_import_buf; | ||
| 3530 | analyzed_executable.backward_branch_count = backward_branch_count; | 3626 | analyzed_executable.backward_branch_count = backward_branch_count; |
| 3531 | analyzed_executable.backward_branch_quota = backward_branch_quota; | 3627 | analyzed_executable.backward_branch_quota = backward_branch_quota; |
| 3532 | TypeTableEntry *result_type = ir_analyze(codegen, &ir_executable, &analyzed_executable, expected_type, node); | 3628 | TypeTableEntry *result_type = ir_analyze(codegen, &ir_executable, &analyzed_executable, expected_type, node); |
| ... | @@ -4641,7 +4737,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -4641,7 +4737,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 4641 | // Analyze the fn body block like any other constant expression. | 4737 | // Analyze the fn body block like any other constant expression. |
| 4642 | AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body; | 4738 | AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body; |
| 4643 | IrInstruction *result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, | 4739 | IrInstruction *result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, |
| 4644 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry); | 4740 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, nullptr); |
| 4645 | if (result->type_entry->id == TypeTableEntryIdInvalid) | 4741 | if (result->type_entry->id == TypeTableEntryIdInvalid) |
| 4646 | return ira->codegen->builtin_types.entry_invalid; | 4742 | return ira->codegen->builtin_types.entry_invalid; |
| 4647 | 4743 | ||
| ... | @@ -4658,7 +4754,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal | ... | @@ -4658,7 +4754,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 4658 | 4754 | ||
| 4659 | // Fork a scope of the function with known values for the parameters. | 4755 | // Fork a scope of the function with known values for the parameters. |
| 4660 | Scope *parent_scope = fn_entry->fndef_scope->base.parent; | 4756 | Scope *parent_scope = fn_entry->fndef_scope->base.parent; |
| 4661 | FnTableEntry *impl_fn = create_fn(ira->codegen, fn_proto_node); | 4757 | FnTableEntry *impl_fn = create_fn(fn_proto_node); |
| 4662 | impl_fn->param_source_nodes = allocate<AstNode *>(call_param_count); | 4758 | impl_fn->param_source_nodes = allocate<AstNode *>(call_param_count); |
| 4663 | buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); | 4759 | buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); |
| 4664 | impl_fn->fndef_scope = create_fndef_scope(impl_fn->fn_def_node, parent_scope, impl_fn); | 4760 | impl_fn->fndef_scope = create_fndef_scope(impl_fn->fn_def_node, parent_scope, impl_fn); |
| ... | @@ -6929,6 +7025,124 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc | ... | @@ -6929,6 +7025,124 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc |
| 6929 | return str_type; | 7025 | return str_type; |
| 6930 | } | 7026 | } |
| 6931 | 7027 | ||
| 7028 | static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCImport *instruction) { | ||
| 7029 | AstNode *node = instruction->base.source_node; | ||
| 7030 | assert(node->type == NodeTypeFnCallExpr); | ||
| 7031 | AstNode *block_node = node->data.fn_call_expr.params.at(0); | ||
| 7032 | |||
| 7033 | ScopeCImport *cimport_scope = create_cimport_scope(node, instruction->base.scope); | ||
| 7034 | |||
| 7035 | // Execute the C import block like an inline function | ||
| 7036 | TypeTableEntry *void_type = ira->codegen->builtin_types.entry_void; | ||
| 7037 | IrInstruction *result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, | ||
| 7038 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, &cimport_scope->buf); | ||
| 7039 | if (result->type_entry->id == TypeTableEntryIdInvalid) | ||
| 7040 | return ira->codegen->builtin_types.entry_invalid; | ||
| 7041 | |||
| 7042 | find_libc_include_path(ira->codegen); | ||
| 7043 | |||
| 7044 | ImportTableEntry *child_import = allocate<ImportTableEntry>(1); | ||
| 7045 | child_import->decls_scope = create_decls_scope(child_import->root, nullptr, nullptr, child_import); | ||
| 7046 | child_import->c_import_node = node; | ||
| 7047 | |||
| 7048 | ZigList<ErrorMsg *> errors = {0}; | ||
| 7049 | |||
| 7050 | int err; | ||
| 7051 | if ((err = parse_h_buf(child_import, &errors, &cimport_scope->buf, ira->codegen, node))) { | ||
| 7052 | zig_panic("unable to parse h file: %s\n", err_str(err)); | ||
| 7053 | } | ||
| 7054 | |||
| 7055 | if (errors.length > 0) { | ||
| 7056 | ErrorMsg *parent_err_msg = add_node_error(ira->codegen, node, buf_sprintf("C import failed")); | ||
| 7057 | for (size_t i = 0; i < errors.length; i += 1) { | ||
| 7058 | ErrorMsg *err_msg = errors.at(i); | ||
| 7059 | err_msg_add_note(parent_err_msg, err_msg); | ||
| 7060 | } | ||
| 7061 | |||
| 7062 | return ira->codegen->builtin_types.entry_invalid; | ||
| 7063 | } | ||
| 7064 | |||
| 7065 | if (ira->codegen->verbose) { | ||
| 7066 | fprintf(stderr, "\nC imports:\n"); | ||
| 7067 | fprintf(stderr, "-----------\n"); | ||
| 7068 | ir_print_decls(stderr, child_import); | ||
| 7069 | } | ||
| 7070 | |||
| 7071 | // TODO to get fewer false negatives on this, we would need to track this value in | ||
| 7072 | // the ir executable | ||
| 7073 | bool depends_on_compile_var = true; | ||
| 7074 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, depends_on_compile_var); | ||
| 7075 | out_val->data.x_import = child_import; | ||
| 7076 | return ira->codegen->builtin_types.entry_namespace; | ||
| 7077 | } | ||
| 7078 | |||
| 7079 | static TypeTableEntry *ir_analyze_instruction_c_include(IrAnalyze *ira, IrInstructionCInclude *instruction) { | ||
| 7080 | IrInstruction *name_value = instruction->name->other; | ||
| 7081 | if (name_value->type_entry->id == TypeTableEntryIdInvalid) | ||
| 7082 | return ira->codegen->builtin_types.entry_invalid; | ||
| 7083 | |||
| 7084 | Buf *include_name = ir_resolve_str(ira, name_value); | ||
| 7085 | if (!include_name) | ||
| 7086 | return ira->codegen->builtin_types.entry_invalid; | ||
| 7087 | |||
| 7088 | Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); | ||
| 7089 | // We check for this error in pass1 | ||
| 7090 | assert(c_import_buf); | ||
| 7091 | |||
| 7092 | buf_appendf(c_import_buf, "#include <%s>\n", buf_ptr(include_name)); | ||
| 7093 | |||
| 7094 | ir_build_const_from(ira, &instruction->base, false); | ||
| 7095 | return ira->codegen->builtin_types.entry_void; | ||
| 7096 | } | ||
| 7097 | |||
| 7098 | static TypeTableEntry *ir_analyze_instruction_c_define(IrAnalyze *ira, IrInstructionCDefine *instruction) { | ||
| 7099 | IrInstruction *name = instruction->name->other; | ||
| 7100 | if (name->type_entry->id == TypeTableEntryIdInvalid) | ||
| 7101 | return ira->codegen->builtin_types.entry_invalid; | ||
| 7102 | |||
| 7103 | Buf *define_name = ir_resolve_str(ira, name); | ||
| 7104 | if (!define_name) | ||
| 7105 | return ira->codegen->builtin_types.entry_invalid; | ||
| 7106 | |||
| 7107 | IrInstruction *value = instruction->value->other; | ||
| 7108 | if (value->type_entry->id == TypeTableEntryIdInvalid) | ||
| 7109 | return ira->codegen->builtin_types.entry_invalid; | ||
| 7110 | |||
| 7111 | Buf *define_value = ir_resolve_str(ira, value); | ||
| 7112 | if (!define_value) | ||
| 7113 | return ira->codegen->builtin_types.entry_invalid; | ||
| 7114 | |||
| 7115 | Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); | ||
| 7116 | // We check for this error in pass1 | ||
| 7117 | assert(c_import_buf); | ||
| 7118 | |||
| 7119 | buf_appendf(c_import_buf, "#define %s %s\n", buf_ptr(define_name), buf_ptr(define_value)); | ||
| 7120 | |||
| 7121 | ir_build_const_from(ira, &instruction->base, false); | ||
| 7122 | return ira->codegen->builtin_types.entry_void; | ||
| 7123 | } | ||
| 7124 | |||
| 7125 | static TypeTableEntry *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstructionCUndef *instruction) { | ||
| 7126 | IrInstruction *name = instruction->name->other; | ||
| 7127 | if (name->type_entry->id == TypeTableEntryIdInvalid) | ||
| 7128 | return ira->codegen->builtin_types.entry_invalid; | ||
| 7129 | |||
| 7130 | Buf *undef_name = ir_resolve_str(ira, name); | ||
| 7131 | if (!undef_name) | ||
| 7132 | return ira->codegen->builtin_types.entry_invalid; | ||
| 7133 | |||
| 7134 | Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); | ||
| 7135 | // We check for this error in pass1 | ||
| 7136 | assert(c_import_buf); | ||
| 7137 | |||
| 7138 | buf_appendf(c_import_buf, "#undef %s\n", buf_ptr(undef_name)); | ||
| 7139 | |||
| 7140 | ir_build_const_from(ira, &instruction->base, false); | ||
| 7141 | return ira->codegen->builtin_types.entry_void; | ||
| 7142 | } | ||
| 7143 | |||
| 7144 | |||
| 7145 | |||
| 6932 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 7146 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 6933 | switch (instruction->id) { | 7147 | switch (instruction->id) { |
| 6934 | case IrInstructionIdInvalid: | 7148 | case IrInstructionIdInvalid: |
| ... | @@ -7021,6 +7235,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -7021,6 +7235,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 7021 | return ir_analyze_instruction_compile_err(ira, (IrInstructionCompileErr *)instruction); | 7235 | return ir_analyze_instruction_compile_err(ira, (IrInstructionCompileErr *)instruction); |
| 7022 | case IrInstructionIdErrName: | 7236 | case IrInstructionIdErrName: |
| 7023 | return ir_analyze_instruction_err_name(ira, (IrInstructionErrName *)instruction); | 7237 | return ir_analyze_instruction_err_name(ira, (IrInstructionErrName *)instruction); |
| 7238 | case IrInstructionIdCImport: | ||
| 7239 | return ir_analyze_instruction_c_import(ira, (IrInstructionCImport *)instruction); | ||
| 7240 | case IrInstructionIdCInclude: | ||
| 7241 | return ir_analyze_instruction_c_include(ira, (IrInstructionCInclude *)instruction); | ||
| 7242 | case IrInstructionIdCDefine: | ||
| 7243 | return ir_analyze_instruction_c_define(ira, (IrInstructionCDefine *)instruction); | ||
| 7244 | case IrInstructionIdCUndef: | ||
| 7245 | return ir_analyze_instruction_c_undef(ira, (IrInstructionCUndef *)instruction); | ||
| 7024 | case IrInstructionIdCast: | 7246 | case IrInstructionIdCast: |
| 7025 | case IrInstructionIdStructFieldPtr: | 7247 | case IrInstructionIdStructFieldPtr: |
| 7026 | case IrInstructionIdEnumFieldPtr: | 7248 | case IrInstructionIdEnumFieldPtr: |
| ... | @@ -7116,6 +7338,10 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -7116,6 +7338,10 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7116 | case IrInstructionIdSetDebugSafety: | 7338 | case IrInstructionIdSetDebugSafety: |
| 7117 | case IrInstructionIdImport: | 7339 | case IrInstructionIdImport: |
| 7118 | case IrInstructionIdCompileErr: | 7340 | case IrInstructionIdCompileErr: |
| 7341 | case IrInstructionIdCImport: | ||
| 7342 | case IrInstructionIdCInclude: | ||
| 7343 | case IrInstructionIdCDefine: | ||
| 7344 | case IrInstructionIdCUndef: | ||
| 7119 | return true; | 7345 | return true; |
| 7120 | case IrInstructionIdPhi: | 7346 | case IrInstructionIdPhi: |
| 7121 | case IrInstructionIdUnOp: | 7347 | case IrInstructionIdUnOp: |
| ... | @@ -7164,63 +7390,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -7164,63 +7390,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7164 | // TODO port over all this commented out code into new IR way of doing things | 7390 | // TODO port over all this commented out code into new IR way of doing things |
| 7165 | 7391 | ||
| 7166 | 7392 | ||
| 7167 | //static TypeTableEntry *analyze_c_import(CodeGen *g, ImportTableEntry *parent_import, | ||
| 7168 | // BlockContext *parent_context, AstNode *node) | ||
| 7169 | //{ | ||
| 7170 | // assert(node->type == NodeTypeFnCallExpr); | ||
| 7171 | // | ||
| 7172 | // if (parent_context->fn_entry) { | ||
| 7173 | // add_node_error(g, node, buf_sprintf("@c_import invalid inside function bodies")); | ||
| 7174 | // return g->builtin_types.entry_invalid; | ||
| 7175 | // } | ||
| 7176 | // | ||
| 7177 | // AstNode *block_node = node->data.fn_call_expr.params.at(0); | ||
| 7178 | // | ||
| 7179 | // BlockContext *child_context = new_block_context(node, parent_context); | ||
| 7180 | // child_context->c_import_buf = buf_alloc(); | ||
| 7181 | // | ||
| 7182 | // TypeTableEntry *resolved_type = analyze_expression(g, parent_import, child_context, | ||
| 7183 | // g->builtin_types.entry_void, block_node); | ||
| 7184 | // | ||
| 7185 | // if (resolved_type->id == TypeTableEntryIdInvalid) { | ||
| 7186 | // return resolved_type; | ||
| 7187 | // } | ||
| 7188 | // | ||
| 7189 | // find_libc_include_path(g); | ||
| 7190 | // | ||
| 7191 | // ImportTableEntry *child_import = allocate<ImportTableEntry>(1); | ||
| 7192 | // child_import->c_import_node = node; | ||
| 7193 | // | ||
| 7194 | // ZigList<ErrorMsg *> errors = {0}; | ||
| 7195 | // | ||
| 7196 | // int err; | ||
| 7197 | // if ((err = parse_h_buf(child_import, &errors, child_context->c_import_buf, g, node))) { | ||
| 7198 | // zig_panic("unable to parse h file: %s\n", err_str(err)); | ||
| 7199 | // } | ||
| 7200 | // | ||
| 7201 | // if (errors.length > 0) { | ||
| 7202 | // ErrorMsg *parent_err_msg = add_node_error(g, node, buf_sprintf("C import failed")); | ||
| 7203 | // for (size_t i = 0; i < errors.length; i += 1) { | ||
| 7204 | // ErrorMsg *err_msg = errors.at(i); | ||
| 7205 | // err_msg_add_note(parent_err_msg, err_msg); | ||
| 7206 | // } | ||
| 7207 | // | ||
| 7208 | // return g->builtin_types.entry_invalid; | ||
| 7209 | // } | ||
| 7210 | // | ||
| 7211 | // if (g->verbose) { | ||
| 7212 | // fprintf(stderr, "\nc_import:\n"); | ||
| 7213 | // fprintf(stderr, "-----------\n"); | ||
| 7214 | // ast_render(stderr, child_import->root, 4); | ||
| 7215 | // } | ||
| 7216 | // | ||
| 7217 | // child_import->di_file = parent_import->di_file; | ||
| 7218 | // child_import->block_context = new_block_context(child_import->root, nullptr); | ||
| 7219 | // | ||
| 7220 | // scan_decls(g, child_import, child_import->block_context, child_import->root); | ||
| 7221 | // return resolve_expr_const_val_as_import(g, node, child_import); | ||
| 7222 | //} | ||
| 7223 | // | ||
| 7224 | //static TypeTableEntry *analyze_embed_file(CodeGen *g, ImportTableEntry *import, | 7393 | //static TypeTableEntry *analyze_embed_file(CodeGen *g, ImportTableEntry *import, |
| 7225 | // BlockContext *context, AstNode *node) | 7394 | // BlockContext *context, AstNode *node) |
| 7226 | //{ | 7395 | //{ |
| ... | @@ -7587,51 +7756,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -7587,51 +7756,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 7587 | // return g->builtin_types.entry_invalid; | 7756 | // return g->builtin_types.entry_invalid; |
| 7588 | // } | 7757 | // } |
| 7589 | // } | 7758 | // } |
| 7590 | // case BuiltinFnIdCInclude: | ||
| 7591 | // { | ||
| 7592 | // if (!context->c_import_buf) { | ||
| 7593 | // add_node_error(g, node, buf_sprintf("@c_include valid only in c_import blocks")); | ||
| 7594 | // return g->builtin_types.entry_invalid; | ||
| 7595 | // } | ||
| 7596 | // | ||
| 7597 | // AstNode **str_node = node->data.fn_call_expr.params.at(0)->parent_field; | ||
| 7598 | // TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true); | ||
| 7599 | // TypeTableEntry *resolved_type = analyze_expression(g, import, context, str_type, *str_node); | ||
| 7600 | // | ||
| 7601 | // if (resolved_type->id == TypeTableEntryIdInvalid) { | ||
| 7602 | // return resolved_type; | ||
| 7603 | // } | ||
| 7604 | // | ||
| 7605 | // ConstExprValue *const_str_val = &get_resolved_expr(*str_node)->const_val; | ||
| 7606 | // | ||
| 7607 | // if (!const_str_val->ok) { | ||
| 7608 | // add_node_error(g, *str_node, buf_sprintf("@c_include requires constant expression")); | ||
| 7609 | // return g->builtin_types.entry_void; | ||
| 7610 | // } | ||
| 7611 | // | ||
| 7612 | // buf_appendf(context->c_import_buf, "#include <"); | ||
| 7613 | // ConstExprValue *ptr_field = const_str_val->data.x_struct.fields[0]; | ||
| 7614 | // uint64_t len = ptr_field->data.x_ptr.len; | ||
| 7615 | // for (uint64_t i = 0; i < len; i += 1) { | ||
| 7616 | // ConstExprValue *char_val = ptr_field->data.x_ptr.ptr[i]; | ||
| 7617 | // uint64_t big_c = char_val->data.x_bignum.data.x_uint; | ||
| 7618 | // assert(big_c <= UINT8_MAX); | ||
| 7619 | // uint8_t c = big_c; | ||
| 7620 | // buf_append_char(context->c_import_buf, c); | ||
| 7621 | // } | ||
| 7622 | // buf_appendf(context->c_import_buf, ">\n"); | ||
| 7623 | // | ||
| 7624 | // return g->builtin_types.entry_void; | ||
| 7625 | // } | ||
| 7626 | // case BuiltinFnIdCDefine: | ||
| 7627 | // zig_panic("TODO"); | ||
| 7628 | // case BuiltinFnIdCUndef: | ||
| 7629 | // zig_panic("TODO"); | ||
| 7630 | // | ||
| 7631 | // case BuiltinFnIdImport: | 7759 | // case BuiltinFnIdImport: |
| 7632 | // return analyze_import(g, import, context, node); | 7760 | // return analyze_import(g, import, context, node); |
| 7633 | // case BuiltinFnIdCImport: | ||
| 7634 | // return analyze_c_import(g, import, context, node); | ||
| 7635 | // case BuiltinFnIdBreakpoint: | 7761 | // case BuiltinFnIdBreakpoint: |
| 7636 | // mark_impure_fn(g, context, node); | 7762 | // mark_impure_fn(g, context, node); |
| 7637 | // return g->builtin_types.entry_void; | 7763 | // return g->builtin_types.entry_void; |
| ... | @@ -8121,9 +8247,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -8121,9 +8247,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 8121 | // switch (builtin_fn->id) { | 8247 | // switch (builtin_fn->id) { |
| 8122 | // case BuiltinFnIdInvalid: | 8248 | // case BuiltinFnIdInvalid: |
| 8123 | // case BuiltinFnIdTypeof: | 8249 | // case BuiltinFnIdTypeof: |
| 8124 | // case BuiltinFnIdCInclude: | ||
| 8125 | // case BuiltinFnIdCDefine: | ||
| 8126 | // case BuiltinFnIdCUndef: | ||
| 8127 | // case BuiltinFnIdImport: | 8250 | // case BuiltinFnIdImport: |
| 8128 | // case BuiltinFnIdCImport: | 8251 | // case BuiltinFnIdCImport: |
| 8129 | // case BuiltinFnIdCompileErr: | 8252 | // case BuiltinFnIdCompileErr: |
src/ir.hpp+1-1| ... | @@ -15,7 +15,7 @@ IrInstruction *ir_gen_fn(CodeGen *g, FnTableEntry *fn_entry); | ... | @@ -15,7 +15,7 @@ IrInstruction *ir_gen_fn(CodeGen *g, FnTableEntry *fn_entry); |
| 15 | 15 | ||
| 16 | IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, | 16 | IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, |
| 17 | TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, | 17 | TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, |
| 18 | FnTableEntry *fn_entry); | 18 | FnTableEntry *fn_entry, Buf *c_import_buf); |
| 19 | 19 | ||
| 20 | TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable, | 20 | TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable, |
| 21 | TypeTableEntry *expected_type, AstNode *expected_type_source_node); | 21 | TypeTableEntry *expected_type, AstNode *expected_type_source_node); |
src/ir_print.cpp+105-1| ... | @@ -144,7 +144,11 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const | ... | @@ -144,7 +144,11 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const |
| 144 | case TypeTableEntryIdNamespace: | 144 | case TypeTableEntryIdNamespace: |
| 145 | { | 145 | { |
| 146 | ImportTableEntry *import = const_val->data.x_import; | 146 | ImportTableEntry *import = const_val->data.x_import; |
| 147 | fprintf(irp->f, "(namespace: %s)", buf_ptr(import->path)); | 147 | if (import->c_import_node) { |
| 148 | fprintf(irp->f, "(namespace from C import)"); | ||
| 149 | } else { | ||
| 150 | fprintf(irp->f, "(namespace: %s)", buf_ptr(import->path)); | ||
| 151 | } | ||
| 148 | return; | 152 | return; |
| 149 | } | 153 | } |
| 150 | case TypeTableEntryIdBoundFn: | 154 | case TypeTableEntryIdBoundFn: |
| ... | @@ -685,6 +689,30 @@ static void ir_print_err_name(IrPrint *irp, IrInstructionErrName *instruction) { | ... | @@ -685,6 +689,30 @@ static void ir_print_err_name(IrPrint *irp, IrInstructionErrName *instruction) { |
| 685 | fprintf(irp->f, ")"); | 689 | fprintf(irp->f, ")"); |
| 686 | } | 690 | } |
| 687 | 691 | ||
| 692 | static void ir_print_c_import(IrPrint *irp, IrInstructionCImport *instruction) { | ||
| 693 | fprintf(irp->f, "@cImport(...)"); | ||
| 694 | } | ||
| 695 | |||
| 696 | static void ir_print_c_include(IrPrint *irp, IrInstructionCInclude *instruction) { | ||
| 697 | fprintf(irp->f, "@cInclude("); | ||
| 698 | ir_print_other_instruction(irp, instruction->name); | ||
| 699 | fprintf(irp->f, ")"); | ||
| 700 | } | ||
| 701 | |||
| 702 | static void ir_print_c_define(IrPrint *irp, IrInstructionCDefine *instruction) { | ||
| 703 | fprintf(irp->f, "@cDefine("); | ||
| 704 | ir_print_other_instruction(irp, instruction->name); | ||
| 705 | fprintf(irp->f, ", "); | ||
| 706 | ir_print_other_instruction(irp, instruction->value); | ||
| 707 | fprintf(irp->f, ")"); | ||
| 708 | } | ||
| 709 | |||
| 710 | static void ir_print_c_undef(IrPrint *irp, IrInstructionCUndef *instruction) { | ||
| 711 | fprintf(irp->f, "@cUndef("); | ||
| 712 | ir_print_other_instruction(irp, instruction->name); | ||
| 713 | fprintf(irp->f, ")"); | ||
| 714 | } | ||
| 715 | |||
| 688 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | 716 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 689 | ir_print_prefix(irp, instruction); | 717 | ir_print_prefix(irp, instruction); |
| 690 | switch (instruction->id) { | 718 | switch (instruction->id) { |
| ... | @@ -834,6 +862,18 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -834,6 +862,18 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 834 | case IrInstructionIdErrName: | 862 | case IrInstructionIdErrName: |
| 835 | ir_print_err_name(irp, (IrInstructionErrName *)instruction); | 863 | ir_print_err_name(irp, (IrInstructionErrName *)instruction); |
| 836 | break; | 864 | break; |
| 865 | case IrInstructionIdCImport: | ||
| 866 | ir_print_c_import(irp, (IrInstructionCImport *)instruction); | ||
| 867 | break; | ||
| 868 | case IrInstructionIdCInclude: | ||
| 869 | ir_print_c_include(irp, (IrInstructionCInclude *)instruction); | ||
| 870 | break; | ||
| 871 | case IrInstructionIdCDefine: | ||
| 872 | ir_print_c_define(irp, (IrInstructionCDefine *)instruction); | ||
| 873 | break; | ||
| 874 | case IrInstructionIdCUndef: | ||
| 875 | ir_print_c_undef(irp, (IrInstructionCUndef *)instruction); | ||
| 876 | break; | ||
| 837 | } | 877 | } |
| 838 | fprintf(irp->f, "\n"); | 878 | fprintf(irp->f, "\n"); |
| 839 | } | 879 | } |
| ... | @@ -854,3 +894,67 @@ void ir_print(FILE *f, IrExecutable *executable, int indent_size) { | ... | @@ -854,3 +894,67 @@ void ir_print(FILE *f, IrExecutable *executable, int indent_size) { |
| 854 | } | 894 | } |
| 855 | } | 895 | } |
| 856 | } | 896 | } |
| 897 | |||
| 898 | static void print_tld_var(IrPrint *irp, TldVar *tld_var) { | ||
| 899 | const char *const_or_var = tld_var->var->src_is_const ? "const" : "var"; | ||
| 900 | fprintf(irp->f, "%s %s", const_or_var, buf_ptr(tld_var->base.name)); | ||
| 901 | bool omit_type = (tld_var->var->type->id == TypeTableEntryIdNumLitFloat || | ||
| 902 | tld_var->var->type->id == TypeTableEntryIdNumLitInt); | ||
| 903 | if (!omit_type) { | ||
| 904 | fprintf(irp->f, ": %s", buf_ptr(&tld_var->var->type->name)); | ||
| 905 | } | ||
| 906 | if (tld_var->var->value) { | ||
| 907 | fprintf(irp->f, " = "); | ||
| 908 | ir_print_const_value(irp, tld_var->var->type, tld_var->var->value); | ||
| 909 | } | ||
| 910 | fprintf(irp->f, ";\n"); | ||
| 911 | } | ||
| 912 | |||
| 913 | static void print_tld_fn(IrPrint *irp, TldFn *tld_fn) { | ||
| 914 | fprintf(irp->f, "// %s = TODO (function)\n", buf_ptr(tld_fn->base.name)); | ||
| 915 | } | ||
| 916 | |||
| 917 | static void print_tld_container(IrPrint *irp, TldContainer *tld_container) { | ||
| 918 | fprintf(irp->f, "// %s = TODO (container)\n", buf_ptr(tld_container->base.name)); | ||
| 919 | } | ||
| 920 | |||
| 921 | static void print_tld_typedef(IrPrint *irp, TldTypeDef *tld_typedef) { | ||
| 922 | fprintf(irp->f, "// %s = TODO (typedef)\n", buf_ptr(tld_typedef->base.name)); | ||
| 923 | } | ||
| 924 | |||
| 925 | void ir_print_decls(FILE *f, ImportTableEntry *import) { | ||
| 926 | IrPrint ir_print = {}; | ||
| 927 | IrPrint *irp = &ir_print; | ||
| 928 | irp->f = f; | ||
| 929 | irp->indent = 0; | ||
| 930 | irp->indent_size = 2; | ||
| 931 | |||
| 932 | auto it = import->decls_scope->decl_table.entry_iterator(); | ||
| 933 | for (;;) { | ||
| 934 | auto *entry = it.next(); | ||
| 935 | if (!entry) | ||
| 936 | break; | ||
| 937 | |||
| 938 | Tld *tld = entry->value; | ||
| 939 | if (!buf_eql_buf(entry->key, tld->name)) { | ||
| 940 | fprintf(f, "// alias: %s = %s\n", buf_ptr(entry->key), buf_ptr(tld->name)); | ||
| 941 | continue; | ||
| 942 | } | ||
| 943 | |||
| 944 | switch (tld->id) { | ||
| 945 | case TldIdVar: | ||
| 946 | print_tld_var(irp, (TldVar *)tld); | ||
| 947 | continue; | ||
| 948 | case TldIdFn: | ||
| 949 | print_tld_fn(irp, (TldFn *)tld); | ||
| 950 | continue; | ||
| 951 | case TldIdContainer: | ||
| 952 | print_tld_container(irp, (TldContainer *)tld); | ||
| 953 | continue; | ||
| 954 | case TldIdTypeDef: | ||
| 955 | print_tld_typedef(irp, (TldTypeDef *)tld); | ||
| 956 | continue; | ||
| 957 | } | ||
| 958 | zig_unreachable(); | ||
| 959 | } | ||
| 960 | } |
src/ir_print.hpp+3| ... | @@ -14,4 +14,7 @@ | ... | @@ -14,4 +14,7 @@ |
| 14 | 14 | ||
| 15 | void ir_print(FILE *f, IrExecutable *executable, int indent_size); | 15 | void ir_print(FILE *f, IrExecutable *executable, int indent_size); |
| 16 | 16 | ||
| 17 | void ir_print_decls(FILE *f, ImportTableEntry *import); | ||
| 18 | |||
| 19 | |||
| 17 | #endif | 20 | #endif |
src/parseh.cpp+174-329| ... | @@ -31,27 +31,28 @@ struct GlobalValue { | ... | @@ -31,27 +31,28 @@ struct GlobalValue { |
| 31 | bool is_const; | 31 | bool is_const; |
| 32 | }; | 32 | }; |
| 33 | 33 | ||
| 34 | struct Alias { | ||
| 35 | Buf *name; | ||
| 36 | Tld *tld; | ||
| 37 | }; | ||
| 38 | |||
| 34 | struct Context { | 39 | struct Context { |
| 35 | ImportTableEntry *import; | 40 | ImportTableEntry *import; |
| 36 | ZigList<ErrorMsg *> *errors; | 41 | ZigList<ErrorMsg *> *errors; |
| 37 | bool warnings_on; | 42 | bool warnings_on; |
| 38 | VisibMod visib_mod; | 43 | VisibMod visib_mod; |
| 39 | AstNode *root; | ||
| 40 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> global_type_table; | 44 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> global_type_table; |
| 41 | HashMap<Buf *, GlobalValue, buf_hash, buf_eql_buf> global_value_table; | ||
| 42 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table; | 45 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table; |
| 43 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_decl_table; | ||
| 44 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table; | 46 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table; |
| 45 | HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table; | 47 | HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table; |
| 46 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table; | 48 | HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> macro_table; |
| 47 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; | ||
| 48 | SourceManager *source_manager; | 49 | SourceManager *source_manager; |
| 49 | ZigList<AstNode *> aliases; | 50 | ZigList<Alias> aliases; |
| 50 | ZigList<MacroSymbol> macro_symbols; | 51 | ZigList<MacroSymbol> macro_symbols; |
| 51 | AstNode *source_node; | 52 | AstNode *source_node; |
| 53 | uint32_t next_anon_index; | ||
| 52 | 54 | ||
| 53 | CodeGen *codegen; | 55 | CodeGen *codegen; |
| 54 | bool transform_extern_fn_ptr; | ||
| 55 | }; | 56 | }; |
| 56 | 57 | ||
| 57 | static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl, | 58 | static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl, |
| ... | @@ -88,233 +89,132 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...) | ... | @@ -88,233 +89,132 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...) |
| 88 | fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg)); | 89 | fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg)); |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | static uint32_t get_next_node_index(Context *c) { | 92 | static uint32_t get_next_anon_index(Context *c) { |
| 92 | uint32_t result = c->codegen->next_node_index; | 93 | uint32_t result = c->next_anon_index; |
| 93 | c->codegen->next_node_index += 1; | 94 | c->next_anon_index += 1; |
| 94 | return result; | 95 | return result; |
| 95 | } | 96 | } |
| 96 | 97 | ||
| 97 | static AstNode *create_node(Context *c, NodeType type) { | 98 | static void add_global_alias(Context *c, Buf *name, Tld *tld) { |
| 98 | AstNode *node = allocate<AstNode>(1); | 99 | c->import->decls_scope->decl_table.put(name, tld); |
| 99 | node->type = type; | ||
| 100 | node->owner = c->import; | ||
| 101 | node->create_index = get_next_node_index(c); | ||
| 102 | return node; | ||
| 103 | } | ||
| 104 | |||
| 105 | static AstNode *create_symbol_node(Context *c, const char *type_name) { | ||
| 106 | AstNode *node = create_node(c, NodeTypeSymbol); | ||
| 107 | node->data.symbol_expr.symbol = buf_create_from_str(type_name); | ||
| 108 | return node; | ||
| 109 | } | ||
| 110 | |||
| 111 | static AstNode *create_field_access_node(Context *c, const char *lhs, const char *rhs) { | ||
| 112 | AstNode *node = create_node(c, NodeTypeFieldAccessExpr); | ||
| 113 | node->data.field_access_expr.struct_expr = create_symbol_node(c, lhs); | ||
| 114 | node->data.field_access_expr.field_name = buf_create_from_str(rhs); | ||
| 115 | return node; | ||
| 116 | } | 100 | } |
| 117 | 101 | ||
| 118 | static AstNode *create_typed_var_decl_node(Context *c, bool is_const, const char *var_name, | 102 | static void add_global_weak_alias(Context *c, Buf *name, Tld *tld) { |
| 119 | AstNode *type_node, AstNode *init_node) | 103 | Alias *alias = c->aliases.add_one(); |
| 120 | { | 104 | alias->name = name; |
| 121 | AstNode *node = create_node(c, NodeTypeVariableDeclaration); | 105 | alias->tld = tld; |
| 122 | node->data.variable_declaration.symbol = buf_create_from_str(var_name); | ||
| 123 | node->data.variable_declaration.is_const = is_const; | ||
| 124 | node->data.variable_declaration.visib_mod = c->visib_mod; | ||
| 125 | node->data.variable_declaration.expr = init_node; | ||
| 126 | node->data.variable_declaration.type = type_node; | ||
| 127 | return node; | ||
| 128 | } | 106 | } |
| 129 | 107 | ||
| 130 | static AstNode *create_var_decl_node(Context *c, const char *var_name, AstNode *expr_node) { | 108 | static void add_global(Context *c, Tld *tld) { |
| 131 | return create_typed_var_decl_node(c, true, var_name, nullptr, expr_node); | 109 | return add_global_alias(c, tld->name, tld); |
| 132 | } | 110 | } |
| 133 | 111 | ||
| 134 | static AstNode *create_prefix_node(Context *c, PrefixOp op, AstNode *child_node) { | 112 | static Tld *get_global(Context *c, Buf *name) { |
| 135 | assert(child_node); | 113 | auto entry = c->import->decls_scope->decl_table.maybe_get(name); |
| 136 | AstNode *node = create_node(c, NodeTypePrefixOpExpr); | 114 | return entry ? entry->value : nullptr; |
| 137 | node->data.prefix_op_expr.prefix_op = op; | ||
| 138 | node->data.prefix_op_expr.primary_expr = child_node; | ||
| 139 | return node; | ||
| 140 | } | 115 | } |
| 141 | 116 | ||
| 142 | static AstNode *create_param_decl_node(Context *c, const char *name, AstNode *type_node, bool is_noalias) { | 117 | static const char *decl_name(const Decl *decl) { |
| 143 | assert(type_node); | 118 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); |
| 144 | AstNode *node = create_node(c, NodeTypeParamDecl); | 119 | return (const char *)named_decl->getName().bytes_begin(); |
| 145 | node->data.param_decl.name = buf_create_from_str(name); | ||
| 146 | node->data.param_decl.type = type_node; | ||
| 147 | node->data.param_decl.is_noalias = is_noalias; | ||
| 148 | |||
| 149 | return node; | ||
| 150 | } | ||
| 151 | |||
| 152 | static AstNode *create_char_lit_node(Context *c, uint8_t value) { | ||
| 153 | AstNode *node = create_node(c, NodeTypeCharLiteral); | ||
| 154 | node->data.char_literal.value = value; | ||
| 155 | return node; | ||
| 156 | } | ||
| 157 | |||
| 158 | // accepts ownership of buf | ||
| 159 | static AstNode *create_str_lit_node(Context *c, Buf *buf) { | ||
| 160 | AstNode *node = create_node(c, NodeTypeStringLiteral); | ||
| 161 | node->data.string_literal.buf = buf; | ||
| 162 | node->data.string_literal.c = true; | ||
| 163 | return node; | ||
| 164 | } | 120 | } |
| 165 | 121 | ||
| 166 | static AstNode *create_num_lit_float(Context *c, double x) { | 122 | static void parseh_init_tld(Context *c, Tld *tld, TldId id, Buf *name) { |
| 167 | AstNode *node = create_node(c, NodeTypeNumberLiteral); | 123 | init_tld(tld, id, name, c->visib_mod, c->source_node, &c->import->decls_scope->base, nullptr); |
| 168 | node->data.number_literal.bignum = allocate_nonzero<BigNum>(1); | 124 | tld->resolution = TldResolutionOk; |
| 169 | bignum_init_float(node->data.number_literal.bignum, x); | ||
| 170 | return node; | ||
| 171 | } | 125 | } |
| 172 | 126 | ||
| 173 | static AstNode *create_num_lit_float_negative(Context *c, double x, bool negative) { | 127 | static TldVar *create_global_var(Context *c, Buf *name, TypeTableEntry *var_type, ConstExprValue *var_value, bool is_const) { |
| 174 | AstNode *num_lit_node = create_num_lit_float(c, x); | 128 | TldVar *tld_var = allocate<TldVar>(1); |
| 175 | if (!negative) return num_lit_node; | 129 | parseh_init_tld(c, &tld_var->base, TldIdVar, name); |
| 176 | return create_prefix_node(c, PrefixOpNegation, num_lit_node); | 130 | tld_var->var = add_variable(c->codegen, c->source_node, &c->import->decls_scope->base, name, var_type, is_const, var_value); |
| 131 | return tld_var; | ||
| 177 | } | 132 | } |
| 178 | 133 | ||
| 179 | static AstNode *create_num_lit_unsigned(Context *c, uint64_t x) { | 134 | static Tld *create_global_char_lit_var(Context *c, Buf *name, uint8_t value) { |
| 180 | AstNode *node = create_node(c, NodeTypeNumberLiteral); | 135 | TldVar *tld_var = create_global_var(c, name, c->codegen->builtin_types.entry_u8, |
| 181 | node->data.number_literal.bignum = allocate_nonzero<BigNum>(1); | 136 | create_const_unsigned_negative(value, false), true); |
| 182 | bignum_init_unsigned(node->data.number_literal.bignum, x); | 137 | return &tld_var->base; |
| 183 | return node; | ||
| 184 | } | 138 | } |
| 185 | 139 | ||
| 186 | static AstNode *create_num_lit_unsigned_negative(Context *c, uint64_t x, bool negative) { | 140 | static Tld *create_global_str_lit_var(Context *c, Buf *name, Buf *value) { |
| 187 | AstNode *num_lit_node = create_num_lit_unsigned(c, x); | 141 | TypeTableEntry *str_type = get_array_type(c->codegen, c->codegen->builtin_types.entry_u8, buf_len(value)); |
| 188 | if (!negative) return num_lit_node; | 142 | TldVar *tld_var = create_global_var(c, name, str_type, create_const_str_lit(value), true); |
| 189 | return create_prefix_node(c, PrefixOpNegation, num_lit_node); | 143 | return &tld_var->base; |
| 190 | } | 144 | } |
| 191 | 145 | ||
| 192 | static AstNode *create_num_lit_signed(Context *c, int64_t x) { | 146 | static Tld *create_global_num_lit_unsigned_negative(Context *c, Buf *name, uint64_t x, bool negative) { |
| 193 | if (x >= 0) { | 147 | TldVar *tld_var = create_global_var(c, name, c->codegen->builtin_types.entry_num_lit_int, |
| 194 | return create_num_lit_unsigned(c, x); | 148 | create_const_unsigned_negative(x, negative), true); |
| 195 | } | 149 | return &tld_var->base; |
| 196 | BigNum bn_orig; | ||
| 197 | bignum_init_signed(&bn_orig, x); | ||
| 198 | |||
| 199 | BigNum bn_negated; | ||
| 200 | bignum_negate(&bn_negated, &bn_orig); | ||
| 201 | |||
| 202 | uint64_t uint = bignum_to_twos_complement(&bn_negated); | ||
| 203 | AstNode *num_lit_node = create_num_lit_unsigned(c, uint); | ||
| 204 | return create_prefix_node(c, PrefixOpNegation, num_lit_node); | ||
| 205 | } | 150 | } |
| 206 | 151 | ||
| 207 | static AstNode *make_type_node(Context *c, TypeTableEntry *type_entry) { | 152 | static Tld *create_global_num_lit_float(Context *c, Buf *name, double value) { |
| 208 | zig_panic("TODO bypass AST in parseh"); | 153 | TldVar *tld_var = create_global_var(c, name, c->codegen->builtin_types.entry_num_lit_float, |
| 154 | create_const_float(value), true); | ||
| 155 | return &tld_var->base; | ||
| 209 | } | 156 | } |
| 210 | 157 | ||
| 211 | static AstNode *create_fn_proto_node(Context *c, Buf *name, TypeTableEntry *fn_type) { | 158 | static ConstExprValue *create_const_num_lit_ap(Context *c, const Decl *source_decl, const llvm::APSInt &aps_int) { |
| 212 | assert(fn_type->id == TypeTableEntryIdFn); | 159 | if (aps_int.isSigned()) { |
| 213 | AstNode *node = create_node(c, NodeTypeFnProto); | 160 | if (aps_int > INT64_MAX || aps_int < INT64_MIN) { |
| 214 | node->data.fn_proto.is_inline = true; | 161 | emit_warning(c, source_decl, "integer overflow\n"); |
| 215 | node->data.fn_proto.visib_mod = c->visib_mod; | 162 | return nullptr; |
| 216 | node->data.fn_proto.name = name; | 163 | } else { |
| 217 | node->data.fn_proto.return_type = make_type_node(c, fn_type->data.fn.fn_type_id.return_type); | 164 | return create_const_signed(aps_int.getExtValue()); |
| 218 | 165 | } | |
| 219 | for (size_t i = 0; i < fn_type->data.fn.fn_type_id.param_count; i += 1) { | 166 | } else { |
| 220 | FnTypeParamInfo *info = &fn_type->data.fn.fn_type_id.param_info[i]; | 167 | if (aps_int > INT64_MAX) { |
| 221 | char arg_name[20]; | 168 | emit_warning(c, source_decl, "integer overflow\n"); |
| 222 | sprintf(arg_name, "arg_%zu", i); | 169 | return nullptr; |
| 223 | node->data.fn_proto.params.append(create_param_decl_node(c, arg_name, | 170 | } else { |
| 224 | make_type_node(c, info->type), info->is_noalias)); | 171 | return create_const_unsigned_negative(aps_int.getExtValue(), false); |
| 172 | } | ||
| 225 | } | 173 | } |
| 226 | |||
| 227 | return node; | ||
| 228 | } | 174 | } |
| 229 | 175 | ||
| 230 | static AstNode *create_one_statement_block(Context *c, AstNode *statement) { | 176 | static Tld *create_global_num_lit_ap(Context *c, const Decl *source_decl, Buf *name, |
| 231 | AstNode *node = create_node(c, NodeTypeBlock); | 177 | const llvm::APSInt &aps_int) |
| 232 | node->data.block.statements.append(statement); | 178 | { |
| 233 | 179 | ConstExprValue *const_value = create_const_num_lit_ap(c, source_decl, aps_int); | |
| 234 | return node; | 180 | if (!const_value) |
| 181 | return nullptr; | ||
| 182 | TldVar *tld_var = create_global_var(c, name, c->codegen->builtin_types.entry_num_lit_int, const_value, true); | ||
| 183 | return &tld_var->base; | ||
| 235 | } | 184 | } |
| 236 | 185 | ||
| 237 | static AstNode *create_inline_fn_node(Context *c, Buf *fn_name, Buf *var_name, TypeTableEntry *fn_type) { | ||
| 238 | AstNode *node = create_node(c, NodeTypeFnDef); | ||
| 239 | node->data.fn_def.fn_proto = create_fn_proto_node(c, fn_name, fn_type); | ||
| 240 | 186 | ||
| 241 | AstNode *unwrap_node = create_prefix_node(c, PrefixOpUnwrapMaybe, create_symbol_node(c, buf_ptr(var_name))); | 187 | static void add_const_type(Context *c, Buf *name, TypeTableEntry *type_entry) { |
| 188 | ConstExprValue *var_value = allocate<ConstExprValue>(1); | ||
| 189 | var_value->special = ConstValSpecialStatic; | ||
| 190 | var_value->data.x_type = type_entry; | ||
| 191 | TldVar *tld_var = create_global_var(c, name, c->codegen->builtin_types.entry_type, var_value, true); | ||
| 192 | add_global(c, &tld_var->base); | ||
| 242 | 193 | ||
| 243 | AstNode *fn_call_node = create_node(c, NodeTypeFnCallExpr); | 194 | c->global_type_table.put(name, type_entry); |
| 244 | fn_call_node->data.fn_call_expr.fn_ref_expr = unwrap_node; | ||
| 245 | for (size_t i = 0; i < fn_type->data.fn.fn_type_id.param_count; i += 1) { | ||
| 246 | AstNode *decl_node = node->data.fn_def.fn_proto->data.fn_proto.params.at(i); | ||
| 247 | Buf *param_name = decl_node->data.param_decl.name; | ||
| 248 | fn_call_node->data.fn_call_expr.params.append(create_symbol_node(c, buf_ptr(param_name))); | ||
| 249 | } | ||
| 250 | |||
| 251 | |||
| 252 | node->data.fn_def.body = create_one_statement_block(c, fn_call_node); | ||
| 253 | |||
| 254 | return node; | ||
| 255 | } | 195 | } |
| 256 | 196 | ||
| 197 | static Tld *add_container_tld(Context *c, TypeTableEntry *type_entry) { | ||
| 198 | TldContainer *tld_container = allocate<TldContainer>(1); | ||
| 199 | parseh_init_tld(c, &tld_container->base, TldIdContainer, &type_entry->name); | ||
| 200 | tld_container->type_entry = type_entry; | ||
| 257 | 201 | ||
| 258 | 202 | add_global(c, &tld_container->base); | |
| 259 | static const char *decl_name(const Decl *decl) { | 203 | return &tld_container->base; |
| 260 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); | ||
| 261 | return (const char *)named_decl->getName().bytes_begin(); | ||
| 262 | } | 204 | } |
| 263 | 205 | ||
| 264 | static void add_typedef_node(Context *c, TypeTableEntry *type_decl) { | 206 | static Tld *add_typedef_tld(Context *c, TypeTableEntry *type_decl) { |
| 265 | assert(type_decl); | 207 | assert(type_decl); |
| 266 | assert(type_decl->id == TypeTableEntryIdTypeDecl); | 208 | assert(type_decl->id == TypeTableEntryIdTypeDecl); |
| 267 | 209 | ||
| 268 | ScopeDecls *decls_scope = c->import->decls_scope; | ||
| 269 | TldTypeDef *tld_typedef = allocate<TldTypeDef>(1); | 210 | TldTypeDef *tld_typedef = allocate<TldTypeDef>(1); |
| 270 | init_tld(&tld_typedef->base, TldIdTypeDef, &type_decl->name, c->visib_mod, c->source_node, &decls_scope->base, nullptr); | 211 | parseh_init_tld(c, &tld_typedef->base, TldIdTypeDef, &type_decl->name); |
| 271 | tld_typedef->type_entry = type_decl; | 212 | tld_typedef->type_entry = type_decl; |
| 272 | 213 | ||
| 273 | decls_scope->decl_table.put(&type_decl->name, &tld_typedef->base); | 214 | add_global(c, &tld_typedef->base); |
| 274 | c->global_type_table.put(&type_decl->name, type_decl); | 215 | c->global_type_table.put(&type_decl->name, type_decl); |
| 275 | } | ||
| 276 | |||
| 277 | static void add_const_var_node(Context *c, Buf *name, TypeTableEntry *type_entry) { | ||
| 278 | ScopeDecls *decls_scope = c->import->decls_scope; | ||
| 279 | TldVar *tld_var = allocate<TldVar>(1); | ||
| 280 | init_tld(&tld_var->base, TldIdVar, name, c->visib_mod, c->source_node, &decls_scope->base, nullptr); | ||
| 281 | bool is_const = true; | ||
| 282 | ConstExprValue *init_value = allocate<ConstExprValue>(1); | ||
| 283 | init_value->special = ConstValSpecialStatic; | ||
| 284 | init_value->data.x_type = type_entry; | ||
| 285 | tld_var->var = add_variable(c->codegen, c->source_node, &decls_scope->base, name, type_entry, is_const, init_value); | ||
| 286 | |||
| 287 | decls_scope->decl_table.put(name, &tld_var->base); | ||
| 288 | c->global_type_table.put(name, type_entry); | ||
| 289 | } | ||
| 290 | |||
| 291 | static void add_container_tld(Context *c, TypeTableEntry *type_entry) { | ||
| 292 | ScopeDecls *decls_scope = c->import->decls_scope; | ||
| 293 | TldContainer *tld_container = allocate<TldContainer>(1); | ||
| 294 | init_tld(&tld_container->base, TldIdContainer, &type_entry->name, c->visib_mod, c->source_node, &decls_scope->base, nullptr); | ||
| 295 | tld_container->type_entry = type_entry; | ||
| 296 | 216 | ||
| 297 | decls_scope->decl_table.put(&type_entry->name, &tld_container->base); | 217 | return &tld_typedef->base; |
| 298 | } | ||
| 299 | |||
| 300 | static AstNode *create_ap_num_lit_node(Context *c, const Decl *source_decl, | ||
| 301 | const llvm::APSInt &aps_int) | ||
| 302 | { | ||
| 303 | if (aps_int.isSigned()) { | ||
| 304 | if (aps_int > INT64_MAX || aps_int < INT64_MIN) { | ||
| 305 | emit_warning(c, source_decl, "integer overflow\n"); | ||
| 306 | return nullptr; | ||
| 307 | } else { | ||
| 308 | return create_num_lit_signed(c, aps_int.getExtValue()); | ||
| 309 | } | ||
| 310 | } else { | ||
| 311 | if (aps_int > INT64_MAX) { | ||
| 312 | emit_warning(c, source_decl, "integer overflow\n"); | ||
| 313 | return nullptr; | ||
| 314 | } else { | ||
| 315 | return create_num_lit_unsigned(c, aps_int.getExtValue()); | ||
| 316 | } | ||
| 317 | } | ||
| 318 | } | 218 | } |
| 319 | 219 | ||
| 320 | static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) { | 220 | static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) { |
| ... | @@ -702,7 +602,7 @@ static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *de | ... | @@ -702,7 +602,7 @@ static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *de |
| 702 | static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { | 602 | static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 703 | Buf *fn_name = buf_create_from_str(decl_name(fn_decl)); | 603 | Buf *fn_name = buf_create_from_str(decl_name(fn_decl)); |
| 704 | 604 | ||
| 705 | if (c->fn_table.maybe_get(fn_name)) { | 605 | if (get_global(c, fn_name)) { |
| 706 | // we already saw this function | 606 | // we already saw this function |
| 707 | return; | 607 | return; |
| 708 | } | 608 | } |
| ... | @@ -715,36 +615,19 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { | ... | @@ -715,36 +615,19 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 715 | } | 615 | } |
| 716 | assert(fn_type->id == TypeTableEntryIdFn); | 616 | assert(fn_type->id == TypeTableEntryIdFn); |
| 717 | 617 | ||
| 718 | 618 | bool internal_linkage = false; | |
| 719 | AstNode *node = create_node(c, NodeTypeFnProto); | 619 | FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, internal_linkage); |
| 720 | node->data.fn_proto.name = fn_name; | 620 | buf_init_from_buf(&fn_entry->symbol_name, fn_name); |
| 721 | 621 | fn_entry->type_entry = fn_type; | |
| 722 | node->data.fn_proto.is_extern = fn_type->data.fn.fn_type_id.is_extern; | ||
| 723 | node->data.fn_proto.visib_mod = c->visib_mod; | ||
| 724 | node->data.fn_proto.is_var_args = fn_type->data.fn.fn_type_id.is_var_args; | ||
| 725 | node->data.fn_proto.return_type = make_type_node(c, fn_type->data.fn.fn_type_id.return_type); | ||
| 726 | 622 | ||
| 727 | assert(!fn_type->data.fn.fn_type_id.is_naked); | 623 | assert(!fn_type->data.fn.fn_type_id.is_naked); |
| 728 | 624 | ||
| 729 | size_t arg_count = fn_type->data.fn.fn_type_id.param_count; | 625 | TldFn *tld_fn = allocate<TldFn>(1); |
| 730 | Buf name_buf = BUF_INIT; | 626 | parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name); |
| 731 | for (size_t i = 0; i < arg_count; i += 1) { | 627 | tld_fn->fn_entry = fn_entry; |
| 732 | FnTypeParamInfo *param_info = &fn_type->data.fn.fn_type_id.param_info[i]; | 628 | add_global(c, &tld_fn->base); |
| 733 | AstNode *type_node = make_type_node(c, param_info->type); | ||
| 734 | const ParmVarDecl *param = fn_decl->getParamDecl(i); | ||
| 735 | const char *name = decl_name(param); | ||
| 736 | if (strlen(name) == 0) { | ||
| 737 | buf_resize(&name_buf, 0); | ||
| 738 | buf_appendf(&name_buf, "arg%zu", i); | ||
| 739 | name = buf_ptr(&name_buf); | ||
| 740 | } | ||
| 741 | |||
| 742 | node->data.fn_proto.params.append(create_param_decl_node(c, name, type_node, param_info->is_noalias)); | ||
| 743 | } | ||
| 744 | 629 | ||
| 745 | 630 | c->codegen->fn_protos.append(fn_entry); | |
| 746 | c->fn_table.put(buf_create_from_buf(fn_name), true); | ||
| 747 | c->root->data.root.top_level_decls.append(node); | ||
| 748 | } | 631 | } |
| 749 | 632 | ||
| 750 | static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) { | 633 | static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) { |
| ... | @@ -775,18 +658,13 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) | ... | @@ -775,18 +658,13 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) |
| 775 | emit_warning(c, typedef_decl, "typedef %s - unresolved child type", buf_ptr(type_name)); | 658 | emit_warning(c, typedef_decl, "typedef %s - unresolved child type", buf_ptr(type_name)); |
| 776 | return; | 659 | return; |
| 777 | } | 660 | } |
| 778 | add_const_var_node(c, type_name, child_type); | 661 | add_const_type(c, type_name, child_type); |
| 779 | } | ||
| 780 | |||
| 781 | static void add_alias(Context *c, const char *new_name, const char *target_name) { | ||
| 782 | AstNode *alias_node = create_var_decl_node(c, new_name, create_symbol_node(c, target_name)); | ||
| 783 | c->aliases.append(alias_node); | ||
| 784 | } | 662 | } |
| 785 | 663 | ||
| 786 | static void replace_with_fwd_decl(Context *c, TypeTableEntry *struct_type, Buf *full_type_name) { | 664 | static void replace_with_fwd_decl(Context *c, TypeTableEntry *struct_type, Buf *full_type_name) { |
| 787 | unsigned line = c->source_node ? c->source_node->line : 0; | 665 | unsigned line = c->source_node ? c->source_node->line : 0; |
| 788 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugForwardDeclType(c->codegen->dbuilder, | 666 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugForwardDeclType(c->codegen->dbuilder, |
| 789 | ZigLLVMTag_DW_structure_type(), buf_ptr(full_type_name), | 667 | ZigLLVMTag_DW_structure_type(), buf_ptr(full_type_name), |
| 790 | ZigLLVMFileToScope(c->import->di_file), c->import->di_file, line); | 668 | ZigLLVMFileToScope(c->import->di_file), c->import->di_file, line); |
| 791 | 669 | ||
| 792 | ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type); | 670 | ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type); |
| ... | @@ -803,7 +681,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) | ... | @@ -803,7 +681,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 803 | 681 | ||
| 804 | Buf *bare_name; | 682 | Buf *bare_name; |
| 805 | if (raw_name[0] == 0) { | 683 | if (raw_name[0] == 0) { |
| 806 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_node_index(c)); | 684 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_anon_index(c)); |
| 807 | } else { | 685 | } else { |
| 808 | bare_name = buf_create_from_str(raw_name); | 686 | bare_name = buf_create_from_str(raw_name); |
| 809 | } | 687 | } |
| ... | @@ -876,11 +754,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) | ... | @@ -876,11 +754,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 876 | 754 | ||
| 877 | // in C each enum value is in the global namespace. so we put them there too. | 755 | // in C each enum value is in the global namespace. so we put them there too. |
| 878 | // at this point we can rely on the enum emitting successfully | 756 | // at this point we can rely on the enum emitting successfully |
| 879 | AstNode *field_access_node = create_field_access_node(c, buf_ptr(full_type_name), buf_ptr(field_name)); | 757 | add_global(c, create_global_num_lit_unsigned_negative(c, enum_val_name, i, false)); |
| 880 | AstNode *var_node = create_var_decl_node(c, buf_ptr(enum_val_name), field_access_node); | ||
| 881 | c->root->data.root.top_level_decls.append(var_node); | ||
| 882 | |||
| 883 | c->global_value_table.put(enum_val_name, {enum_type, true}); | ||
| 884 | } | 758 | } |
| 885 | 759 | ||
| 886 | // create llvm type for root struct | 760 | // create llvm type for root struct |
| ... | @@ -912,20 +786,14 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) | ... | @@ -912,20 +786,14 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 912 | it != it_end; ++it) | 786 | it != it_end; ++it) |
| 913 | { | 787 | { |
| 914 | const EnumConstantDecl *enum_const = *it; | 788 | const EnumConstantDecl *enum_const = *it; |
| 915 | AstNode *num_lit_node = create_ap_num_lit_node(c, enum_decl, enum_const->getInitVal()); | ||
| 916 | if (!num_lit_node) { | ||
| 917 | return c->codegen->builtin_types.entry_invalid; | ||
| 918 | } | ||
| 919 | 789 | ||
| 920 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); | 790 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 921 | 791 | ||
| 922 | AstNode *type_node = make_type_node(c, enum_type); | 792 | Tld *tld = create_global_num_lit_ap(c, enum_decl, enum_val_name, enum_const->getInitVal()); |
| 923 | AstNode *var_decl_node = create_typed_var_decl_node(c, true, buf_ptr(enum_val_name), | 793 | if (!tld) |
| 924 | type_node, num_lit_node); | 794 | return c->codegen->builtin_types.entry_invalid; |
| 925 | |||
| 926 | c->root->data.root.top_level_decls.append(var_decl_node); | ||
| 927 | c->global_value_table.put(enum_val_name, {enum_type, true}); | ||
| 928 | 795 | ||
| 796 | add_global(c, tld); | ||
| 929 | } | 797 | } |
| 930 | 798 | ||
| 931 | return enum_type; | 799 | return enum_type; |
| ... | @@ -940,20 +808,25 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { | ... | @@ -940,20 +808,25 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 940 | 808 | ||
| 941 | // make an alias without the "enum_" prefix. this will get emitted at the | 809 | // make an alias without the "enum_" prefix. this will get emitted at the |
| 942 | // end if it doesn't conflict with anything else | 810 | // end if it doesn't conflict with anything else |
| 943 | if (decl_name(enum_decl)[0] != 0) { | 811 | bool is_anonymous = (decl_name(enum_decl)[0] == 0); |
| 944 | add_alias(c, decl_name(enum_decl), buf_ptr(&enum_type->name)); | 812 | if (is_anonymous) |
| 945 | } | 813 | return; |
| 814 | |||
| 815 | Buf *bare_name = buf_create_from_str(decl_name(enum_decl)); | ||
| 946 | 816 | ||
| 947 | if (enum_type->id == TypeTableEntryIdEnum) { | 817 | if (enum_type->id == TypeTableEntryIdEnum) { |
| 948 | if (enum_type->data.enumeration.complete) { | 818 | if (enum_type->data.enumeration.complete) { |
| 949 | add_container_tld(c, enum_type); | 819 | Tld *tld = add_container_tld(c, enum_type); |
| 820 | add_global_weak_alias(c, bare_name, tld); | ||
| 950 | } else { | 821 | } else { |
| 951 | TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&enum_type->name), | 822 | TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&enum_type->name), |
| 952 | c->codegen->builtin_types.entry_u8); | 823 | c->codegen->builtin_types.entry_u8); |
| 953 | add_typedef_node(c, typedecl_type); | 824 | Tld *tld = add_typedef_tld(c, typedecl_type); |
| 825 | add_global_weak_alias(c, bare_name, tld); | ||
| 954 | } | 826 | } |
| 955 | } else if (enum_type->id == TypeTableEntryIdTypeDecl) { | 827 | } else if (enum_type->id == TypeTableEntryIdTypeDecl) { |
| 956 | add_typedef_node(c, enum_type); | 828 | Tld *tld = add_typedef_tld(c, enum_type); |
| 829 | add_global_weak_alias(c, bare_name, tld); | ||
| 957 | } else { | 830 | } else { |
| 958 | zig_unreachable(); | 831 | zig_unreachable(); |
| 959 | } | 832 | } |
| ... | @@ -974,7 +847,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ | ... | @@ -974,7 +847,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 974 | 847 | ||
| 975 | Buf *bare_name; | 848 | Buf *bare_name; |
| 976 | if (record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0) { | 849 | if (record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0) { |
| 977 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_node_index(c)); | 850 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_anon_index(c)); |
| 978 | } else { | 851 | } else { |
| 979 | bare_name = buf_create_from_str(raw_name); | 852 | bare_name = buf_create_from_str(raw_name); |
| 980 | } | 853 | } |
| ... | @@ -1096,23 +969,20 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) { | ... | @@ -1096,23 +969,20 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) { |
| 1096 | 969 | ||
| 1097 | assert(struct_type->id == TypeTableEntryIdStruct); | 970 | assert(struct_type->id == TypeTableEntryIdStruct); |
| 1098 | 971 | ||
| 1099 | if (c->struct_decl_table.maybe_get(&struct_type->name)) { | 972 | bool is_anonymous = (record_decl->isAnonymousStructOrUnion() || decl_name(record_decl)[0] == 0); |
| 973 | if (is_anonymous) | ||
| 1100 | return; | 974 | return; |
| 1101 | } | ||
| 1102 | c->struct_decl_table.put(&struct_type->name, struct_type); | ||
| 1103 | 975 | ||
| 1104 | // make an alias without the "struct_" prefix. this will get emitted at the | 976 | Buf *bare_name = buf_create_from_str(decl_name(record_decl)); |
| 1105 | // end if it doesn't conflict with anything else | ||
| 1106 | if (decl_name(record_decl)[0] != 0) { | ||
| 1107 | add_alias(c, decl_name(record_decl), buf_ptr(&struct_type->name)); | ||
| 1108 | } | ||
| 1109 | 977 | ||
| 1110 | if (struct_type->data.structure.complete) { | 978 | if (struct_type->data.structure.complete) { |
| 1111 | add_container_tld(c, struct_type); | 979 | Tld *tld = add_container_tld(c, struct_type); |
| 980 | add_global_weak_alias(c, bare_name, tld); | ||
| 1112 | } else { | 981 | } else { |
| 1113 | TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&struct_type->name), | 982 | TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&struct_type->name), |
| 1114 | c->codegen->builtin_types.entry_u8); | 983 | c->codegen->builtin_types.entry_u8); |
| 1115 | add_typedef_node(c, typedecl_type); | 984 | Tld *tld = add_typedef_tld(c, typedecl_type); |
| 985 | add_global_weak_alias(c, bare_name, tld); | ||
| 1116 | } | 986 | } |
| 1117 | } | 987 | } |
| 1118 | 988 | ||
| ... | @@ -1151,7 +1021,7 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { | ... | @@ -1151,7 +1021,7 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| 1151 | emit_warning(c, var_decl, "ignoring variable '%s' - unable to evaluate initializer\n", buf_ptr(name)); | 1021 | emit_warning(c, var_decl, "ignoring variable '%s' - unable to evaluate initializer\n", buf_ptr(name)); |
| 1152 | return; | 1022 | return; |
| 1153 | } | 1023 | } |
| 1154 | AstNode *init_node = nullptr; | 1024 | ConstExprValue *init_value = nullptr; |
| 1155 | switch (ap_value->getKind()) { | 1025 | switch (ap_value->getKind()) { |
| 1156 | case APValue::Int: | 1026 | case APValue::Int: |
| 1157 | { | 1027 | { |
| ... | @@ -1161,10 +1031,10 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { | ... | @@ -1161,10 +1031,10 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| 1161 | "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name)); | 1031 | "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name)); |
| 1162 | return; | 1032 | return; |
| 1163 | } | 1033 | } |
| 1164 | init_node = create_ap_num_lit_node(c, var_decl, ap_value->getInt()); | 1034 | init_value = create_const_num_lit_ap(c, var_decl, ap_value->getInt()); |
| 1165 | if (!init_node) { | 1035 | if (!init_value) |
| 1166 | return; | 1036 | return; |
| 1167 | } | 1037 | |
| 1168 | break; | 1038 | break; |
| 1169 | } | 1039 | } |
| 1170 | case APValue::Uninitialized: | 1040 | case APValue::Uninitialized: |
| ... | @@ -1183,19 +1053,15 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { | ... | @@ -1183,19 +1053,15 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| 1183 | return; | 1053 | return; |
| 1184 | } | 1054 | } |
| 1185 | 1055 | ||
| 1186 | AstNode *type_node = make_type_node(c, var_type); | 1056 | TldVar *tld_var = create_global_var(c, name, var_type, init_value, true); |
| 1187 | AstNode *var_node = create_typed_var_decl_node(c, true, buf_ptr(name), type_node, init_node); | 1057 | add_global(c, &tld_var->base); |
| 1188 | c->root->data.root.top_level_decls.append(var_node); | ||
| 1189 | c->global_value_table.put(name, {var_type, true}); | ||
| 1190 | return; | 1058 | return; |
| 1191 | } | 1059 | } |
| 1192 | 1060 | ||
| 1193 | if (is_extern) { | 1061 | if (is_extern) { |
| 1194 | AstNode *type_node = make_type_node(c, var_type); | 1062 | TldVar *tld_var = create_global_var(c, name, var_type, nullptr, is_const); |
| 1195 | AstNode *var_node = create_typed_var_decl_node(c, is_const, buf_ptr(name), type_node, nullptr); | 1063 | tld_var->var->is_extern = true; |
| 1196 | var_node->data.variable_declaration.is_extern = true; | 1064 | add_global(c, &tld_var->base); |
| 1197 | c->root->data.root.top_level_decls.append(var_node); | ||
| 1198 | c->global_value_table.put(name, {var_type, is_const}); | ||
| 1199 | return; | 1065 | return; |
| 1200 | } | 1066 | } |
| 1201 | 1067 | ||
| ... | @@ -1233,10 +1099,7 @@ static bool name_exists(Context *c, Buf *name) { | ... | @@ -1233,10 +1099,7 @@ static bool name_exists(Context *c, Buf *name) { |
| 1233 | if (c->global_type_table.maybe_get(name)) { | 1099 | if (c->global_type_table.maybe_get(name)) { |
| 1234 | return true; | 1100 | return true; |
| 1235 | } | 1101 | } |
| 1236 | if (c->global_value_table.maybe_get(name)) { | 1102 | if (get_global(c, name)) { |
| 1237 | return true; | ||
| 1238 | } | ||
| 1239 | if (c->fn_table.maybe_get(name)) { | ||
| 1240 | return true; | 1103 | return true; |
| 1241 | } | 1104 | } |
| 1242 | if (c->macro_table.maybe_get(name)) { | 1105 | if (c->macro_table.maybe_get(name)) { |
| ... | @@ -1245,31 +1108,13 @@ static bool name_exists(Context *c, Buf *name) { | ... | @@ -1245,31 +1108,13 @@ static bool name_exists(Context *c, Buf *name) { |
| 1245 | return false; | 1108 | return false; |
| 1246 | } | 1109 | } |
| 1247 | 1110 | ||
| 1248 | static bool name_exists_and_const(Context *c, Buf *name) { | ||
| 1249 | if (c->global_type_table.maybe_get(name)) { | ||
| 1250 | return true; | ||
| 1251 | } | ||
| 1252 | if (c->fn_table.maybe_get(name)) { | ||
| 1253 | return true; | ||
| 1254 | } | ||
| 1255 | if (c->macro_table.maybe_get(name)) { | ||
| 1256 | return true; | ||
| 1257 | } | ||
| 1258 | if (auto entry = c->global_value_table.maybe_get(name)) { | ||
| 1259 | return entry->value.is_const; | ||
| 1260 | } | ||
| 1261 | return false; | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | static void render_aliases(Context *c) { | 1111 | static void render_aliases(Context *c) { |
| 1265 | for (size_t i = 0; i < c->aliases.length; i += 1) { | 1112 | for (size_t i = 0; i < c->aliases.length; i += 1) { |
| 1266 | AstNode *alias_node = c->aliases.at(i); | 1113 | Alias *alias = &c->aliases.at(i); |
| 1267 | assert(alias_node->type == NodeTypeVariableDeclaration); | 1114 | if (name_exists(c, alias->name)) |
| 1268 | Buf *name = alias_node->data.variable_declaration.symbol; | ||
| 1269 | if (name_exists(c, name)) { | ||
| 1270 | continue; | 1115 | continue; |
| 1271 | } | 1116 | |
| 1272 | c->root->data.root.top_level_decls.append(alias_node); | 1117 | add_global_alias(c, alias->name, alias->tld); |
| 1273 | } | 1118 | } |
| 1274 | } | 1119 | } |
| 1275 | 1120 | ||
| ... | @@ -1280,8 +1125,8 @@ static void render_macros(Context *c) { | ... | @@ -1280,8 +1125,8 @@ static void render_macros(Context *c) { |
| 1280 | if (!entry) | 1125 | if (!entry) |
| 1281 | break; | 1126 | break; |
| 1282 | 1127 | ||
| 1283 | AstNode *var_node = entry->value; | 1128 | Tld *var_tld = entry->value; |
| 1284 | c->root->data.root.top_level_decls.append(var_node); | 1129 | add_global(c, var_tld); |
| 1285 | } | 1130 | } |
| 1286 | } | 1131 | } |
| 1287 | 1132 | ||
| ... | @@ -1300,30 +1145,27 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch | ... | @@ -1300,30 +1145,27 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch |
| 1300 | switch (tok->id) { | 1145 | switch (tok->id) { |
| 1301 | case CTokIdCharLit: | 1146 | case CTokIdCharLit: |
| 1302 | if (is_last && is_first) { | 1147 | if (is_last && is_first) { |
| 1303 | AstNode *var_node = create_var_decl_node(c, buf_ptr(name), | 1148 | Tld *tld = create_global_char_lit_var(c, name, tok->data.char_lit); |
| 1304 | create_char_lit_node(c, tok->data.char_lit)); | 1149 | c->macro_table.put(name, tld); |
| 1305 | c->macro_table.put(name, var_node); | ||
| 1306 | } | 1150 | } |
| 1307 | return; | 1151 | return; |
| 1308 | case CTokIdStrLit: | 1152 | case CTokIdStrLit: |
| 1309 | if (is_last && is_first) { | 1153 | if (is_last && is_first) { |
| 1310 | AstNode *var_node = create_var_decl_node(c, buf_ptr(name), | 1154 | Tld *tld = create_global_str_lit_var(c, name, buf_create_from_buf(&tok->data.str_lit)); |
| 1311 | create_str_lit_node(c, buf_create_from_buf(&tok->data.str_lit))); | 1155 | c->macro_table.put(name, tld); |
| 1312 | c->macro_table.put(name, var_node); | ||
| 1313 | } | 1156 | } |
| 1314 | return; | 1157 | return; |
| 1315 | case CTokIdNumLitInt: | 1158 | case CTokIdNumLitInt: |
| 1316 | if (is_last) { | 1159 | if (is_last) { |
| 1317 | AstNode *var_node = create_var_decl_node(c, buf_ptr(name), | 1160 | Tld *tld = create_global_num_lit_unsigned_negative(c, name, tok->data.num_lit_int, negate); |
| 1318 | create_num_lit_unsigned_negative(c, tok->data.num_lit_int, negate)); | 1161 | c->macro_table.put(name, tld); |
| 1319 | c->macro_table.put(name, var_node); | ||
| 1320 | } | 1162 | } |
| 1321 | return; | 1163 | return; |
| 1322 | case CTokIdNumLitFloat: | 1164 | case CTokIdNumLitFloat: |
| 1323 | if (is_last) { | 1165 | if (is_last) { |
| 1324 | AstNode *var_node = create_var_decl_node(c, buf_ptr(name), | 1166 | double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float; |
| 1325 | create_num_lit_float_negative(c, tok->data.num_lit_float, negate)); | 1167 | Tld *tld = create_global_num_lit_float(c, name, value); |
| 1326 | c->macro_table.put(name, var_node); | 1168 | c->macro_table.put(name, tld); |
| 1327 | } | 1169 | } |
| 1328 | return; | 1170 | return; |
| 1329 | case CTokIdSymbol: | 1171 | case CTokIdSymbol: |
| ... | @@ -1351,22 +1193,31 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch | ... | @@ -1351,22 +1193,31 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch |
| 1351 | static void process_symbol_macros(Context *c) { | 1193 | static void process_symbol_macros(Context *c) { |
| 1352 | for (size_t i = 0; i < c->macro_symbols.length; i += 1) { | 1194 | for (size_t i = 0; i < c->macro_symbols.length; i += 1) { |
| 1353 | MacroSymbol ms = c->macro_symbols.at(i); | 1195 | MacroSymbol ms = c->macro_symbols.at(i); |
| 1354 | if (name_exists_and_const(c, ms.value)) { | 1196 | |
| 1355 | AstNode *var_node = create_var_decl_node(c, buf_ptr(ms.name), | 1197 | // If this macro aliases another top level declaration, we can make that happen by |
| 1356 | create_symbol_node(c, buf_ptr(ms.value))); | 1198 | // putting another entry in the decl table pointing to the same top level decl. |
| 1357 | c->macro_table.put(ms.name, var_node); | 1199 | Tld *existing_tld = get_global(c, ms.value); |
| 1358 | } else if (c->transform_extern_fn_ptr || true) { // TODO take off the || true | 1200 | if (!existing_tld) |
| 1359 | if (auto entry = c->global_value_table.maybe_get(ms.value)) { | 1201 | continue; |
| 1360 | TypeTableEntry *maybe_type = entry->value.type; | 1202 | |
| 1361 | if (maybe_type->id == TypeTableEntryIdMaybe) { | 1203 | // If a macro aliases a global variable which is a function pointer, we conclude that |
| 1362 | TypeTableEntry *fn_type = maybe_type->data.maybe.child_type; | 1204 | // the macro is intended to represent a function that assumes the function pointer |
| 1363 | if (fn_type->id == TypeTableEntryIdFn) { | 1205 | // variable is non-null and calls it. |
| 1364 | AstNode *fn_node = create_inline_fn_node(c, ms.name, ms.value, fn_type); | 1206 | if (existing_tld->id == TldIdVar) { |
| 1365 | c->macro_table.put(ms.name, fn_node); | 1207 | TldVar *tld_var = (TldVar *)existing_tld; |
| 1366 | } | 1208 | TypeTableEntry *var_type = tld_var->var->type; |
| 1209 | if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) { | ||
| 1210 | TypeTableEntry *child_type = var_type->data.maybe.child_type; | ||
| 1211 | if (child_type->id == TypeTableEntryIdFn) { | ||
| 1212 | zig_panic("TODO"); | ||
| 1213 | //Tld *fn_tld = create_inline_fn_alias(c, ms.name, tld_var->var); | ||
| 1214 | //c->macro_table.put(ms.name, fn_tld); | ||
| 1215 | continue; | ||
| 1367 | } | 1216 | } |
| 1368 | } | 1217 | } |
| 1369 | } | 1218 | } |
| 1219 | |||
| 1220 | add_global_alias(c, ms.value, existing_tld); | ||
| 1370 | } | 1221 | } |
| 1371 | } | 1222 | } |
| 1372 | 1223 | ||
| ... | @@ -1430,12 +1281,9 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1430,12 +1281,9 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1430 | c->errors = errors; | 1281 | c->errors = errors; |
| 1431 | c->visib_mod = VisibModPub; | 1282 | c->visib_mod = VisibModPub; |
| 1432 | c->global_type_table.init(8); | 1283 | c->global_type_table.init(8); |
| 1433 | c->global_value_table.init(8); | ||
| 1434 | c->enum_type_table.init(8); | 1284 | c->enum_type_table.init(8); |
| 1435 | c->struct_type_table.init(8); | 1285 | c->struct_type_table.init(8); |
| 1436 | c->struct_decl_table.init(8); | ||
| 1437 | c->decl_table.init(8); | 1286 | c->decl_table.init(8); |
| 1438 | c->fn_table.init(8); | ||
| 1439 | c->macro_table.init(8); | 1287 | c->macro_table.init(8); |
| 1440 | c->codegen = codegen; | 1288 | c->codegen = codegen; |
| 1441 | c->source_node = source_node; | 1289 | c->source_node = source_node; |
| ... | @@ -1521,7 +1369,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1521,7 +1369,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1521 | err_unit = std::move(ast_unit); | 1369 | err_unit = std::move(ast_unit); |
| 1522 | } | 1370 | } |
| 1523 | 1371 | ||
| 1524 | for (ASTUnit::stored_diag_iterator it = err_unit->stored_diag_begin(), | 1372 | for (ASTUnit::stored_diag_iterator it = err_unit->stored_diag_begin(), |
| 1525 | it_end = err_unit->stored_diag_end(); | 1373 | it_end = err_unit->stored_diag_end(); |
| 1526 | it != it_end; ++it) | 1374 | it != it_end; ++it) |
| 1527 | { | 1375 | { |
| ... | @@ -1561,7 +1409,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1561,7 +1409,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1561 | 1409 | ||
| 1562 | c->source_manager = &ast_unit->getSourceManager(); | 1410 | c->source_manager = &ast_unit->getSourceManager(); |
| 1563 | 1411 | ||
| 1564 | c->root = create_node(c, NodeTypeRoot); | ||
| 1565 | ast_unit->visitLocalTopLevelDecls(c, decl_visitor); | 1412 | ast_unit->visitLocalTopLevelDecls(c, decl_visitor); |
| 1566 | 1413 | ||
| 1567 | process_preprocessor_entities(c, *ast_unit); | 1414 | process_preprocessor_entities(c, *ast_unit); |
| ... | @@ -1571,7 +1418,5 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1571,7 +1418,5 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1571 | render_macros(c); | 1418 | render_macros(c); |
| 1572 | render_aliases(c); | 1419 | render_aliases(c); |
| 1573 | 1420 | ||
| 1574 | import->root = c->root; | ||
| 1575 | |||
| 1576 | return 0; | 1421 | return 0; |
| 1577 | } | 1422 | } |