authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-11 00:13:43-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-11 00:13:43-05:00
log2dd85d52cc4c4c6a32704f187b41a06401400f0c
tree9bb2423234eede3297d266c151f49bf89c0a89f0
parent3cfbec3eef3e5949a457120287298233978cb236

IR: fix implementation of parseh

libc hello world works now

10 files changed, 663 insertions(+), 478 deletions(-)

src/all_types.hpp+30-1
......@@ -53,6 +53,7 @@ struct IrExecutable {
5353 ZigList<IrGotoItem> goto_list;
5454 bool is_inline;
5555 FnTableEntry *fn_entry;
56 Buf *c_import_buf;
5657};
5758
5859enum OutType {
......@@ -1226,6 +1227,7 @@ struct VariableTableEntry {
12261227 size_t mem_slot_index;
12271228 size_t ref_count;
12281229 ConstExprValue *value;
1230 bool is_extern;
12291231};
12301232
12311233struct ErrorTableEntry {
......@@ -1307,7 +1309,7 @@ struct ScopeVarDecl {
13071309struct ScopeCImport {
13081310 Scope base;
13091311
1310 Buf c_import_buf;
1312 Buf buf;
13111313};
13121314
13131315// This scope is created for a loop such as for or while in order to
......@@ -1394,6 +1396,10 @@ enum IrInstructionId {
13941396 IrInstructionIdCtz,
13951397 IrInstructionIdStaticEval,
13961398 IrInstructionIdImport,
1399 IrInstructionIdCImport,
1400 IrInstructionIdCInclude,
1401 IrInstructionIdCDefine,
1402 IrInstructionIdCUndef,
13971403 IrInstructionIdArrayLen,
13981404 IrInstructionIdRef,
13991405 IrInstructionIdMinValue,
......@@ -1823,6 +1829,29 @@ struct IrInstructionErrName {
18231829 IrInstruction *value;
18241830};
18251831
1832struct IrInstructionCImport {
1833 IrInstruction base;
1834};
1835
1836struct IrInstructionCInclude {
1837 IrInstruction base;
1838
1839 IrInstruction *name;
1840};
1841
1842struct IrInstructionCDefine {
1843 IrInstruction base;
1844
1845 IrInstruction *name;
1846 IrInstruction *value;
1847};
1848
1849struct IrInstructionCUndef {
1850 IrInstruction base;
1851
1852 IrInstruction *name;
1853};
1854
18261855enum LValPurpose {
18271856 LValPurposeNone,
18281857 LValPurposeAssign,
src/analyze.cpp+81-19
......@@ -13,7 +13,6 @@
1313#include "ir.hpp"
1414#include "ir_print.hpp"
1515#include "os.hpp"
16#include "parseh.hpp"
1716#include "parser.hpp"
1817#include "zig_llvm.hpp"
1918
......@@ -136,8 +135,8 @@ void init_scope(Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) {
136135 dest->parent = parent;
137136}
138137
139static ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *container_type, ImportTableEntry *import) {
140 assert(node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl);
138ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *container_type, ImportTableEntry *import) {
139 assert(node == nullptr || node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr);
141140 ScopeDecls *scope = allocate<ScopeDecls>(1);
142141 init_scope(&scope->base, ScopeIdDecls, node, parent);
143142 scope->decl_table.init(4);
......@@ -168,12 +167,12 @@ Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var) {
168167 return &scope->base;
169168}
170169
171Scope *create_cimport_scope(AstNode *node, Scope *parent) {
170ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent) {
172171 assert(node->type == NodeTypeFnCallExpr);
173172 ScopeCImport *scope = allocate<ScopeCImport>(1);
174173 init_scope(&scope->base, ScopeIdCImport, node, parent);
175 buf_resize(&scope->c_import_buf, 0);
176 return &scope->base;
174 buf_resize(&scope->buf, 0);
175 return scope;
177176}
178177
179178Scope *create_loop_scope(AstNode *node, Scope *parent) {
......@@ -877,7 +876,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *nod
877876 size_t backward_branch_count = 0;
878877 return ir_eval_const_value(g, scope, node, type_entry,
879878 &backward_branch_count, default_backward_branch_quota,
880 nullptr);
879 nullptr, nullptr);
881880}
882881
883882TypeTableEntry *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) {
13671366 }
13681367}
13691368
1370FnTableEntry *create_fn(CodeGen *g, AstNode *proto_node) {
1369FnTableEntry *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
1382FnTableEntry *create_fn(AstNode *proto_node) {
13711383 assert(proto_node->type == NodeTypeFnProto);
13721384 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
13731385
1374 FnTableEntry *fn_table_entry = allocate<FnTableEntry>(1);
1375 fn_table_entry->analyzed_executable.backward_branch_count = &fn_table_entry->prealloc_bbc;
1376 fn_table_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota;
1377 fn_table_entry->analyzed_executable.fn_entry = fn_table_entry;
1378 fn_table_entry->ir_executable.fn_entry = fn_table_entry;
1379 fn_table_entry->proto_node = proto_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);
1386 FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto;
1387 bool internal_linkage = (fn_proto->visib_mod != VisibModExport);
1388 FnTableEntry *fn_entry = create_fn_raw(inline_value, internal_linkage);
1389
1390 fn_entry->proto_node = proto_node;
1391 fn_entry->fn_def_node = proto_node->data.fn_proto.fn_def_node;
13831392
1384 return fn_table_entry;
1393 return fn_entry;
13851394}
13861395
13871396static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
......@@ -1399,7 +1408,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
13991408 return;
14001409 }
14011410
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);
14031412 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
14041413
14051414 tld_fn->fn_entry = fn_table_entry;
......@@ -1801,6 +1810,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
18011810
18021811 tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope,
18031812 var_decl->symbol, type, is_const, &init_value->static_value);
1813 tld_var->var->is_extern = is_extern;
18041814
18051815 g->global_vars.append(tld_var->var);
18061816}
......@@ -2736,3 +2746,55 @@ uint64_t get_memcpy_align(CodeGen *g, TypeTableEntry *type_entry) {
27362746 TypeTableEntry *first_type_in_mem = type_of_first_thing_in_memory(type_entry);
27372747 return LLVMABISizeOfType(g->target_data_ref, first_type_in_mem->type_ref);
27382748}
2749
2750void 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
2762ConstExprValue *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
2768void 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
2774ConstExprValue *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
2780void 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
2785ConstExprValue *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
2791void 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
2796ConstExprValue *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
7070VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name,
7171 TypeTableEntry *type_entry, bool is_const, ConstExprValue *init_value);
7272TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node);
73FnTableEntry *create_fn(CodeGen *g, AstNode *proto_node);
73FnTableEntry *create_fn(AstNode *proto_node);
74FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage);
7475void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node);
7576AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index);
7677
7778Scope *create_block_scope(AstNode *node, Scope *parent);
7879ScopeDefer *create_defer_scope(AstNode *node, Scope *parent);
7980Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var);
80Scope *create_cimport_scope(AstNode *node, Scope *parent);
81ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent);
8182Scope *create_loop_scope(AstNode *node, Scope *parent);
8283ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry);
84ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *container_type, ImportTableEntry *import);
85
86void init_const_str_lit(ConstExprValue *const_val, Buf *str);
87ConstExprValue *create_const_str_lit(Buf *str);
88
89void init_const_unsigned_negative(ConstExprValue *const_val, uint64_t x, bool negative);
90ConstExprValue *create_const_unsigned_negative(uint64_t x, bool negative);
91
92void init_const_signed(ConstExprValue *const_val, int64_t x);
93ConstExprValue *create_const_signed(int64_t x);
94
95void init_const_float(ConstExprValue *const_val, double value);
96ConstExprValue *create_const_float(double value);
8397
8498#endif
src/ast_render.cpp+1
......@@ -870,3 +870,4 @@ void ast_render(FILE *f, AstNode *node, int indent_size) {
870870
871871 render_node_grouped(&ar, node);
872872}
873
src/codegen.cpp+6-2
......@@ -1868,12 +1868,16 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
18681868 case IrInstructionIdSizeOf:
18691869 case IrInstructionIdSwitchTarget:
18701870 case IrInstructionIdStaticEval:
1871 case IrInstructionIdImport:
18721871 case IrInstructionIdContainerInitFields:
18731872 case IrInstructionIdMinValue:
18741873 case IrInstructionIdMaxValue:
18751874 case IrInstructionIdCompileErr:
18761875 case IrInstructionIdArrayLen:
1876 case IrInstructionIdImport:
1877 case IrInstructionIdCImport:
1878 case IrInstructionIdCInclude:
1879 case IrInstructionIdCDefine:
1880 case IrInstructionIdCUndef:
18771881 zig_unreachable();
18781882 case IrInstructionIdReturn:
18791883 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
......@@ -2346,7 +2350,7 @@ static void do_code_gen(CodeGen *g) {
23462350 assert(var->decl_node->type == NodeTypeVariableDeclaration);
23472351
23482352 LLVMValueRef global_value;
2349 if (var->decl_node->data.variable_declaration.is_extern) {
2353 if (var->is_extern) {
23502354 global_value = LLVMAddGlobal(g->module, var->type->type_ref, buf_ptr(&var->name));
23512355
23522356 // TODO debug info for the extern variable
src/ir.cpp+246-123
......@@ -12,6 +12,7 @@
1212#include "ir.hpp"
1313#include "ir_print.hpp"
1414#include "os.hpp"
15#include "parseh.hpp"
1516
1617struct IrExecContext {
1718 ConstExprValue *mem_slot_list;
......@@ -88,6 +89,10 @@ static FnTableEntry *exec_fn_entry(IrExecutable *exec) {
8889 return exec->fn_entry;
8990}
9091
92static Buf *exec_c_import_buf(IrExecutable *exec) {
93 return exec->c_import_buf;
94}
95
9196static void ir_link_new_instruction(IrInstruction *new_instruction, IrInstruction *old_instruction) {
9297 new_instruction->other = old_instruction;
9398 old_instruction->other = new_instruction;
......@@ -294,6 +299,22 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) {
294299 return IrInstructionIdImport;
295300}
296301
302static constexpr IrInstructionId ir_instruction_id(IrInstructionCImport *) {
303 return IrInstructionIdCImport;
304}
305
306static constexpr IrInstructionId ir_instruction_id(IrInstructionCInclude *) {
307 return IrInstructionIdCInclude;
308}
309
310static constexpr IrInstructionId ir_instruction_id(IrInstructionCDefine *) {
311 return IrInstructionIdCDefine;
312}
313
314static constexpr IrInstructionId ir_instruction_id(IrInstructionCUndef *) {
315 return IrInstructionIdCUndef;
316}
317
297318static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayLen *) {
298319 return IrInstructionIdArrayLen;
299320}
......@@ -512,18 +533,6 @@ static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, Scope *scope, AstN
512533 return &const_instruction->base;
513534}
514535
515static 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
527536static IrInstruction *ir_create_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) {
528537 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, scope, source_node);
529538 TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;
......@@ -1301,6 +1310,39 @@ static IrInstruction *ir_build_err_name_from(IrBuilder *irb, IrInstruction *old_
13011310 return new_instruction;
13021311}
13031312
1313static 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
1318static 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
1327static 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
1338static 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}
13041346
13051347static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope,
13061348 bool gen_error_defers, bool gen_maybe_defers)
......@@ -1934,12 +1976,68 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
19341976 return arg0_value;
19351977
19361978 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"));
19381980 return irb->codegen->invalid_instruction;
19391981 }
19401982
19411983 return ir_build_import(irb, scope, node, arg0_value);
19421984 }
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 }
19432041 case BuiltinFnIdMaxValue:
19442042 {
19452043 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
19842082 case BuiltinFnIdSubWithOverflow:
19852083 case BuiltinFnIdMulWithOverflow:
19862084 case BuiltinFnIdShlWithOverflow:
1987 case BuiltinFnIdCInclude:
1988 case BuiltinFnIdCDefine:
1989 case BuiltinFnIdCUndef:
1990 case BuiltinFnIdCImport:
19912085 case BuiltinFnIdBreakpoint:
19922086 case BuiltinFnIdReturnAddress:
19932087 case BuiltinFnIdFrameAddress:
......@@ -3507,11 +3601,12 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value) {
35073601
35083602IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
35093603 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)
35113605{
35123606 IrExecutable ir_executable = {0};
35133607 ir_executable.is_inline = true;
35143608 ir_executable.fn_entry = fn_entry;
3609 ir_executable.c_import_buf = c_import_buf;
35153610 ir_gen(codegen, node, scope, &ir_executable);
35163611
35173612 if (ir_executable.invalid)
......@@ -3527,6 +3622,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
35273622 IrExecutable analyzed_executable = {0};
35283623 analyzed_executable.is_inline = true;
35293624 analyzed_executable.fn_entry = fn_entry;
3625 analyzed_executable.c_import_buf = c_import_buf;
35303626 analyzed_executable.backward_branch_count = backward_branch_count;
35313627 analyzed_executable.backward_branch_quota = backward_branch_quota;
35323628 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
46414737 // Analyze the fn body block like any other constant expression.
46424738 AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body;
46434739 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);
46454741 if (result->type_entry->id == TypeTableEntryIdInvalid)
46464742 return ira->codegen->builtin_types.entry_invalid;
46474743
......@@ -4658,7 +4754,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
46584754
46594755 // Fork a scope of the function with known values for the parameters.
46604756 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);
46624758 impl_fn->param_source_nodes = allocate<AstNode *>(call_param_count);
46634759 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);
46644760 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
69297025 return str_type;
69307026}
69317027
7028static 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
7079static 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
7098static 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
7125static 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
69327146static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
69337147 switch (instruction->id) {
69347148 case IrInstructionIdInvalid:
......@@ -7021,6 +7235,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
70217235 return ir_analyze_instruction_compile_err(ira, (IrInstructionCompileErr *)instruction);
70227236 case IrInstructionIdErrName:
70237237 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);
70247246 case IrInstructionIdCast:
70257247 case IrInstructionIdStructFieldPtr:
70267248 case IrInstructionIdEnumFieldPtr:
......@@ -7116,6 +7338,10 @@ bool ir_has_side_effects(IrInstruction *instruction) {
71167338 case IrInstructionIdSetDebugSafety:
71177339 case IrInstructionIdImport:
71187340 case IrInstructionIdCompileErr:
7341 case IrInstructionIdCImport:
7342 case IrInstructionIdCInclude:
7343 case IrInstructionIdCDefine:
7344 case IrInstructionIdCUndef:
71197345 return true;
71207346 case IrInstructionIdPhi:
71217347 case IrInstructionIdUnOp:
......@@ -7164,63 +7390,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
71647390// TODO port over all this commented out code into new IR way of doing things
71657391
71667392
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//
72247393//static TypeTableEntry *analyze_embed_file(CodeGen *g, ImportTableEntry *import,
72257394// BlockContext *context, AstNode *node)
72267395//{
......@@ -7587,51 +7756,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
75877756// return g->builtin_types.entry_invalid;
75887757// }
75897758// }
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//
76317759// case BuiltinFnIdImport:
76327760// return analyze_import(g, import, context, node);
7633// case BuiltinFnIdCImport:
7634// return analyze_c_import(g, import, context, node);
76357761// case BuiltinFnIdBreakpoint:
76367762// mark_impure_fn(g, context, node);
76377763// return g->builtin_types.entry_void;
......@@ -8121,9 +8247,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
81218247// switch (builtin_fn->id) {
81228248// case BuiltinFnIdInvalid:
81238249// case BuiltinFnIdTypeof:
8124// case BuiltinFnIdCInclude:
8125// case BuiltinFnIdCDefine:
8126// case BuiltinFnIdCUndef:
81278250// case BuiltinFnIdImport:
81288251// case BuiltinFnIdCImport:
81298252// case BuiltinFnIdCompileErr:
src/ir.hpp+1-1
......@@ -15,7 +15,7 @@ IrInstruction *ir_gen_fn(CodeGen *g, FnTableEntry *fn_entry);
1515
1616IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
1717 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);
1919
2020TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable,
2121 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
144144 case TypeTableEntryIdNamespace:
145145 {
146146 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 }
148152 return;
149153 }
150154 case TypeTableEntryIdBoundFn:
......@@ -685,6 +689,30 @@ static void ir_print_err_name(IrPrint *irp, IrInstructionErrName *instruction) {
685689 fprintf(irp->f, ")");
686690}
687691
692static void ir_print_c_import(IrPrint *irp, IrInstructionCImport *instruction) {
693 fprintf(irp->f, "@cImport(...)");
694}
695
696static 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
702static 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
710static 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
688716static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
689717 ir_print_prefix(irp, instruction);
690718 switch (instruction->id) {
......@@ -834,6 +862,18 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
834862 case IrInstructionIdErrName:
835863 ir_print_err_name(irp, (IrInstructionErrName *)instruction);
836864 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;
837877 }
838878 fprintf(irp->f, "\n");
839879}
......@@ -854,3 +894,67 @@ void ir_print(FILE *f, IrExecutable *executable, int indent_size) {
854894 }
855895 }
856896}
897
898static 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
913static 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
917static 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
921static 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
925void 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 @@
1414
1515void ir_print(FILE *f, IrExecutable *executable, int indent_size);
1616
17void ir_print_decls(FILE *f, ImportTableEntry *import);
18
19
1720#endif
src/parseh.cpp+174-329
......@@ -31,27 +31,28 @@ struct GlobalValue {
3131 bool is_const;
3232};
3333
34struct Alias {
35 Buf *name;
36 Tld *tld;
37};
38
3439struct Context {
3540 ImportTableEntry *import;
3641 ZigList<ErrorMsg *> *errors;
3742 bool warnings_on;
3843 VisibMod visib_mod;
39 AstNode *root;
4044 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> global_type_table;
41 HashMap<Buf *, GlobalValue, buf_hash, buf_eql_buf> global_value_table;
4245 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table;
43 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_decl_table;
4446 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table;
4547 HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table;
46 HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table;
47 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
48 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> macro_table;
4849 SourceManager *source_manager;
49 ZigList<AstNode *> aliases;
50 ZigList<Alias> aliases;
5051 ZigList<MacroSymbol> macro_symbols;
5152 AstNode *source_node;
53 uint32_t next_anon_index;
5254
5355 CodeGen *codegen;
54 bool transform_extern_fn_ptr;
5556};
5657
5758static 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, ...)
8889 fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg));
8990}
9091
91static uint32_t get_next_node_index(Context *c) {
92 uint32_t result = c->codegen->next_node_index;
93 c->codegen->next_node_index += 1;
92static uint32_t get_next_anon_index(Context *c) {
93 uint32_t result = c->next_anon_index;
94 c->next_anon_index += 1;
9495 return result;
9596}
9697
97static AstNode *create_node(Context *c, NodeType type) {
98 AstNode *node = allocate<AstNode>(1);
99 node->type = type;
100 node->owner = c->import;
101 node->create_index = get_next_node_index(c);
102 return node;
103}
104
105static 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
111static 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;
98static void add_global_alias(Context *c, Buf *name, Tld *tld) {
99 c->import->decls_scope->decl_table.put(name, tld);
116100}
117101
118static AstNode *create_typed_var_decl_node(Context *c, bool is_const, const char *var_name,
119 AstNode *type_node, AstNode *init_node)
120{
121 AstNode *node = create_node(c, NodeTypeVariableDeclaration);
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;
102static void add_global_weak_alias(Context *c, Buf *name, Tld *tld) {
103 Alias *alias = c->aliases.add_one();
104 alias->name = name;
105 alias->tld = tld;
128106}
129107
130static AstNode *create_var_decl_node(Context *c, const char *var_name, AstNode *expr_node) {
131 return create_typed_var_decl_node(c, true, var_name, nullptr, expr_node);
108static void add_global(Context *c, Tld *tld) {
109 return add_global_alias(c, tld->name, tld);
132110}
133111
134static AstNode *create_prefix_node(Context *c, PrefixOp op, AstNode *child_node) {
135 assert(child_node);
136 AstNode *node = create_node(c, NodeTypePrefixOpExpr);
137 node->data.prefix_op_expr.prefix_op = op;
138 node->data.prefix_op_expr.primary_expr = child_node;
139 return node;
112static Tld *get_global(Context *c, Buf *name) {
113 auto entry = c->import->decls_scope->decl_table.maybe_get(name);
114 return entry ? entry->value : nullptr;
140115}
141116
142static AstNode *create_param_decl_node(Context *c, const char *name, AstNode *type_node, bool is_noalias) {
143 assert(type_node);
144 AstNode *node = create_node(c, NodeTypeParamDecl);
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
152static 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
159static 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;
117static const char *decl_name(const Decl *decl) {
118 const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);
119 return (const char *)named_decl->getName().bytes_begin();
164120}
165121
166static AstNode *create_num_lit_float(Context *c, double x) {
167 AstNode *node = create_node(c, NodeTypeNumberLiteral);
168 node->data.number_literal.bignum = allocate_nonzero<BigNum>(1);
169 bignum_init_float(node->data.number_literal.bignum, x);
170 return node;
122static void parseh_init_tld(Context *c, Tld *tld, TldId id, Buf *name) {
123 init_tld(tld, id, name, c->visib_mod, c->source_node, &c->import->decls_scope->base, nullptr);
124 tld->resolution = TldResolutionOk;
171125}
172126
173static AstNode *create_num_lit_float_negative(Context *c, double x, bool negative) {
174 AstNode *num_lit_node = create_num_lit_float(c, x);
175 if (!negative) return num_lit_node;
176 return create_prefix_node(c, PrefixOpNegation, num_lit_node);
127static TldVar *create_global_var(Context *c, Buf *name, TypeTableEntry *var_type, ConstExprValue *var_value, bool is_const) {
128 TldVar *tld_var = allocate<TldVar>(1);
129 parseh_init_tld(c, &tld_var->base, TldIdVar, name);
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;
177132}
178133
179static AstNode *create_num_lit_unsigned(Context *c, uint64_t x) {
180 AstNode *node = create_node(c, NodeTypeNumberLiteral);
181 node->data.number_literal.bignum = allocate_nonzero<BigNum>(1);
182 bignum_init_unsigned(node->data.number_literal.bignum, x);
183 return node;
134static Tld *create_global_char_lit_var(Context *c, Buf *name, uint8_t value) {
135 TldVar *tld_var = create_global_var(c, name, c->codegen->builtin_types.entry_u8,
136 create_const_unsigned_negative(value, false), true);
137 return &tld_var->base;
184138}
185139
186static AstNode *create_num_lit_unsigned_negative(Context *c, uint64_t x, bool negative) {
187 AstNode *num_lit_node = create_num_lit_unsigned(c, x);
188 if (!negative) return num_lit_node;
189 return create_prefix_node(c, PrefixOpNegation, num_lit_node);
140static Tld *create_global_str_lit_var(Context *c, Buf *name, Buf *value) {
141 TypeTableEntry *str_type = get_array_type(c->codegen, c->codegen->builtin_types.entry_u8, buf_len(value));
142 TldVar *tld_var = create_global_var(c, name, str_type, create_const_str_lit(value), true);
143 return &tld_var->base;
190144}
191145
192static AstNode *create_num_lit_signed(Context *c, int64_t x) {
193 if (x >= 0) {
194 return create_num_lit_unsigned(c, x);
195 }
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);
146static Tld *create_global_num_lit_unsigned_negative(Context *c, Buf *name, uint64_t x, bool negative) {
147 TldVar *tld_var = create_global_var(c, name, c->codegen->builtin_types.entry_num_lit_int,
148 create_const_unsigned_negative(x, negative), true);
149 return &tld_var->base;
205150}
206151
207static AstNode *make_type_node(Context *c, TypeTableEntry *type_entry) {
208 zig_panic("TODO bypass AST in parseh");
152static Tld *create_global_num_lit_float(Context *c, Buf *name, double value) {
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;
209156}
210157
211static AstNode *create_fn_proto_node(Context *c, Buf *name, TypeTableEntry *fn_type) {
212 assert(fn_type->id == TypeTableEntryIdFn);
213 AstNode *node = create_node(c, NodeTypeFnProto);
214 node->data.fn_proto.is_inline = true;
215 node->data.fn_proto.visib_mod = c->visib_mod;
216 node->data.fn_proto.name = name;
217 node->data.fn_proto.return_type = make_type_node(c, fn_type->data.fn.fn_type_id.return_type);
218
219 for (size_t i = 0; i < fn_type->data.fn.fn_type_id.param_count; i += 1) {
220 FnTypeParamInfo *info = &fn_type->data.fn.fn_type_id.param_info[i];
221 char arg_name[20];
222 sprintf(arg_name, "arg_%zu", i);
223 node->data.fn_proto.params.append(create_param_decl_node(c, arg_name,
224 make_type_node(c, info->type), info->is_noalias));
158static ConstExprValue *create_const_num_lit_ap(Context *c, const Decl *source_decl, const llvm::APSInt &aps_int) {
159 if (aps_int.isSigned()) {
160 if (aps_int > INT64_MAX || aps_int < INT64_MIN) {
161 emit_warning(c, source_decl, "integer overflow\n");
162 return nullptr;
163 } else {
164 return create_const_signed(aps_int.getExtValue());
165 }
166 } else {
167 if (aps_int > INT64_MAX) {
168 emit_warning(c, source_decl, "integer overflow\n");
169 return nullptr;
170 } else {
171 return create_const_unsigned_negative(aps_int.getExtValue(), false);
172 }
225173 }
226
227 return node;
228174}
229175
230static AstNode *create_one_statement_block(Context *c, AstNode *statement) {
231 AstNode *node = create_node(c, NodeTypeBlock);
232 node->data.block.statements.append(statement);
233
234 return node;
176static Tld *create_global_num_lit_ap(Context *c, const Decl *source_decl, Buf *name,
177 const llvm::APSInt &aps_int)
178{
179 ConstExprValue *const_value = create_const_num_lit_ap(c, source_decl, aps_int);
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;
235184}
236185
237static 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);
240186
241 AstNode *unwrap_node = create_prefix_node(c, PrefixOpUnwrapMaybe, create_symbol_node(c, buf_ptr(var_name)));
187static 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);
242193
243 AstNode *fn_call_node = create_node(c, NodeTypeFnCallExpr);
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;
194 c->global_type_table.put(name, type_entry);
255195}
256196
197static 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;
257201
258
259static const char *decl_name(const Decl *decl) {
260 const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);
261 return (const char *)named_decl->getName().bytes_begin();
202 add_global(c, &tld_container->base);
203 return &tld_container->base;
262204}
263205
264static void add_typedef_node(Context *c, TypeTableEntry *type_decl) {
206static Tld *add_typedef_tld(Context *c, TypeTableEntry *type_decl) {
265207 assert(type_decl);
266208 assert(type_decl->id == TypeTableEntryIdTypeDecl);
267209
268 ScopeDecls *decls_scope = c->import->decls_scope;
269210 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);
271212 tld_typedef->type_entry = type_decl;
272213
273 decls_scope->decl_table.put(&type_decl->name, &tld_typedef->base);
214 add_global(c, &tld_typedef->base);
274215 c->global_type_table.put(&type_decl->name, type_decl);
275}
276
277static 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
291static 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;
296216
297 decls_scope->decl_table.put(&type_entry->name, &tld_container->base);
298}
299
300static 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 }
217 return &tld_typedef->base;
318218}
319219
320220static 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
702602static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
703603 Buf *fn_name = buf_create_from_str(decl_name(fn_decl));
704604
705 if (c->fn_table.maybe_get(fn_name)) {
605 if (get_global(c, fn_name)) {
706606 // we already saw this function
707607 return;
708608 }
......@@ -715,36 +615,19 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
715615 }
716616 assert(fn_type->id == TypeTableEntryIdFn);
717617
718
719 AstNode *node = create_node(c, NodeTypeFnProto);
720 node->data.fn_proto.name = fn_name;
721
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);
618 bool internal_linkage = false;
619 FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, internal_linkage);
620 buf_init_from_buf(&fn_entry->symbol_name, fn_name);
621 fn_entry->type_entry = fn_type;
726622
727623 assert(!fn_type->data.fn.fn_type_id.is_naked);
728624
729 size_t arg_count = fn_type->data.fn.fn_type_id.param_count;
730 Buf name_buf = BUF_INIT;
731 for (size_t i = 0; i < arg_count; i += 1) {
732 FnTypeParamInfo *param_info = &fn_type->data.fn.fn_type_id.param_info[i];
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 }
625 TldFn *tld_fn = allocate<TldFn>(1);
626 parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name);
627 tld_fn->fn_entry = fn_entry;
628 add_global(c, &tld_fn->base);
744629
745
746 c->fn_table.put(buf_create_from_buf(fn_name), true);
747 c->root->data.root.top_level_decls.append(node);
630 c->codegen->fn_protos.append(fn_entry);
748631}
749632
750633static 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)
775658 emit_warning(c, typedef_decl, "typedef %s - unresolved child type", buf_ptr(type_name));
776659 return;
777660 }
778 add_const_var_node(c, type_name, child_type);
779}
780
781static 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);
661 add_const_type(c, type_name, child_type);
784662}
785663
786664static void replace_with_fwd_decl(Context *c, TypeTableEntry *struct_type, Buf *full_type_name) {
787665 unsigned line = c->source_node ? c->source_node->line : 0;
788666 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),
790668 ZigLLVMFileToScope(c->import->di_file), c->import->di_file, line);
791669
792670 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)
803681
804682 Buf *bare_name;
805683 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));
807685 } else {
808686 bare_name = buf_create_from_str(raw_name);
809687 }
......@@ -876,11 +754,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
876754
877755 // in C each enum value is in the global namespace. so we put them there too.
878756 // 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));
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});
757 add_global(c, create_global_num_lit_unsigned_negative(c, enum_val_name, i, false));
884758 }
885759
886760 // create llvm type for root struct
......@@ -912,20 +786,14 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
912786 it != it_end; ++it)
913787 {
914788 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 }
919789
920790 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
921791
922 AstNode *type_node = make_type_node(c, enum_type);
923 AstNode *var_decl_node = create_typed_var_decl_node(c, true, buf_ptr(enum_val_name),
924 type_node, num_lit_node);
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});
792 Tld *tld = create_global_num_lit_ap(c, enum_decl, enum_val_name, enum_const->getInitVal());
793 if (!tld)
794 return c->codegen->builtin_types.entry_invalid;
928795
796 add_global(c, tld);
929797 }
930798
931799 return enum_type;
......@@ -940,20 +808,25 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
940808
941809 // make an alias without the "enum_" prefix. this will get emitted at the
942810 // end if it doesn't conflict with anything else
943 if (decl_name(enum_decl)[0] != 0) {
944 add_alias(c, decl_name(enum_decl), buf_ptr(&enum_type->name));
945 }
811 bool is_anonymous = (decl_name(enum_decl)[0] == 0);
812 if (is_anonymous)
813 return;
814
815 Buf *bare_name = buf_create_from_str(decl_name(enum_decl));
946816
947817 if (enum_type->id == TypeTableEntryIdEnum) {
948818 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);
950821 } else {
951822 TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&enum_type->name),
952823 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);
954826 }
955827 } 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);
957830 } else {
958831 zig_unreachable();
959832 }
......@@ -974,7 +847,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
974847
975848 Buf *bare_name;
976849 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));
978851 } else {
979852 bare_name = buf_create_from_str(raw_name);
980853 }
......@@ -1096,23 +969,20 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) {
1096969
1097970 assert(struct_type->id == TypeTableEntryIdStruct);
1098971
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)
1100974 return;
1101 }
1102 c->struct_decl_table.put(&struct_type->name, struct_type);
1103975
1104 // make an alias without the "struct_" prefix. this will get emitted at the
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 }
976 Buf *bare_name = buf_create_from_str(decl_name(record_decl));
1109977
1110978 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);
1112981 } else {
1113982 TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&struct_type->name),
1114983 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);
1116986 }
1117987}
1118988
......@@ -1151,7 +1021,7 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
11511021 emit_warning(c, var_decl, "ignoring variable '%s' - unable to evaluate initializer\n", buf_ptr(name));
11521022 return;
11531023 }
1154 AstNode *init_node = nullptr;
1024 ConstExprValue *init_value = nullptr;
11551025 switch (ap_value->getKind()) {
11561026 case APValue::Int:
11571027 {
......@@ -1161,10 +1031,10 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
11611031 "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name));
11621032 return;
11631033 }
1164 init_node = create_ap_num_lit_node(c, var_decl, ap_value->getInt());
1165 if (!init_node) {
1034 init_value = create_const_num_lit_ap(c, var_decl, ap_value->getInt());
1035 if (!init_value)
11661036 return;
1167 }
1037
11681038 break;
11691039 }
11701040 case APValue::Uninitialized:
......@@ -1183,19 +1053,15 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
11831053 return;
11841054 }
11851055
1186 AstNode *type_node = make_type_node(c, var_type);
1187 AstNode *var_node = create_typed_var_decl_node(c, true, buf_ptr(name), type_node, init_node);
1188 c->root->data.root.top_level_decls.append(var_node);
1189 c->global_value_table.put(name, {var_type, true});
1056 TldVar *tld_var = create_global_var(c, name, var_type, init_value, true);
1057 add_global(c, &tld_var->base);
11901058 return;
11911059 }
11921060
11931061 if (is_extern) {
1194 AstNode *type_node = make_type_node(c, var_type);
1195 AstNode *var_node = create_typed_var_decl_node(c, is_const, buf_ptr(name), type_node, nullptr);
1196 var_node->data.variable_declaration.is_extern = true;
1197 c->root->data.root.top_level_decls.append(var_node);
1198 c->global_value_table.put(name, {var_type, is_const});
1062 TldVar *tld_var = create_global_var(c, name, var_type, nullptr, is_const);
1063 tld_var->var->is_extern = true;
1064 add_global(c, &tld_var->base);
11991065 return;
12001066 }
12011067
......@@ -1233,10 +1099,7 @@ static bool name_exists(Context *c, Buf *name) {
12331099 if (c->global_type_table.maybe_get(name)) {
12341100 return true;
12351101 }
1236 if (c->global_value_table.maybe_get(name)) {
1237 return true;
1238 }
1239 if (c->fn_table.maybe_get(name)) {
1102 if (get_global(c, name)) {
12401103 return true;
12411104 }
12421105 if (c->macro_table.maybe_get(name)) {
......@@ -1245,31 +1108,13 @@ static bool name_exists(Context *c, Buf *name) {
12451108 return false;
12461109}
12471110
1248static 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
12641111static void render_aliases(Context *c) {
12651112 for (size_t i = 0; i < c->aliases.length; i += 1) {
1266 AstNode *alias_node = c->aliases.at(i);
1267 assert(alias_node->type == NodeTypeVariableDeclaration);
1268 Buf *name = alias_node->data.variable_declaration.symbol;
1269 if (name_exists(c, name)) {
1113 Alias *alias = &c->aliases.at(i);
1114 if (name_exists(c, alias->name))
12701115 continue;
1271 }
1272 c->root->data.root.top_level_decls.append(alias_node);
1116
1117 add_global_alias(c, alias->name, alias->tld);
12731118 }
12741119}
12751120
......@@ -1280,8 +1125,8 @@ static void render_macros(Context *c) {
12801125 if (!entry)
12811126 break;
12821127
1283 AstNode *var_node = entry->value;
1284 c->root->data.root.top_level_decls.append(var_node);
1128 Tld *var_tld = entry->value;
1129 add_global(c, var_tld);
12851130 }
12861131}
12871132
......@@ -1300,30 +1145,27 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch
13001145 switch (tok->id) {
13011146 case CTokIdCharLit:
13021147 if (is_last && is_first) {
1303 AstNode *var_node = create_var_decl_node(c, buf_ptr(name),
1304 create_char_lit_node(c, tok->data.char_lit));
1305 c->macro_table.put(name, var_node);
1148 Tld *tld = create_global_char_lit_var(c, name, tok->data.char_lit);
1149 c->macro_table.put(name, tld);
13061150 }
13071151 return;
13081152 case CTokIdStrLit:
13091153 if (is_last && is_first) {
1310 AstNode *var_node = create_var_decl_node(c, buf_ptr(name),
1311 create_str_lit_node(c, buf_create_from_buf(&tok->data.str_lit)));
1312 c->macro_table.put(name, var_node);
1154 Tld *tld = create_global_str_lit_var(c, name, buf_create_from_buf(&tok->data.str_lit));
1155 c->macro_table.put(name, tld);
13131156 }
13141157 return;
13151158 case CTokIdNumLitInt:
13161159 if (is_last) {
1317 AstNode *var_node = create_var_decl_node(c, buf_ptr(name),
1318 create_num_lit_unsigned_negative(c, tok->data.num_lit_int, negate));
1319 c->macro_table.put(name, var_node);
1160 Tld *tld = create_global_num_lit_unsigned_negative(c, name, tok->data.num_lit_int, negate);
1161 c->macro_table.put(name, tld);
13201162 }
13211163 return;
13221164 case CTokIdNumLitFloat:
13231165 if (is_last) {
1324 AstNode *var_node = create_var_decl_node(c, buf_ptr(name),
1325 create_num_lit_float_negative(c, tok->data.num_lit_float, negate));
1326 c->macro_table.put(name, var_node);
1166 double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float;
1167 Tld *tld = create_global_num_lit_float(c, name, value);
1168 c->macro_table.put(name, tld);
13271169 }
13281170 return;
13291171 case CTokIdSymbol:
......@@ -1351,22 +1193,31 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch
13511193static void process_symbol_macros(Context *c) {
13521194 for (size_t i = 0; i < c->macro_symbols.length; i += 1) {
13531195 MacroSymbol ms = c->macro_symbols.at(i);
1354 if (name_exists_and_const(c, ms.value)) {
1355 AstNode *var_node = create_var_decl_node(c, buf_ptr(ms.name),
1356 create_symbol_node(c, buf_ptr(ms.value)));
1357 c->macro_table.put(ms.name, var_node);
1358 } else if (c->transform_extern_fn_ptr || true) { // TODO take off the || true
1359 if (auto entry = c->global_value_table.maybe_get(ms.value)) {
1360 TypeTableEntry *maybe_type = entry->value.type;
1361 if (maybe_type->id == TypeTableEntryIdMaybe) {
1362 TypeTableEntry *fn_type = maybe_type->data.maybe.child_type;
1363 if (fn_type->id == TypeTableEntryIdFn) {
1364 AstNode *fn_node = create_inline_fn_node(c, ms.name, ms.value, fn_type);
1365 c->macro_table.put(ms.name, fn_node);
1366 }
1196
1197 // If this macro aliases another top level declaration, we can make that happen by
1198 // putting another entry in the decl table pointing to the same top level decl.
1199 Tld *existing_tld = get_global(c, ms.value);
1200 if (!existing_tld)
1201 continue;
1202
1203 // If a macro aliases a global variable which is a function pointer, we conclude that
1204 // the macro is intended to represent a function that assumes the function pointer
1205 // variable is non-null and calls it.
1206 if (existing_tld->id == TldIdVar) {
1207 TldVar *tld_var = (TldVar *)existing_tld;
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;
13671216 }
13681217 }
13691218 }
1219
1220 add_global_alias(c, ms.value, existing_tld);
13701221 }
13711222}
13721223
......@@ -1430,12 +1281,9 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
14301281 c->errors = errors;
14311282 c->visib_mod = VisibModPub;
14321283 c->global_type_table.init(8);
1433 c->global_value_table.init(8);
14341284 c->enum_type_table.init(8);
14351285 c->struct_type_table.init(8);
1436 c->struct_decl_table.init(8);
14371286 c->decl_table.init(8);
1438 c->fn_table.init(8);
14391287 c->macro_table.init(8);
14401288 c->codegen = codegen;
14411289 c->source_node = source_node;
......@@ -1521,7 +1369,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
15211369 err_unit = std::move(ast_unit);
15221370 }
15231371
1524 for (ASTUnit::stored_diag_iterator it = err_unit->stored_diag_begin(),
1372 for (ASTUnit::stored_diag_iterator it = err_unit->stored_diag_begin(),
15251373 it_end = err_unit->stored_diag_end();
15261374 it != it_end; ++it)
15271375 {
......@@ -1561,7 +1409,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
15611409
15621410 c->source_manager = &ast_unit->getSourceManager();
15631411
1564 c->root = create_node(c, NodeTypeRoot);
15651412 ast_unit->visitLocalTopLevelDecls(c, decl_visitor);
15661413
15671414 process_preprocessor_entities(c, *ast_unit);
......@@ -1571,7 +1418,5 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
15711418 render_macros(c);
15721419 render_aliases(c);
15731420
1574 import->root = c->root;
1575
15761421 return 0;
15771422}