authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-02 04:11:23-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-02 04:11:23-04:00
loge1d5da20a5d5e54b9dba6031c97fe232192e69cd
tree78d17c42ff26bed171582d31aa06647571d6cfdf
parent0f38955ee5b5ff2251fdbc3ac4d95a9aecfdfd3c

rewrite parseh to use AST instead of direct types

some tests still failing

11 files changed, 710 insertions(+), 1152 deletions(-)

src/all_types.hpp+1
...@@ -751,6 +751,7 @@ struct AstNodeContainerDecl {...@@ -751,6 +751,7 @@ struct AstNodeContainerDecl {
751 ZigList<AstNode *> fields;751 ZigList<AstNode *> fields;
752 ZigList<AstNode *> decls;752 ZigList<AstNode *> decls;
753 ContainerLayout layout;753 ContainerLayout layout;
754 AstNode *init_arg_expr; // enum(T) or struct(endianness)
754};755};
755756
756struct AstNodeStructField {757struct AstNodeStructField {
src/ast_render.cpp+20-158
...@@ -112,16 +112,16 @@ static const char *extern_string(bool is_extern) {...@@ -112,16 +112,16 @@ static const char *extern_string(bool is_extern) {
112 return is_extern ? "extern " : "";112 return is_extern ? "extern " : "";
113}113}
114114
115static const char *calling_convention_string(CallingConvention cc) {115//static const char *calling_convention_string(CallingConvention cc) {
116 switch (cc) {116// switch (cc) {
117 case CallingConventionUnspecified: return "";117// case CallingConventionUnspecified: return "";
118 case CallingConventionC: return "extern ";118// case CallingConventionC: return "extern ";
119 case CallingConventionCold: return "coldcc ";119// case CallingConventionCold: return "coldcc ";
120 case CallingConventionNaked: return "nakedcc ";120// case CallingConventionNaked: return "nakedcc ";
121 case CallingConventionStdcall: return "stdcallcc ";121// case CallingConventionStdcall: return "stdcallcc ";
122 }122// }
123 zig_unreachable();123// zig_unreachable();
124}124//}
125125
126static const char *inline_string(bool is_inline) {126static const char *inline_string(bool is_inline) {
127 return is_inline ? "inline " : "";127 return is_inline ? "inline " : "";
...@@ -439,8 +439,10 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -439,8 +439,10 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
439 fprintf(ar->f, ")");439 fprintf(ar->f, ")");
440440
441 AstNode *return_type_node = node->data.fn_proto.return_type;441 AstNode *return_type_node = node->data.fn_proto.return_type;
442 fprintf(ar->f, " -> ");442 if (return_type_node != nullptr) {
443 render_node_grouped(ar, return_type_node);443 fprintf(ar->f, " -> ");
444 render_node_grouped(ar, return_type_node);
445 }
444 break;446 break;
445 }447 }
446 case NodeTypeFnDef:448 case NodeTypeFnDef:
...@@ -651,16 +653,19 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -651,16 +653,19 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
651 break;653 break;
652 case NodeTypeContainerDecl:654 case NodeTypeContainerDecl:
653 {655 {
656 const char *layout_str = layout_string(node->data.container_decl.layout);
654 const char *container_str = container_string(node->data.container_decl.kind);657 const char *container_str = container_string(node->data.container_decl.kind);
655 fprintf(ar->f, "%s {\n", container_str);658 fprintf(ar->f, "%s%s {\n", layout_str, container_str);
656 ar->indent += ar->indent_size;659 ar->indent += ar->indent_size;
657 for (size_t field_i = 0; field_i < node->data.container_decl.fields.length; field_i += 1) {660 for (size_t field_i = 0; field_i < node->data.container_decl.fields.length; field_i += 1) {
658 AstNode *field_node = node->data.container_decl.fields.at(field_i);661 AstNode *field_node = node->data.container_decl.fields.at(field_i);
659 assert(field_node->type == NodeTypeStructField);662 assert(field_node->type == NodeTypeStructField);
660 print_indent(ar);663 print_indent(ar);
661 print_symbol(ar, field_node->data.struct_field.name);664 print_symbol(ar, field_node->data.struct_field.name);
662 fprintf(ar->f, ": ");665 if (field_node->data.struct_field.type != nullptr) {
663 render_node_grouped(ar, field_node->data.struct_field.type);666 fprintf(ar->f, ": ");
667 render_node_grouped(ar, field_node->data.struct_field.type);
668 }
664 fprintf(ar->f, ",\n");669 fprintf(ar->f, ",\n");
665 }670 }
666671
...@@ -989,146 +994,3 @@ void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size) {...@@ -989,146 +994,3 @@ void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size) {
989994
990 render_node_grouped(&ar, node);995 render_node_grouped(&ar, node);
991}996}
992
993static void ast_render_tld_fn(AstRender *ar, Buf *name, TldFn *tld_fn) {
994 FnTableEntry *fn_entry = tld_fn->fn_entry;
995 FnTypeId *fn_type_id = &fn_entry->type_entry->data.fn.fn_type_id;
996 const char *visib_mod_str = visib_mod_string(tld_fn->base.visib_mod);
997 const char *cc_str = calling_convention_string(fn_type_id->cc);
998 fprintf(ar->f, "%s%sfn %s(", visib_mod_str, cc_str, buf_ptr(&fn_entry->symbol_name));
999 for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
1000 FnTypeParamInfo *param_info = &fn_type_id->param_info[i];
1001 if (i != 0) {
1002 fprintf(ar->f, ", ");
1003 }
1004 if (param_info->is_noalias) {
1005 fprintf(ar->f, "noalias ");
1006 }
1007 Buf *param_name = tld_fn->fn_entry->param_names ? tld_fn->fn_entry->param_names[i] : buf_sprintf("arg%" ZIG_PRI_usize "", i);
1008 fprintf(ar->f, "%s: %s", buf_ptr(param_name), buf_ptr(&param_info->type->name));
1009 }
1010 if (fn_type_id->return_type->id == TypeTableEntryIdVoid) {
1011 fprintf(ar->f, ");\n");
1012 } else {
1013 fprintf(ar->f, ") -> %s;\n", buf_ptr(&fn_type_id->return_type->name));
1014 }
1015}
1016
1017static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {
1018 VariableTableEntry *var = tld_var->var;
1019 const char *visib_mod_str = visib_mod_string(tld_var->base.visib_mod);
1020 const char *const_or_var = const_or_var_string(var->src_is_const);
1021 const char *extern_str = extern_string(var->linkage == VarLinkageExternal);
1022 fprintf(ar->f, "%s%s%s %s", visib_mod_str, extern_str, const_or_var, buf_ptr(name));
1023
1024 if (var->value->type->id == TypeTableEntryIdNumLitFloat ||
1025 var->value->type->id == TypeTableEntryIdNumLitInt ||
1026 var->value->type->id == TypeTableEntryIdMetaType)
1027 {
1028 // skip type
1029 } else {
1030 fprintf(ar->f, ": %s", buf_ptr(&var->value->type->name));
1031 }
1032
1033 if (var->value->special == ConstValSpecialRuntime) {
1034 fprintf(ar->f, ";\n");
1035 return;
1036 }
1037
1038 fprintf(ar->f, " = ");
1039
1040 if (var->value->special == ConstValSpecialStatic &&
1041 var->value->type->id == TypeTableEntryIdMetaType)
1042 {
1043 TypeTableEntry *type_entry = var->value->data.x_type;
1044 if (type_entry->id == TypeTableEntryIdStruct) {
1045 const char *layout_str = layout_string(type_entry->data.structure.layout);
1046 fprintf(ar->f, "%sstruct {\n", layout_str);
1047 if (type_entry->data.structure.complete) {
1048 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
1049 TypeStructField *field = &type_entry->data.structure.fields[i];
1050 fprintf(ar->f, " ");
1051 print_symbol(ar, field->name);
1052 fprintf(ar->f, ": %s,\n", buf_ptr(&field->type_entry->name));
1053 }
1054 }
1055 fprintf(ar->f, "}");
1056 } else if (type_entry->id == TypeTableEntryIdEnum) {
1057 const char *layout_str = layout_string(type_entry->data.enumeration.layout);
1058 fprintf(ar->f, "%senum {\n", layout_str);
1059 if (type_entry->data.enumeration.complete) {
1060 for (size_t i = 0; i < type_entry->data.enumeration.src_field_count; i += 1) {
1061 TypeEnumField *field = &type_entry->data.enumeration.fields[i];
1062 fprintf(ar->f, " ");
1063 print_symbol(ar, field->name);
1064 if (field->type_entry->id == TypeTableEntryIdVoid) {
1065 fprintf(ar->f, ",\n");
1066 } else {
1067 fprintf(ar->f, ": %s,\n", buf_ptr(&field->type_entry->name));
1068 }
1069 }
1070 }
1071 fprintf(ar->f, "}");
1072 } else if (type_entry->id == TypeTableEntryIdUnion) {
1073 fprintf(ar->f, "union {");
1074 fprintf(ar->f, "TODO");
1075 fprintf(ar->f, "}");
1076 } else if (type_entry->id == TypeTableEntryIdOpaque) {
1077 if (buf_eql_buf(&type_entry->name, name)) {
1078 fprintf(ar->f, "@OpaqueType()");
1079 } else {
1080 fprintf(ar->f, "%s", buf_ptr(&type_entry->name));
1081 }
1082 } else {
1083 fprintf(ar->f, "%s", buf_ptr(&type_entry->name));
1084 }
1085 } else {
1086 Buf buf = BUF_INIT;
1087 buf_resize(&buf, 0);
1088 render_const_value(ar->codegen, &buf, var->value);
1089 fprintf(ar->f, "%s", buf_ptr(&buf));
1090 }
1091
1092 fprintf(ar->f, ";\n");
1093}
1094
1095void ast_render_decls(CodeGen *codegen, FILE *f, int indent_size, ImportTableEntry *import) {
1096 AstRender ar = {0};
1097 ar.codegen = codegen;
1098 ar.f = f;
1099 ar.indent_size = indent_size;
1100 ar.indent = 0;
1101
1102 auto it = import->decls_scope->decl_table.entry_iterator();
1103 for (;;) {
1104 auto *entry = it.next();
1105 if (!entry)
1106 break;
1107
1108 Tld *tld = entry->value;
1109
1110 if (tld->name != nullptr && !buf_eql_buf(entry->key, tld->name)) {
1111 fprintf(ar.f, "pub const ");
1112 print_symbol(&ar, entry->key);
1113 fprintf(ar.f, " = %s;\n", buf_ptr(tld->name));
1114 continue;
1115 }
1116
1117 switch (tld->id) {
1118 case TldIdVar:
1119 ast_render_tld_var(&ar, entry->key, (TldVar *)tld);
1120 break;
1121 case TldIdFn:
1122 ast_render_tld_fn(&ar, entry->key, (TldFn *)tld);
1123 break;
1124 case TldIdContainer:
1125 fprintf(stdout, "container\n");
1126 break;
1127 case TldIdCompTime:
1128 fprintf(stdout, "comptime\n");
1129 break;
1130 }
1131 }
1132}
1133
1134
src/ast_render.hpp-2
...@@ -19,7 +19,5 @@ void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size);...@@ -19,7 +19,5 @@ void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size);
1919
20const char *container_string(ContainerKind kind);20const char *container_string(ContainerKind kind);
2121
22void ast_render_decls(CodeGen *codegen, FILE *f, int indent_size, ImportTableEntry *import);
23
24#endif22#endif
2523
src/bigint.cpp+19
...@@ -165,6 +165,25 @@ void bigint_init_signed(BigInt *dest, int64_t x) {...@@ -165,6 +165,25 @@ void bigint_init_signed(BigInt *dest, int64_t x) {
165 dest->data.digit = ((uint64_t)(-(x + 1))) + 1;165 dest->data.digit = ((uint64_t)(-(x + 1))) + 1;
166}166}
167167
168void bigint_init_data(BigInt *dest, const uint64_t *digits, size_t digit_count, bool is_negative) {
169 if (digit_count == 0) {
170 return bigint_init_unsigned(dest, 0);
171 } else if (digit_count == 1) {
172 dest->digit_count = 1;
173 dest->data.digit = digits[0];
174 dest->is_negative = is_negative;
175 bigint_normalize(dest);
176 return;
177 }
178
179 dest->digit_count = digit_count;
180 dest->is_negative = is_negative;
181 dest->data.digits = allocate_nonzero<uint64_t>(digit_count);
182 memcpy(dest->data.digits, digits, sizeof(uint64_t) * digit_count);
183
184 bigint_normalize(dest);
185}
186
168void bigint_init_bigint(BigInt *dest, const BigInt *src) {187void bigint_init_bigint(BigInt *dest, const BigInt *src) {
169 if (src->digit_count == 0) {188 if (src->digit_count == 0) {
170 return bigint_init_unsigned(dest, 0);189 return bigint_init_unsigned(dest, 0);
src/bigint.hpp+1
...@@ -34,6 +34,7 @@ void bigint_init_u128(BigInt *dest, unsigned __int128 x);...@@ -34,6 +34,7 @@ void bigint_init_u128(BigInt *dest, unsigned __int128 x);
34void bigint_init_signed(BigInt *dest, int64_t x);34void bigint_init_signed(BigInt *dest, int64_t x);
35void bigint_init_bigint(BigInt *dest, const BigInt *src);35void bigint_init_bigint(BigInt *dest, const BigInt *src);
36void bigint_init_bigfloat(BigInt *dest, const BigFloat *op);36void bigint_init_bigfloat(BigInt *dest, const BigFloat *op);
37void bigint_init_data(BigInt *dest, const uint64_t *digits, size_t digit_count, bool is_negative);
3738
38// panics if number won't fit39// panics if number won't fit
39uint64_t bigint_as_unsigned(const BigInt *bigint);40uint64_t bigint_as_unsigned(const BigInt *bigint);
src/codegen.hpp-1
...@@ -55,7 +55,6 @@ void codegen_add_assembly(CodeGen *g, Buf *path);...@@ -55,7 +55,6 @@ void codegen_add_assembly(CodeGen *g, Buf *path);
55void codegen_add_object(CodeGen *g, Buf *object_path);55void codegen_add_object(CodeGen *g, Buf *object_path);
5656
57void codegen_parseh(CodeGen *g, Buf *path);57void codegen_parseh(CodeGen *g, Buf *path);
58void codegen_render_ast(CodeGen *g, FILE *f, int indent_size);
5958
6059
61#endif60#endif
src/ir.cpp+11-66
...@@ -6114,9 +6114,14 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -6114,9 +6114,14 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
6114 return irb->codegen->invalid_instruction;6114 return irb->codegen->invalid_instruction;
6115 }6115 }
61166116
6117 IrInstruction *return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope);6117 IrInstruction *return_type;
6118 if (return_type == irb->codegen->invalid_instruction)6118 if (node->data.fn_proto.return_type == nullptr) {
6119 return irb->codegen->invalid_instruction;6119 return_type = ir_build_const_void(irb, parent_scope, node);
6120 } else {
6121 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope);
6122 if (return_type == irb->codegen->invalid_instruction)
6123 return irb->codegen->invalid_instruction;
6124 }
61206125
6121 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);6126 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);
6122}6127}
...@@ -13358,9 +13363,11 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc...@@ -13358,9 +13363,11 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc
13358 if (ira->codegen->verbose) {13363 if (ira->codegen->verbose) {
13359 fprintf(stderr, "\nC imports:\n");13364 fprintf(stderr, "\nC imports:\n");
13360 fprintf(stderr, "-----------\n");13365 fprintf(stderr, "-----------\n");
13361 ast_render_decls(ira->codegen, stderr, 4, child_import);13366 ast_render(ira->codegen, stderr, child_import->root, 4);
13362 }13367 }
1336313368
13369 scan_decls(ira->codegen, child_import->decls_scope, child_import->root);
13370
13364 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);13371 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
13365 out_val->data.x_import = child_import;13372 out_val->data.x_import = child_import;
13366 return ira->codegen->builtin_types.entry_namespace;13373 return ira->codegen->builtin_types.entry_namespace;
...@@ -15515,65 +15522,3 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -15515,65 +15522,3 @@ bool ir_has_side_effects(IrInstruction *instruction) {
15515 }15522 }
15516 zig_unreachable();15523 zig_unreachable();
15517}15524}
15518
15519FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableEntry *var, Scope *parent_scope) {
15520 FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdInternal);
15521 buf_init_from_buf(&fn_entry->symbol_name, fn_name);
15522
15523 fn_entry->fndef_scope = create_fndef_scope(nullptr, parent_scope, fn_entry);
15524 fn_entry->child_scope = &fn_entry->fndef_scope->base;
15525
15526 assert(var->value->type->id == TypeTableEntryIdMaybe);
15527 TypeTableEntry *src_fn_type = var->value->type->data.maybe.child_type;
15528 assert(src_fn_type->id == TypeTableEntryIdFn);
15529
15530 FnTypeId new_fn_type = src_fn_type->data.fn.fn_type_id;
15531 new_fn_type.cc = CallingConventionUnspecified;
15532
15533 fn_entry->type_entry = get_fn_type(codegen, &new_fn_type);
15534
15535 IrBuilder ir_builder = {0};
15536 IrBuilder *irb = &ir_builder;
15537
15538 irb->codegen = codegen;
15539 irb->exec = &fn_entry->ir_executable;
15540
15541 AstNode *source_node = parent_scope->source_node;
15542
15543 size_t arg_count = fn_entry->type_entry->data.fn.fn_type_id.param_count;
15544 IrInstruction **args = allocate<IrInstruction *>(arg_count);
15545 VariableTableEntry **arg_vars = allocate<VariableTableEntry *>(arg_count);
15546
15547 define_local_param_variables(codegen, fn_entry, arg_vars);
15548 Scope *scope = fn_entry->child_scope;
15549
15550 irb->current_basic_block = ir_build_basic_block(irb, scope, "Entry");
15551 // Entry block gets a reference because we enter it to begin.
15552 ir_ref_bb(irb->current_basic_block);
15553
15554 IrInstruction *maybe_fn_ptr = ir_build_var_ptr(irb, scope, source_node, var, true, false);
15555 IrInstruction *unwrapped_fn_ptr = ir_build_unwrap_maybe(irb, scope, source_node, maybe_fn_ptr, true);
15556 IrInstruction *fn_ref_instruction = ir_build_load_ptr(irb, scope, source_node, unwrapped_fn_ptr);
15557
15558 for (size_t i = 0; i < arg_count; i += 1) {
15559 IrInstruction *var_ptr_instruction = ir_build_var_ptr(irb, scope, source_node, arg_vars[i], true, false);
15560 args[i] = ir_build_load_ptr(irb, scope, source_node, var_ptr_instruction);
15561 }
15562
15563 IrInstruction *call_instruction = ir_build_call(irb, scope, source_node, nullptr, fn_ref_instruction,
15564 arg_count, args, false, false);
15565 ir_build_return(irb, scope, source_node, call_instruction);
15566
15567 if (codegen->verbose) {
15568 fprintf(stderr, "{\n");
15569 ir_print(codegen, stderr, &fn_entry->ir_executable, 4);
15570 fprintf(stderr, "}\n");
15571 }
15572
15573 analyze_fn_ir(codegen, fn_entry, nullptr);
15574
15575 codegen->fn_defs.append(fn_entry);
15576
15577 return fn_entry;
15578}
15579
src/ir.hpp-2
...@@ -24,6 +24,4 @@ TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutabl...@@ -24,6 +24,4 @@ TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutabl
24bool ir_has_side_effects(IrInstruction *instruction);24bool ir_has_side_effects(IrInstruction *instruction);
25ConstExprValue *const_ptr_pointee(CodeGen *codegen, ConstExprValue *const_val);25ConstExprValue *const_ptr_pointee(CodeGen *codegen, ConstExprValue *const_val);
2626
27FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableEntry *var, Scope *parent_scope);
28
29#endif27#endif
src/main.cpp+1-1
...@@ -670,7 +670,7 @@ int main(int argc, char **argv) {...@@ -670,7 +670,7 @@ int main(int argc, char **argv) {
670 return EXIT_SUCCESS;670 return EXIT_SUCCESS;
671 } else if (cmd == CmdParseH) {671 } else if (cmd == CmdParseH) {
672 codegen_parseh(g, in_file_buf);672 codegen_parseh(g, in_file_buf);
673 ast_render_decls(g, stdout, 4, g->root_import);673 ast_render(g, stdout, g->root_import->root, 4);
674 if (timing_info)674 if (timing_info)
675 codegen_print_timing_report(g, stdout);675 codegen_print_timing_report(g, stdout);
676 return EXIT_SUCCESS;676 return EXIT_SUCCESS;
src/parseh.cpp+643-918
...@@ -15,6 +15,7 @@...@@ -15,6 +15,7 @@
15#include "parseh.hpp"15#include "parseh.hpp"
16#include "parser.hpp"16#include "parser.hpp"
1717
18
18#include <clang/Frontend/ASTUnit.h>19#include <clang/Frontend/ASTUnit.h>
19#include <clang/Frontend/CompilerInstance.h>20#include <clang/Frontend/CompilerInstance.h>
20#include <clang/AST/Expr.h>21#include <clang/AST/Expr.h>
...@@ -28,14 +29,9 @@ struct MacroSymbol {...@@ -28,14 +29,9 @@ struct MacroSymbol {
28 Buf *value;29 Buf *value;
29};30};
3031
31struct GlobalValue {
32 TypeTableEntry *type;
33 bool is_const;
34};
35
36struct Alias {32struct Alias {
37 Buf *name;33 Buf *name;
38 Tld *tld;34 AstNode *node;
39};35};
4036
41struct Context {37struct Context {
...@@ -43,30 +39,26 @@ struct Context {...@@ -43,30 +39,26 @@ struct Context {
43 ZigList<ErrorMsg *> *errors;39 ZigList<ErrorMsg *> *errors;
44 bool warnings_on;40 bool warnings_on;
45 VisibMod visib_mod;41 VisibMod visib_mod;
4642 AstNode *root;
47 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> global_type_table;43 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_type_table;
48 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_type_table2;44 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> struct_type_table;
4945 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> enum_type_table;
50 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table;46 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
51 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table;47 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
52 HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table;
53 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> macro_table;
54 SourceManager *source_manager;48 SourceManager *source_manager;
55 ZigList<Alias> aliases;49 ZigList<Alias> aliases;
56 ZigList<MacroSymbol> macro_symbols;50 ZigList<MacroSymbol> macro_symbols;
57 AstNode *source_node;51 AstNode *source_node;
58 uint32_t next_anon_index;
5952
60 CodeGen *codegen;53 CodeGen *codegen;
61 ASTContext *ctx;54 ASTContext *ctx;
62};55};
6356
64static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl,57static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);
65 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table);58static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
6659static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc,
67static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl);60 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> *type_table);
68static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl);61static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
69static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
7062
7163
72__attribute__ ((format (printf, 3, 4)))64__attribute__ ((format (printf, 3, 4)))
...@@ -93,522 +85,226 @@ static void emit_warning(Context *c, const SourceLocation &sl, const char *forma...@@ -93,522 +85,226 @@ static void emit_warning(Context *c, const SourceLocation &sl, const char *forma
93 fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg));85 fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg));
94}86}
9587
96static uint32_t get_next_anon_index(Context *c) {88static void add_global_weak_alias(Context *c, Buf *name, AstNode *node) {
97 uint32_t result = c->next_anon_index;
98 c->next_anon_index += 1;
99 return result;
100}
101
102static void add_global_alias(Context *c, Buf *name, Tld *tld) {
103 c->import->decls_scope->decl_table.put(name, tld);
104}
105
106static void add_global_weak_alias(Context *c, Buf *name, Tld *tld) {
107 Alias *alias = c->aliases.add_one();89 Alias *alias = c->aliases.add_one();
108 alias->name = name;90 alias->name = name;
109 alias->tld = tld;91 alias->node = node;
110}92}
11193
112static void add_global(Context *c, Tld *tld) {94static AstNode * trans_create_node(Context *c, NodeType id) {
113 return add_global_alias(c, tld->name, tld);95 AstNode *node = allocate<AstNode>(1);
96 node->type = id;
97 node->owner = c->import;
98 // TODO line/column. mapping to C file??
99 return node;
114}100}
115101
116static Tld *get_global(Context *c, Buf *name) {102static AstNode *trans_create_node_float_lit(Context *c, double value) {
117 {103 AstNode *node = trans_create_node(c, NodeTypeFloatLiteral);
118 auto entry = c->import->decls_scope->decl_table.maybe_get(name);104 node->data.float_literal.bigfloat = allocate<BigFloat>(1);
119 if (entry)105 bigfloat_init_64(node->data.float_literal.bigfloat, value);
120 return entry->value;106 return node;
121 }
122 {
123 auto entry = c->macro_table.maybe_get(name);
124 if (entry)
125 return entry->value;
126 }
127 return nullptr;
128}107}
129108
130static const char *decl_name(const Decl *decl) {109static AstNode *trans_create_node_symbol(Context *c, Buf *name) {
131 const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);110 AstNode *node = trans_create_node(c, NodeTypeSymbol);
132 return (const char *)named_decl->getName().bytes_begin();111 node->data.symbol_expr.symbol = name;
112 return node;
133}113}
134114
135static void parseh_init_tld(Context *c, Tld *tld, TldId id, Buf *name) {115static AstNode *trans_create_node_symbol_str(Context *c, const char *name) {
136 init_tld(tld, id, name, c->visib_mod, c->source_node, &c->import->decls_scope->base);116 return trans_create_node_symbol(c, buf_create_from_str(name));
137 tld->resolution = TldResolutionOk;
138 tld->import = c->import;
139}117}
140118
141static Tld *create_inline_fn_tld(Context *c, Buf *fn_name, TldVar *tld_var) {119static AstNode *trans_create_node_builtin_fn_call(Context *c, Buf *name) {
142 TldFn *tld_fn = allocate<TldFn>(1);120 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
143 parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name);121 node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, name);
144 tld_fn->fn_entry = ir_create_inline_fn(c->codegen, fn_name, tld_var->var, &c->import->decls_scope->base);122 node->data.fn_call_expr.is_builtin = true;
145 return &tld_fn->base;123 return node;
146}124}
147125
148static TldVar *create_global_var(Context *c, Buf *name, ConstExprValue *var_value, bool is_const) {126static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *name) {
149 auto entry = c->import->decls_scope->decl_table.maybe_get(name);127 return trans_create_node_builtin_fn_call(c, buf_create_from_str(name));
150 if (entry) {
151 Tld *existing_tld = entry->value;
152 assert(existing_tld->id == TldIdVar);
153 return (TldVar *)existing_tld;
154 }
155 TldVar *tld_var = allocate<TldVar>(1);
156 parseh_init_tld(c, &tld_var->base, TldIdVar, name);
157 tld_var->var = add_variable(c->codegen, c->source_node, &c->import->decls_scope->base,
158 name, is_const, var_value, &tld_var->base);
159 c->codegen->global_vars.append(tld_var);
160 return tld_var;
161}128}
162129
163static Tld *create_global_str_lit_var(Context *c, Buf *name, Buf *value) {130static AstNode *trans_create_node_opaque(Context *c) {
164 TldVar *tld_var = create_global_var(c, name, create_const_c_str_lit(c->codegen, value), true);131 return trans_create_node_builtin_fn_call_str(c, "opaque");
165 return &tld_var->base;
166}132}
167133
168static Tld *create_global_num_lit_unsigned_negative_type(Context *c, Buf *name, uint64_t x, bool negative, TypeTableEntry *type_entry) {134static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) {
169 ConstExprValue *var_val = create_const_unsigned_negative(type_entry, x, negative);135 AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr);
170 TldVar *tld_var = create_global_var(c, name, var_val, true);136 node->data.field_access_expr.struct_expr = container;
171 return &tld_var->base;137 node->data.field_access_expr.field_name = field_name;
138 return node;
172}139}
173140
174static Tld *create_global_num_lit_unsigned_negative(Context *c, Buf *name, uint64_t x, bool negative) {141static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {
175 return create_global_num_lit_unsigned_negative_type(c, name, x, negative, c->codegen->builtin_types.entry_num_lit_int);142 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
143 node->data.prefix_op_expr.prefix_op = op;
144 node->data.prefix_op_expr.primary_expr = child_node;
145 return node;
176}146}
177147
178static Tld *create_global_num_lit_float(Context *c, Buf *name, double value) {148static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) {
179 ConstExprValue *var_val = create_const_float(c->codegen->builtin_types.entry_num_lit_float, value);149 AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr);
180 TldVar *tld_var = create_global_var(c, name, var_val, true);150 node->data.addr_of_expr.is_const = is_const;
181 return &tld_var->base;151 node->data.addr_of_expr.is_volatile = is_volatile;
152 node->data.addr_of_expr.op_expr = child_node;
153 return node;
182}154}
183155
184static ConstExprValue *create_const_int_ap(Context *c, TypeTableEntry *type, const Decl *source_decl,156static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) {
185 const llvm::APSInt &aps_int)157 AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
186{158 node->data.string_literal.buf = buf;
187 if (aps_int.isSigned()) {159 node->data.string_literal.c = true;
188 if (aps_int > INT64_MAX || aps_int < INT64_MIN) {160 return node;
189 emit_warning(c, source_decl->getLocation(), "integer overflow\n");
190 return nullptr;
191 } else {
192 return create_const_signed(type, aps_int.getExtValue());
193 }
194 } else {
195 if (aps_int > INT64_MAX) {
196 emit_warning(c, source_decl->getLocation(), "integer overflow\n");
197 return nullptr;
198 } else {
199 return create_const_unsigned_negative(type, aps_int.getExtValue(), false);
200 }
201 }
202}161}
203162
204static Tld *create_global_num_lit_ap(Context *c, const Decl *source_decl, Buf *name,163static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) {
205 const llvm::APSInt &aps_int)164 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
206{165 node->data.int_literal.bigint = allocate<BigInt>(1);
207 ConstExprValue *const_value = create_const_int_ap(c, c->codegen->builtin_types.entry_num_lit_int,166 bigint_init_data(node->data.int_literal.bigint, &x, 1, is_negative);
208 source_decl, aps_int);167 return node;
209 if (!const_value)
210 return nullptr;
211 TldVar *tld_var = create_global_var(c, name, const_value, true);
212 return &tld_var->base;
213}168}
214169
215170static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) {
216static Tld *add_const_type(Context *c, Buf *name, TypeTableEntry *type_entry) {171 return trans_create_node_unsigned_negative(c, x, false);
217 ConstExprValue *var_value = create_const_type(c->codegen, type_entry);
218 TldVar *tld_var = create_global_var(c, name, var_value, true);
219 add_global(c, &tld_var->base);
220
221 c->global_type_table.put(name, type_entry);
222 return &tld_var->base;
223}172}
224173
225static Tld *add_container_tld(Context *c, TypeTableEntry *type_entry) {174static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) {
226 return add_const_type(c, &type_entry->name, type_entry);175 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
176 node->data.fn_call_expr.fn_ref_expr = dest;
177 node->data.fn_call_expr.params.resize(1);
178 node->data.fn_call_expr.params.items[0] = src;
179 return node;
227}180}
228181
229static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) {182static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative,
230 return (type_entry == c->codegen->builtin_types.entry_c_void);183 const char *type_name)
184{
185 AstNode *lit_node = trans_create_node_unsigned_negative(c, x, is_negative);
186 return trans_create_node_cast(c, trans_create_node_symbol_str(c, type_name), lit_node);
231}187}
232188
233static bool qual_type_child_is_fn_proto(const QualType &qt) {189static AstNode *trans_create_node_array_type(Context *c, AstNode *size_node, AstNode *child_type_node) {
234 if (qt.getTypePtr()->getTypeClass() == Type::Paren) {190 AstNode *node = trans_create_node(c, NodeTypeArrayType);
235 const ParenType *paren_type = static_cast<const ParenType *>(qt.getTypePtr());191 node->data.array_type.size = size_node;
236 if (paren_type->getInnerType()->getTypeClass() == Type::FunctionProto) {192 node->data.array_type.child_type = child_type_node;
237 return true;193 return node;
238 }
239 } else if (qt.getTypePtr()->getTypeClass() == Type::Attributed) {
240 const AttributedType *attr_type = static_cast<const AttributedType *>(qt.getTypePtr());
241 return qual_type_child_is_fn_proto(attr_type->getEquivalentType());
242 }
243 return false;
244}194}
245195
246static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl,196static AstNode *trans_create_node_var_decl(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
247 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table)197 AstNode *init_node)
248{198{
249 switch (ty->getTypeClass()) {199 AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration);
250 case Type::Builtin:200 node->data.variable_declaration.visib_mod = c->visib_mod;
251 {201 node->data.variable_declaration.symbol = var_name;
252 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);202 node->data.variable_declaration.is_const = is_const;
253 switch (builtin_ty->getKind()) {203 node->data.variable_declaration.type = type_node;
254 case BuiltinType::Void:204 node->data.variable_declaration.expr = init_node;
255 return c->codegen->builtin_types.entry_c_void;205 return node;
256 case BuiltinType::Bool:206}
257 return c->codegen->builtin_types.entry_bool;
258 case BuiltinType::Char_U:
259 case BuiltinType::UChar:
260 case BuiltinType::Char_S:
261 return c->codegen->builtin_types.entry_u8;
262 case BuiltinType::SChar:
263 return c->codegen->builtin_types.entry_i8;
264 case BuiltinType::UShort:
265 return get_c_int_type(c->codegen, CIntTypeUShort);
266 case BuiltinType::UInt:
267 return get_c_int_type(c->codegen, CIntTypeUInt);
268 case BuiltinType::ULong:
269 return get_c_int_type(c->codegen, CIntTypeULong);
270 case BuiltinType::ULongLong:
271 return get_c_int_type(c->codegen, CIntTypeULongLong);
272 case BuiltinType::Short:
273 return get_c_int_type(c->codegen, CIntTypeShort);
274 case BuiltinType::Int:
275 return get_c_int_type(c->codegen, CIntTypeInt);
276 case BuiltinType::Long:
277 return get_c_int_type(c->codegen, CIntTypeLong);
278 case BuiltinType::LongLong:
279 return get_c_int_type(c->codegen, CIntTypeLongLong);
280 case BuiltinType::UInt128:
281 return c->codegen->builtin_types.entry_u128;
282 case BuiltinType::Int128:
283 return c->codegen->builtin_types.entry_i128;
284 case BuiltinType::Float:
285 return c->codegen->builtin_types.entry_f32;
286 case BuiltinType::Double:
287 return c->codegen->builtin_types.entry_f64;
288 case BuiltinType::Float128:
289 return c->codegen->builtin_types.entry_f128;
290 case BuiltinType::LongDouble:
291 return c->codegen->builtin_types.entry_c_longdouble;
292 case BuiltinType::WChar_U:
293 case BuiltinType::Char16:
294 case BuiltinType::Char32:
295 case BuiltinType::WChar_S:
296 case BuiltinType::Half:
297 case BuiltinType::NullPtr:
298 case BuiltinType::ObjCId:
299 case BuiltinType::ObjCClass:
300 case BuiltinType::ObjCSel:
301 case BuiltinType::OMPArraySection:
302 case BuiltinType::Dependent:
303 case BuiltinType::Overload:
304 case BuiltinType::BoundMember:
305 case BuiltinType::PseudoObject:
306 case BuiltinType::UnknownAny:
307 case BuiltinType::BuiltinFn:
308 case BuiltinType::ARCUnbridgedCast:
309207
310 case BuiltinType::OCLImage1dRO:
311 case BuiltinType::OCLImage1dArrayRO:
312 case BuiltinType::OCLImage1dBufferRO:
313 case BuiltinType::OCLImage2dRO:
314 case BuiltinType::OCLImage2dArrayRO:
315 case BuiltinType::OCLImage2dDepthRO:
316 case BuiltinType::OCLImage2dArrayDepthRO:
317 case BuiltinType::OCLImage2dMSAARO:
318 case BuiltinType::OCLImage2dArrayMSAARO:
319 case BuiltinType::OCLImage2dMSAADepthRO:
320 case BuiltinType::OCLImage2dArrayMSAADepthRO:
321 case BuiltinType::OCLImage3dRO:
322 case BuiltinType::OCLImage1dWO:
323 case BuiltinType::OCLImage1dArrayWO:
324 case BuiltinType::OCLImage1dBufferWO:
325 case BuiltinType::OCLImage2dWO:
326 case BuiltinType::OCLImage2dArrayWO:
327 case BuiltinType::OCLImage2dDepthWO:
328 case BuiltinType::OCLImage2dArrayDepthWO:
329 case BuiltinType::OCLImage2dMSAAWO:
330 case BuiltinType::OCLImage2dArrayMSAAWO:
331 case BuiltinType::OCLImage2dMSAADepthWO:
332 case BuiltinType::OCLImage2dArrayMSAADepthWO:
333 case BuiltinType::OCLImage3dWO:
334 case BuiltinType::OCLImage1dRW:
335 case BuiltinType::OCLImage1dArrayRW:
336 case BuiltinType::OCLImage1dBufferRW:
337 case BuiltinType::OCLImage2dRW:
338 case BuiltinType::OCLImage2dArrayRW:
339 case BuiltinType::OCLImage2dDepthRW:
340 case BuiltinType::OCLImage2dArrayDepthRW:
341 case BuiltinType::OCLImage2dMSAARW:
342 case BuiltinType::OCLImage2dArrayMSAARW:
343 case BuiltinType::OCLImage2dMSAADepthRW:
344 case BuiltinType::OCLImage2dArrayMSAADepthRW:
345 case BuiltinType::OCLImage3dRW:
346 case BuiltinType::OCLSampler:
347 case BuiltinType::OCLEvent:
348 case BuiltinType::OCLClkEvent:
349 case BuiltinType::OCLQueue:
350 case BuiltinType::OCLReserveID:
351 emit_warning(c, decl->getLocation(), "missed a builtin type");
352 return c->codegen->builtin_types.entry_invalid;
353 }
354 break;
355 }
356 case Type::Pointer:
357 {
358 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
359 QualType child_qt = pointer_ty->getPointeeType();
360 TypeTableEntry *child_type = resolve_qual_type(c, child_qt, decl);
361 if (type_is_invalid(child_type)) {
362 emit_warning(c, decl->getLocation(), "pointer to unresolved type");
363 return c->codegen->builtin_types.entry_invalid;
364 }
365208
366 if (qual_type_child_is_fn_proto(child_qt)) {209static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_name, AstNode *src_proto_node) {
367 return get_maybe_type(c->codegen, child_type);210 AstNode *fn_def = trans_create_node(c, NodeTypeFnDef);
368 }211 AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto);
369 bool is_const = child_qt.isConstQualified();212 fn_proto->data.fn_proto.visib_mod = c->visib_mod;;
213 fn_proto->data.fn_proto.name = fn_name;
214 fn_proto->data.fn_proto.is_inline = true;
215 fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias?
370216
371 TypeTableEntry *non_null_pointer_type = get_pointer_to_type(c->codegen, child_type, is_const);217 fn_def->data.fn_def.fn_proto = fn_proto;
372 return get_maybe_type(c->codegen, non_null_pointer_type);218 fn_proto->data.fn_proto.fn_def_node = fn_def;
373 }
374 case Type::Typedef:
375 {
376 const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty);
377 const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
378 Buf *type_name = buf_create_from_str(decl_name(typedef_decl));
379 if (buf_eql_str(type_name, "uint8_t")) {
380 return c->codegen->builtin_types.entry_u8;
381 } else if (buf_eql_str(type_name, "int8_t")) {
382 return c->codegen->builtin_types.entry_i8;
383 } else if (buf_eql_str(type_name, "uint16_t")) {
384 return c->codegen->builtin_types.entry_u16;
385 } else if (buf_eql_str(type_name, "int16_t")) {
386 return c->codegen->builtin_types.entry_i16;
387 } else if (buf_eql_str(type_name, "uint32_t")) {
388 return c->codegen->builtin_types.entry_u32;
389 } else if (buf_eql_str(type_name, "int32_t")) {
390 return c->codegen->builtin_types.entry_i32;
391 } else if (buf_eql_str(type_name, "uint64_t")) {
392 return c->codegen->builtin_types.entry_u64;
393 } else if (buf_eql_str(type_name, "int64_t")) {
394 return c->codegen->builtin_types.entry_i64;
395 } else if (buf_eql_str(type_name, "intptr_t")) {
396 return c->codegen->builtin_types.entry_isize;
397 } else if (buf_eql_str(type_name, "uintptr_t")) {
398 return c->codegen->builtin_types.entry_usize;
399 } else {
400 auto entry = type_table->maybe_get(type_name);
401 if (entry) {
402 if (type_is_invalid(entry->value)) {
403 return c->codegen->builtin_types.entry_invalid;
404 } else {
405 return entry->value;
406 }
407 } else {
408 return c->codegen->builtin_types.entry_invalid;
409 }
410 }
411 }
412 case Type::Elaborated:
413 {
414 const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty);
415 switch (elaborated_ty->getKeyword()) {
416 case ETK_Struct:
417 return resolve_qual_type_with_table(c, elaborated_ty->getNamedType(),
418 decl, &c->struct_type_table);
419 case ETK_Enum:
420 return resolve_qual_type_with_table(c, elaborated_ty->getNamedType(),
421 decl, &c->enum_type_table);
422 case ETK_Interface:
423 case ETK_Union:
424 case ETK_Class:
425 case ETK_Typename:
426 case ETK_None:
427 emit_warning(c, decl->getLocation(), "unsupported elaborated type");
428 return c->codegen->builtin_types.entry_invalid;
429 }
430 }
431 case Type::FunctionProto:
432 {
433 const FunctionProtoType *fn_proto_ty = static_cast<const FunctionProtoType*>(ty);
434219
435 switch (fn_proto_ty->getCallConv()) {220 AstNode *unwrap_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, trans_create_node_symbol(c, var_name));
436 case CC_C: // __attribute__((cdecl))221 AstNode *fn_call_node = trans_create_node(c, NodeTypeFnCallExpr);
437 break;222 fn_call_node->data.fn_call_expr.fn_ref_expr = unwrap_node;
438 case CC_X86StdCall: // __attribute__((stdcall))
439 emit_warning(c, decl->getLocation(), "function type has x86 stdcall calling convention");
440 return c->codegen->builtin_types.entry_invalid;
441 case CC_X86FastCall: // __attribute__((fastcall))
442 emit_warning(c, decl->getLocation(), "function type has x86 fastcall calling convention");
443 return c->codegen->builtin_types.entry_invalid;
444 case CC_X86ThisCall: // __attribute__((thiscall))
445 emit_warning(c, decl->getLocation(), "function type has x86 thiscall calling convention");
446 return c->codegen->builtin_types.entry_invalid;
447 case CC_X86VectorCall: // __attribute__((vectorcall))
448 emit_warning(c, decl->getLocation(), "function type has x86 vectorcall calling convention");
449 return c->codegen->builtin_types.entry_invalid;
450 case CC_X86Pascal: // __attribute__((pascal))
451 emit_warning(c, decl->getLocation(), "function type has x86 pascal calling convention");
452 return c->codegen->builtin_types.entry_invalid;
453 case CC_Win64: // __attribute__((ms_abi))
454 emit_warning(c, decl->getLocation(), "function type has win64 calling convention");
455 return c->codegen->builtin_types.entry_invalid;
456 case CC_X86_64SysV: // __attribute__((sysv_abi))
457 emit_warning(c, decl->getLocation(), "function type has x86 64sysv calling convention");
458 return c->codegen->builtin_types.entry_invalid;
459 case CC_X86RegCall:
460 emit_warning(c, decl->getLocation(), "function type has x86 reg calling convention");
461 return c->codegen->builtin_types.entry_invalid;
462 case CC_AAPCS: // __attribute__((pcs("aapcs")))
463 emit_warning(c, decl->getLocation(), "function type has aapcs calling convention");
464 return c->codegen->builtin_types.entry_invalid;
465 case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
466 emit_warning(c, decl->getLocation(), "function type has aapcs-vfp calling convention");
467 return c->codegen->builtin_types.entry_invalid;
468 case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc))
469 emit_warning(c, decl->getLocation(), "function type has intel_ocl_bicc calling convention");
470 return c->codegen->builtin_types.entry_invalid;
471 case CC_SpirFunction: // default for OpenCL functions on SPIR target
472 emit_warning(c, decl->getLocation(), "function type has SPIR function calling convention");
473 return c->codegen->builtin_types.entry_invalid;
474 case CC_OpenCLKernel:
475 emit_warning(c, decl->getLocation(), "function type has OpenCLKernel calling convention");
476 return c->codegen->builtin_types.entry_invalid;
477 case CC_Swift:
478 emit_warning(c, decl->getLocation(), "function type has Swift calling convention");
479 return c->codegen->builtin_types.entry_invalid;
480 case CC_PreserveMost:
481 emit_warning(c, decl->getLocation(), "function type has PreserveMost calling convention");
482 return c->codegen->builtin_types.entry_invalid;
483 case CC_PreserveAll:
484 emit_warning(c, decl->getLocation(), "function type has PreserveAll calling convention");
485 return c->codegen->builtin_types.entry_invalid;
486 }
487223
488 FnTypeId fn_type_id = {0};224 for (size_t i = 0; i < src_proto_node->data.fn_proto.params.length; i += 1) {
489 fn_type_id.cc = CallingConventionC;225 AstNode *src_param_node = src_proto_node->data.fn_proto.params.at(i);
490 fn_type_id.is_var_args = fn_proto_ty->isVariadic();226 Buf *param_name = src_param_node->data.param_decl.name;
491 fn_type_id.param_count = fn_proto_ty->getNumParams();
492227
228 AstNode *dest_param_node = trans_create_node(c, NodeTypeParamDecl);
229 dest_param_node->data.param_decl.name = param_name;
230 dest_param_node->data.param_decl.type = src_param_node->data.param_decl.type;
231 dest_param_node->data.param_decl.is_noalias = src_param_node->data.param_decl.is_noalias;
232 fn_proto->data.fn_proto.params.append(dest_param_node);
493233
494 if (fn_proto_ty->getNoReturnAttr()) {234 fn_call_node->data.fn_call_expr.params.append(trans_create_node_symbol(c, param_name));
495 fn_type_id.return_type = c->codegen->builtin_types.entry_unreachable;
496 } else {
497 fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl);
498 if (type_is_invalid(fn_type_id.return_type)) {
499 emit_warning(c, decl->getLocation(), "unresolved function proto return type");
500 return c->codegen->builtin_types.entry_invalid;
501 }
502 // convert c_void to actual void (only for return type)
503 if (is_c_void_type(c, fn_type_id.return_type)) {
504 fn_type_id.return_type = c->codegen->builtin_types.entry_void;
505 }
506 }
507235
508 fn_type_id.param_info = allocate_nonzero<FnTypeParamInfo>(fn_type_id.param_count);236 }
509 for (size_t i = 0; i < fn_type_id.param_count; i += 1) {
510 QualType qt = fn_proto_ty->getParamType(i);
511 TypeTableEntry *param_type = resolve_qual_type(c, qt, decl);
512237
513 if (type_is_invalid(param_type)) {238 AstNode *block = trans_create_node(c, NodeTypeBlock);
514 emit_warning(c, decl->getLocation(), "unresolved function proto parameter type");239 block->data.block.statements.resize(1);
515 return c->codegen->builtin_types.entry_invalid;240 block->data.block.statements.items[0] = fn_call_node;
516 }
517241
518 FnTypeParamInfo *param_info = &fn_type_id.param_info[i];242 fn_def->data.fn_def.body = block;
519 param_info->type = param_type;243 return fn_def;
520 param_info->is_noalias = qt.isRestrictQualified();244}
521 }
522245
523 return get_fn_type(c->codegen, &fn_type_id);246static AstNode *get_global(Context *c, Buf *name) {
524 }247 for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) {
525 case Type::Record:248 AstNode *decl_node = c->root->data.root.top_level_decls.items[i];
526 {249 if (decl_node->type == NodeTypeVariableDeclaration) {
527 const RecordType *record_ty = static_cast<const RecordType*>(ty);250 if (buf_eql_buf(decl_node->data.variable_declaration.symbol, name)) {
528 return resolve_record_decl(c, record_ty->getDecl());251 return decl_node;
529 }
530 case Type::Enum:
531 {
532 const EnumType *enum_ty = static_cast<const EnumType*>(ty);
533 return resolve_enum_decl(c, enum_ty->getDecl());
534 }252 }
535 case Type::ConstantArray:253 } else if (decl_node->type == NodeTypeFnDef) {
536 {254 if (buf_eql_buf(decl_node->data.fn_def.fn_proto->data.fn_proto.name, name)) {
537 const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty);255 return decl_node;
538 TypeTableEntry *child_type = resolve_qual_type(c, const_arr_ty->getElementType(), decl);
539 if (child_type->id == TypeTableEntryIdInvalid) {
540 emit_warning(c, decl->getLocation(), "unresolved array element type");
541 return child_type;
542 }
543 uint64_t size = const_arr_ty->getSize().getLimitedValue();
544 return get_array_type(c->codegen, child_type, size);
545 }256 }
546 case Type::Paren:257 } else if (decl_node->type == NodeTypeFnProto) {
547 {258 if (buf_eql_buf(decl_node->data.fn_proto.name, name)) {
548 const ParenType *paren_ty = static_cast<const ParenType *>(ty);259 return decl_node;
549 return resolve_qual_type(c, paren_ty->getInnerType(), decl);
550 }260 }
551 case Type::Decayed:261 }
552 {
553 const DecayedType *decayed_ty = static_cast<const DecayedType *>(ty);
554 return resolve_qual_type(c, decayed_ty->getDecayedType(), decl);
555 }
556 case Type::Attributed:
557 {
558 const AttributedType *attributed_ty = static_cast<const AttributedType *>(ty);
559 return resolve_qual_type(c, attributed_ty->getEquivalentType(), decl);
560 }
561 case Type::BlockPointer:
562 case Type::LValueReference:
563 case Type::RValueReference:
564 case Type::MemberPointer:
565 case Type::IncompleteArray:
566 case Type::VariableArray:
567 case Type::DependentSizedArray:
568 case Type::DependentSizedExtVector:
569 case Type::Vector:
570 case Type::ExtVector:
571 case Type::FunctionNoProto:
572 case Type::UnresolvedUsing:
573 case Type::Adjusted:
574 case Type::TypeOfExpr:
575 case Type::TypeOf:
576 case Type::Decltype:
577 case Type::UnaryTransform:
578 case Type::TemplateTypeParm:
579 case Type::SubstTemplateTypeParm:
580 case Type::SubstTemplateTypeParmPack:
581 case Type::TemplateSpecialization:
582 case Type::Auto:
583 case Type::InjectedClassName:
584 case Type::DependentName:
585 case Type::DependentTemplateSpecialization:
586 case Type::PackExpansion:
587 case Type::ObjCObject:
588 case Type::ObjCInterface:
589 case Type::Complex:
590 case Type::ObjCObjectPointer:
591 case Type::Atomic:
592 case Type::Pipe:
593 case Type::ObjCTypeParam:
594 case Type::DeducedTemplateSpecialization:
595 emit_warning(c, decl->getLocation(), "missed a '%s' type", ty->getTypeClassName());
596 return c->codegen->builtin_types.entry_invalid;
597 }262 }
598 zig_unreachable();263 {
264 auto entry = c->macro_table.maybe_get(name);
265 if (entry)
266 return entry->value;
267 }
268 return nullptr;
269}
270
271static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) {
272 bool is_const = true;
273 AstNode *type_node = nullptr;
274 AstNode *node = trans_create_node_var_decl(c, is_const, var_name, type_node, value_node);
275 c->root->data.root.top_level_decls.append(node);
276 return node;
277}
278
279static const char *decl_name(const Decl *decl) {
280 const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);
281 return (const char *)named_decl->getName().bytes_begin();
599}282}
600283
601static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl,284static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) {
602 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table)285 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
603{286 node->data.int_literal.bigint = allocate<BigInt>(1);
604 return resolve_type_with_table(c, qt.getTypePtr(), decl, type_table);287 bigint_init_data(node->data.int_literal.bigint, aps_int.getRawData(), aps_int.getNumWords(), aps_int.isNegative());
288 return node;
289
605}290}
606291
607static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl) {292static bool is_c_void_type(AstNode *node) {
608 return resolve_qual_type_with_table(c, qt, decl, &c->global_type_table);293 return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
609}294}
610295
611#include "ast_render.hpp"296static bool qual_type_child_is_fn_proto(const QualType &qt) {
297 if (qt.getTypePtr()->getTypeClass() == Type::Paren) {
298 const ParenType *paren_type = static_cast<const ParenType *>(qt.getTypePtr());
299 if (paren_type->getInnerType()->getTypeClass() == Type::FunctionProto) {
300 return true;
301 }
302 } else if (qt.getTypePtr()->getTypeClass() == Type::Attributed) {
303 const AttributedType *attr_type = static_cast<const AttributedType *>(qt.getTypePtr());
304 return qual_type_child_is_fn_proto(attr_type->getEquivalentType());
305 }
306 return false;
307}
612308
613static bool c_is_signed_integer(Context *c, QualType qt) {309static bool c_is_signed_integer(Context *c, QualType qt) {
614 const Type *c_type = qt.getTypePtr();310 const Type *c_type = qt.getTypePtr();
...@@ -668,19 +364,12 @@ static bool c_is_float(Context *c, QualType qt) {...@@ -668,19 +364,12 @@ static bool c_is_float(Context *c, QualType qt) {
668}364}
669365
670static AstNode * trans_stmt(Context *c, AstNode *block, Stmt *stmt);366static AstNode * trans_stmt(Context *c, AstNode *block, Stmt *stmt);
671static AstNode * trans_create_node(Context *c, NodeType id);
672static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);367static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
673368
674static AstNode * trans_expr(Context *c, AstNode *block, Expr *expr) {369static AstNode * trans_expr(Context *c, AstNode *block, Expr *expr) {
675 return trans_stmt(c, block, expr);370 return trans_stmt(c, block, expr);
676}371}
677372
678static AstNode *trans_create_symbol_node(Context *c, const char * name) {
679 AstNode *node = trans_create_node(c, NodeTypeSymbol);
680 node->data.symbol_expr.symbol = buf_create_from_str(name);
681 return node;
682}
683
684static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLocation &source_loc,373static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLocation &source_loc,
685 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> *type_table)374 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> *type_table)
686{375{
...@@ -690,43 +379,43 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo...@@ -690,43 +379,43 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo
690 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);379 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
691 switch (builtin_ty->getKind()) {380 switch (builtin_ty->getKind()) {
692 case BuiltinType::Void:381 case BuiltinType::Void:
693 return trans_create_symbol_node(c, "c_void");382 return trans_create_node_symbol_str(c, "c_void");
694 case BuiltinType::Bool:383 case BuiltinType::Bool:
695 return trans_create_symbol_node(c, "bool");384 return trans_create_node_symbol_str(c, "bool");
696 case BuiltinType::Char_U:385 case BuiltinType::Char_U:
697 case BuiltinType::UChar:386 case BuiltinType::UChar:
698 case BuiltinType::Char_S:387 case BuiltinType::Char_S:
699 return trans_create_symbol_node(c, "u8");388 return trans_create_node_symbol_str(c, "u8");
700 case BuiltinType::SChar:389 case BuiltinType::SChar:
701 return trans_create_symbol_node(c, "i8");390 return trans_create_node_symbol_str(c, "i8");
702 case BuiltinType::UShort:391 case BuiltinType::UShort:
703 return trans_create_symbol_node(c, "c_ushort");392 return trans_create_node_symbol_str(c, "c_ushort");
704 case BuiltinType::UInt:393 case BuiltinType::UInt:
705 return trans_create_symbol_node(c, "c_uint");394 return trans_create_node_symbol_str(c, "c_uint");
706 case BuiltinType::ULong:395 case BuiltinType::ULong:
707 return trans_create_symbol_node(c, "c_ulong");396 return trans_create_node_symbol_str(c, "c_ulong");
708 case BuiltinType::ULongLong:397 case BuiltinType::ULongLong:
709 return trans_create_symbol_node(c, "c_ulonglong");398 return trans_create_node_symbol_str(c, "c_ulonglong");
710 case BuiltinType::Short:399 case BuiltinType::Short:
711 return trans_create_symbol_node(c, "c_short");400 return trans_create_node_symbol_str(c, "c_short");
712 case BuiltinType::Int:401 case BuiltinType::Int:
713 return trans_create_symbol_node(c, "c_int");402 return trans_create_node_symbol_str(c, "c_int");
714 case BuiltinType::Long:403 case BuiltinType::Long:
715 return trans_create_symbol_node(c, "c_long");404 return trans_create_node_symbol_str(c, "c_long");
716 case BuiltinType::LongLong:405 case BuiltinType::LongLong:
717 return trans_create_symbol_node(c, "c_longlong");406 return trans_create_node_symbol_str(c, "c_longlong");
718 case BuiltinType::UInt128:407 case BuiltinType::UInt128:
719 return trans_create_symbol_node(c, "u128");408 return trans_create_node_symbol_str(c, "u128");
720 case BuiltinType::Int128:409 case BuiltinType::Int128:
721 return trans_create_symbol_node(c, "i128");410 return trans_create_node_symbol_str(c, "i128");
722 case BuiltinType::Float:411 case BuiltinType::Float:
723 return trans_create_symbol_node(c, "f32");412 return trans_create_node_symbol_str(c, "f32");
724 case BuiltinType::Double:413 case BuiltinType::Double:
725 return trans_create_symbol_node(c, "f64");414 return trans_create_node_symbol_str(c, "f64");
726 case BuiltinType::Float128:415 case BuiltinType::Float128:
727 return trans_create_symbol_node(c, "f128");416 return trans_create_node_symbol_str(c, "f128");
728 case BuiltinType::LongDouble:417 case BuiltinType::LongDouble:
729 return trans_create_symbol_node(c, "c_longdouble");418 return trans_create_node_symbol_str(c, "c_longdouble");
730 case BuiltinType::WChar_U:419 case BuiltinType::WChar_U:
731 case BuiltinType::Char16:420 case BuiltinType::Char16:
732 case BuiltinType::Char32:421 case BuiltinType::Char32:
...@@ -786,7 +475,8 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo...@@ -786,7 +475,8 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo
786 case BuiltinType::OCLClkEvent:475 case BuiltinType::OCLClkEvent:
787 case BuiltinType::OCLQueue:476 case BuiltinType::OCLQueue:
788 case BuiltinType::OCLReserveID:477 case BuiltinType::OCLReserveID:
789 zig_panic("TODO more c type");478 emit_warning(c, source_loc, "unsupported builtin type");
479 return nullptr;
790 }480 }
791 break;481 break;
792 }482 }
...@@ -795,40 +485,218 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo...@@ -795,40 +485,218 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo
795 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);485 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
796 QualType child_qt = pointer_ty->getPointeeType();486 QualType child_qt = pointer_ty->getPointeeType();
797 AstNode *child_node = trans_qual_type(c, child_qt, source_loc);487 AstNode *child_node = trans_qual_type(c, child_qt, source_loc);
798 if (child_node == nullptr) return nullptr;488 if (child_node == nullptr) {
489 emit_warning(c, source_loc, "pointer to unsupported type");
490 return nullptr;
491 }
799492
800 if (qual_type_child_is_fn_proto(child_qt)) {493 if (qual_type_child_is_fn_proto(child_qt)) {
801 zig_panic("TODO pointer to function proto");494 return trans_create_node_prefix_op(c, PrefixOpMaybe, child_node);
802 }495 }
803496
804 AstNode *pointer_node = trans_create_node(c, NodeTypeAddrOfExpr);497 AstNode *pointer_node = trans_create_node_addr_of(c, child_qt.isConstQualified(),
805 pointer_node->data.addr_of_expr.is_const = child_qt.isConstQualified();498 child_qt.isVolatileQualified(), child_node);
806 pointer_node->data.addr_of_expr.is_volatile = child_qt.isVolatileQualified();499 return trans_create_node_prefix_op(c, PrefixOpMaybe, pointer_node);
807 pointer_node->data.addr_of_expr.op_expr = child_node;
808
809 AstNode *maybe_node = trans_create_node(c, NodeTypePrefixOpExpr);
810 maybe_node->data.prefix_op_expr.prefix_op = PrefixOpMaybe;
811 maybe_node->data.prefix_op_expr.primary_expr = pointer_node;
812 return maybe_node;
813 }500 }
814 case Type::Typedef:501 case Type::Typedef:
815 zig_panic("TODO typedef");502 {
503 const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty);
504 const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
505 Buf *type_name = buf_create_from_str(decl_name(typedef_decl));
506 if (buf_eql_str(type_name, "uint8_t")) {
507 return trans_create_node_symbol_str(c, "u8");
508 } else if (buf_eql_str(type_name, "int8_t")) {
509 return trans_create_node_symbol_str(c, "i8");
510 } else if (buf_eql_str(type_name, "uint16_t")) {
511 return trans_create_node_symbol_str(c, "u16");
512 } else if (buf_eql_str(type_name, "int16_t")) {
513 return trans_create_node_symbol_str(c, "i16");
514 } else if (buf_eql_str(type_name, "uint32_t")) {
515 return trans_create_node_symbol_str(c, "u32");
516 } else if (buf_eql_str(type_name, "int32_t")) {
517 return trans_create_node_symbol_str(c, "i32");
518 } else if (buf_eql_str(type_name, "uint64_t")) {
519 return trans_create_node_symbol_str(c, "u64");
520 } else if (buf_eql_str(type_name, "int64_t")) {
521 return trans_create_node_symbol_str(c, "i64");
522 } else if (buf_eql_str(type_name, "intptr_t")) {
523 return trans_create_node_symbol_str(c, "isize");
524 } else if (buf_eql_str(type_name, "uintptr_t")) {
525 return trans_create_node_symbol_str(c, "usize");
526 } else {
527 auto entry = type_table->maybe_get(type_name);
528 if (entry == nullptr || entry->value == nullptr) {
529 return nullptr;
530 } else {
531 return entry->value;
532 }
533 }
534 }
816 case Type::Elaborated:535 case Type::Elaborated:
817 zig_panic("TODO elaborated");536 {
537 const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty);
538 switch (elaborated_ty->getKeyword()) {
539 case ETK_Struct:
540 return trans_qual_type_with_table(c, elaborated_ty->getNamedType(),
541 source_loc, &c->struct_type_table);
542 case ETK_Enum:
543 return trans_qual_type_with_table(c, elaborated_ty->getNamedType(),
544 source_loc, &c->enum_type_table);
545 case ETK_Interface:
546 case ETK_Union:
547 case ETK_Class:
548 case ETK_Typename:
549 case ETK_None:
550 emit_warning(c, source_loc, "unsupported elaborated type");
551 return nullptr;
552 }
553 }
818 case Type::FunctionProto:554 case Type::FunctionProto:
819 zig_panic("TODO FunctionProto");555 {
556 const FunctionProtoType *fn_proto_ty = static_cast<const FunctionProtoType*>(ty);
557
558 AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
559 switch (fn_proto_ty->getCallConv()) {
560 case CC_C: // __attribute__((cdecl))
561 proto_node->data.fn_proto.cc = CallingConventionC;
562 break;
563 case CC_X86StdCall: // __attribute__((stdcall))
564 proto_node->data.fn_proto.cc = CallingConventionStdcall;
565 break;
566 case CC_X86FastCall: // __attribute__((fastcall))
567 emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall");
568 return nullptr;
569 case CC_X86ThisCall: // __attribute__((thiscall))
570 emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall");
571 return nullptr;
572 case CC_X86VectorCall: // __attribute__((vectorcall))
573 emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall");
574 return nullptr;
575 case CC_X86Pascal: // __attribute__((pascal))
576 emit_warning(c, source_loc, "unsupported calling convention: x86 pascal");
577 return nullptr;
578 case CC_Win64: // __attribute__((ms_abi))
579 emit_warning(c, source_loc, "unsupported calling convention: win64");
580 return nullptr;
581 case CC_X86_64SysV: // __attribute__((sysv_abi))
582 emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv");
583 return nullptr;
584 case CC_X86RegCall:
585 emit_warning(c, source_loc, "unsupported calling convention: x86 reg");
586 return nullptr;
587 case CC_AAPCS: // __attribute__((pcs("aapcs")))
588 emit_warning(c, source_loc, "unsupported calling convention: aapcs");
589 return nullptr;
590 case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
591 emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp");
592 return nullptr;
593 case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc))
594 emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc");
595 return nullptr;
596 case CC_SpirFunction: // default for OpenCL functions on SPIR target
597 emit_warning(c, source_loc, "unsupported calling convention: SPIR function");
598 return nullptr;
599 case CC_OpenCLKernel:
600 emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel");
601 return nullptr;
602 case CC_Swift:
603 emit_warning(c, source_loc, "unsupported calling convention: Swift");
604 return nullptr;
605 case CC_PreserveMost:
606 emit_warning(c, source_loc, "unsupported calling convention: PreserveMost");
607 return nullptr;
608 case CC_PreserveAll:
609 emit_warning(c, source_loc, "unsupported calling convention: PreserveAll");
610 return nullptr;
611 }
612
613 proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic();
614 size_t param_count = fn_proto_ty->getNumParams();
615
616 if (fn_proto_ty->getNoReturnAttr()) {
617 proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn");
618 } else {
619 proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_proto_ty->getReturnType(),
620 source_loc);
621 if (proto_node->data.fn_proto.return_type == nullptr) {
622 emit_warning(c, source_loc, "unsupported function proto return type");
623 return nullptr;
624 }
625 // convert c_void to actual void (only for return type)
626 if (is_c_void_type(proto_node->data.fn_proto.return_type)) {
627 proto_node->data.fn_proto.return_type = nullptr;
628 }
629 }
630
631 //emit_warning(c, source_loc, "TODO figure out fn prototype fn name");
632 const char *fn_name = nullptr;
633 if (fn_name != nullptr) {
634 proto_node->data.fn_proto.name = buf_create_from_str(fn_name);
635 }
636
637 for (size_t i = 0; i < param_count; i += 1) {
638 QualType qt = fn_proto_ty->getParamType(i);
639 AstNode *param_type_node = trans_qual_type(c, qt, source_loc);
640
641 if (param_type_node == nullptr) {
642 emit_warning(c, source_loc, "unresolved function proto parameter type");
643 return nullptr;
644 }
645
646 AstNode *param_node = trans_create_node(c, NodeTypeParamDecl);
647 //emit_warning(c, source_loc, "TODO figure out fn prototype param name");
648 const char *param_name = nullptr;
649 if (param_name == nullptr) {
650 param_node->data.param_decl.name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
651 } else {
652 param_node->data.param_decl.name = buf_create_from_str(param_name);
653 }
654 param_node->data.param_decl.is_noalias = qt.isRestrictQualified();
655 param_node->data.param_decl.type = param_type_node;
656 proto_node->data.fn_proto.params.append(param_node);
657 }
658 // TODO check for always_inline attribute
659 // TODO check for align attribute
660
661 return proto_node;
662 }
820 case Type::Record:663 case Type::Record:
821 zig_panic("TODO Record");664 {
665 const RecordType *record_ty = static_cast<const RecordType*>(ty);
666 return resolve_record_decl(c, record_ty->getDecl());
667 }
822 case Type::Enum:668 case Type::Enum:
823 zig_panic("TODO Enum");669 {
670 const EnumType *enum_ty = static_cast<const EnumType*>(ty);
671 return resolve_enum_decl(c, enum_ty->getDecl());
672 }
824 case Type::ConstantArray:673 case Type::ConstantArray:
825 zig_panic("TODO ConstantArray");674 {
675 const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty);
676 AstNode *child_type_node = trans_qual_type(c, const_arr_ty->getElementType(), source_loc);
677 if (child_type_node == nullptr) {
678 emit_warning(c, source_loc, "unresolved array element type");
679 return nullptr;
680 }
681 uint64_t size = const_arr_ty->getSize().getLimitedValue();
682 AstNode *size_node = trans_create_node_unsigned(c, size);
683 return trans_create_node_array_type(c, size_node, child_type_node);
684 }
826 case Type::Paren:685 case Type::Paren:
827 zig_panic("TODO Paren");686 {
687 const ParenType *paren_ty = static_cast<const ParenType *>(ty);
688 return trans_qual_type(c, paren_ty->getInnerType(), source_loc);
689 }
828 case Type::Decayed:690 case Type::Decayed:
829 zig_panic("TODO Decayed");691 {
692 const DecayedType *decayed_ty = static_cast<const DecayedType *>(ty);
693 return trans_qual_type(c, decayed_ty->getDecayedType(), source_loc);
694 }
830 case Type::Attributed:695 case Type::Attributed:
831 zig_panic("TODO Attributed");696 {
697 const AttributedType *attributed_ty = static_cast<const AttributedType *>(ty);
698 return trans_qual_type(c, attributed_ty->getEquivalentType(), source_loc);
699 }
832 case Type::BlockPointer:700 case Type::BlockPointer:
833 case Type::LValueReference:701 case Type::LValueReference:
834 case Type::RValueReference:702 case Type::RValueReference:
...@@ -863,7 +731,8 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo...@@ -863,7 +731,8 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo
863 case Type::Pipe:731 case Type::Pipe:
864 case Type::ObjCTypeParam:732 case Type::ObjCTypeParam:
865 case Type::DeducedTemplateSpecialization:733 case Type::DeducedTemplateSpecialization:
866 zig_panic("TODO more c type aoeu");734 emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName());
735 return nullptr;
867 }736 }
868 zig_unreachable();737 zig_unreachable();
869}738}
...@@ -875,15 +744,7 @@ static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const Sourc...@@ -875,15 +744,7 @@ static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const Sourc
875}744}
876745
877static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc) {746static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc) {
878 return trans_qual_type_with_table(c, qt, source_loc, &c->global_type_table2);747 return trans_qual_type_with_table(c, qt, source_loc, &c->global_type_table);
879}
880
881static AstNode * trans_create_node(Context *c, NodeType id) {
882 AstNode *node = allocate<AstNode>(1);
883 node->type = id;
884 node->owner = c->import;
885 // TODO line/column. mapping to C file??
886 return node;
887}748}
888749
889static AstNode * trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) {750static AstNode * trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) {
...@@ -907,35 +768,15 @@ static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt)...@@ -907,35 +768,15 @@ static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt)
907 }768 }
908}769}
909770
910static void aps_int_to_bigint(Context *c, const llvm::APSInt &aps_int, BigInt *bigint) {771static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) {
911 // TODO respect actually big integers
912 if (aps_int.isSigned()) {
913 if (aps_int > INT64_MAX || aps_int < INT64_MIN) {
914 zig_panic("TODO actually bigint in C");
915 } else {
916 bigint_init_signed(bigint, aps_int.getExtValue());
917 }
918 } else {
919 if (aps_int > INT64_MAX) {
920 zig_panic("TODO actually bigint in C");
921 } else {
922 bigint_init_unsigned(bigint, aps_int.getExtValue());
923 }
924 }
925}
926
927static AstNode * trans_integer_literal(Context *c, IntegerLiteral *stmt) {
928 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
929 llvm::APSInt result;772 llvm::APSInt result;
930 if (!stmt->EvaluateAsInt(result, *c->ctx)) {773 if (!stmt->EvaluateAsInt(result, *c->ctx)) {
931 fprintf(stderr, "TODO unable to convert integer literal to zig\n");774 zig_panic("TODO handle libclang unable to evaluate C integer literal");
932 }775 }
933 node->data.int_literal.bigint = allocate<BigInt>(1);776 return trans_create_node_apint(c, result);
934 aps_int_to_bigint(c, result, node->data.int_literal.bigint);
935 return node;
936}777}
937778
938static AstNode * trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) {779static AstNode *trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) {
939 AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);780 AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
940781
941 Expr *cond_expr = stmt->getCond();782 Expr *cond_expr = stmt->getCond();
...@@ -1034,9 +875,7 @@ static AstNode * trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCa...@@ -1034,9 +875,7 @@ static AstNode * trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCa
1034 return trans_expr(c, block, stmt->getSubExpr());875 return trans_expr(c, block, stmt->getSubExpr());
1035 case CK_IntegralCast:876 case CK_IntegralCast:
1036 {877 {
1037 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);878 AstNode *node = trans_create_node_builtin_fn_call_str(c, "bitCast");
1038 node->data.fn_call_expr.fn_ref_expr = trans_create_symbol_node(c, "bitCast");
1039 node->data.fn_call_expr.is_builtin = true;
1040 node->data.fn_call_expr.params.append(trans_qual_type(c, stmt->getType(), stmt->getExprLoc()));879 node->data.fn_call_expr.params.append(trans_qual_type(c, stmt->getType(), stmt->getExprLoc()));
1041 node->data.fn_call_expr.params.append(trans_expr(c, block, stmt->getSubExpr()));880 node->data.fn_call_expr.params.append(trans_expr(c, block, stmt->getSubExpr()));
1042 return node;881 return node;
...@@ -1166,13 +1005,6 @@ static AstNode * trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) {...@@ -1166,13 +1005,6 @@ static AstNode * trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) {
1166 return node;1005 return node;
1167}1006}
11681007
1169static AstNode * trans_create_num_lit_node_unsigned(Context *c, Stmt *stmt, uint64_t x) {
1170 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
1171 node->data.int_literal.bigint = allocate<BigInt>(1);
1172 bigint_init_unsigned(node->data.int_literal.bigint, x);
1173 return node;
1174}
1175
1176static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) {1008static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) {
1177 switch (stmt->getOpcode()) {1009 switch (stmt->getOpcode()) {
1178 case UO_PostInc:1010 case UO_PostInc:
...@@ -1200,7 +1032,7 @@ static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator...@@ -1200,7 +1032,7 @@ static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator
1200 } else if (c_is_unsigned_integer(c, op_expr->getType())) {1032 } else if (c_is_unsigned_integer(c, op_expr->getType())) {
1201 // we gotta emit 0 -% x1033 // we gotta emit 0 -% x
1202 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);1034 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
1203 node->data.bin_op_expr.op1 = trans_create_num_lit_node_unsigned(c, stmt, 0);1035 node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0);
1204 node->data.bin_op_expr.op2 = trans_expr(c, block, op_expr);1036 node->data.bin_op_expr.op2 = trans_expr(c, block, op_expr);
1205 node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;1037 node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;
1206 return node;1038 return node;
...@@ -1230,19 +1062,14 @@ static AstNode * trans_local_declaration(Context *c, AstNode *block, DeclStmt *s...@@ -1230,19 +1062,14 @@ static AstNode * trans_local_declaration(Context *c, AstNode *block, DeclStmt *s
1230 switch (decl->getKind()) {1062 switch (decl->getKind()) {
1231 case Decl::Var: {1063 case Decl::Var: {
1232 VarDecl *var_decl = (VarDecl *)decl;1064 VarDecl *var_decl = (VarDecl *)decl;
1233 AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration);
1234 node->data.variable_declaration.symbol = buf_create_from_str(decl_name(var_decl));
1235 QualType qual_type = var_decl->getTypeSourceInfo()->getType();1065 QualType qual_type = var_decl->getTypeSourceInfo()->getType();
1236 node->data.variable_declaration.is_const = qual_type.isConstQualified();1066 AstNode *init_node = var_decl->hasInit() ? trans_expr(c, block, var_decl->getInit()) : nullptr;
1237 node->data.variable_declaration.type = trans_qual_type(c, qual_type, stmt->getStartLoc());1067 AstNode *type_node = trans_qual_type(c, qual_type, stmt->getStartLoc());
1238 if (var_decl->hasInit()) {1068 AstNode *node = trans_create_node_var_decl(c, qual_type.isConstQualified(),
1239 node->data.variable_declaration.expr = trans_expr(c, block, var_decl->getInit());1069 buf_create_from_str(decl_name(var_decl)), type_node, init_node);
1240 }
1241
1242 block->data.block.statements.append(node);1070 block->data.block.statements.append(node);
1243 continue;1071 continue;
1244 }1072 }
1245
1246 case Decl::AccessSpec:1073 case Decl::AccessSpec:
1247 zig_panic("TODO handle decl kind AccessSpec");1074 zig_panic("TODO handle decl kind AccessSpec");
1248 case Decl::Block:1075 case Decl::Block:
...@@ -1802,53 +1629,57 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {...@@ -1802,53 +1629,57 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {
1802static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {1629static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
1803 Buf *fn_name = buf_create_from_str(decl_name(fn_decl));1630 Buf *fn_name = buf_create_from_str(decl_name(fn_decl));
18041631
1805 if (fn_decl->hasBody()) {
1806 fprintf(stderr, "fn %s\n", buf_ptr(fn_name));
1807 Stmt *body = fn_decl->getBody();
1808 AstNode *body_node = trans_stmt(c, nullptr, body);
1809 ast_render(c->codegen, stderr, body_node, 4);
1810 fprintf(stderr, "\n");
1811 }
1812
1813 if (get_global(c, fn_name)) {1632 if (get_global(c, fn_name)) {
1814 // we already saw this function1633 // we already saw this function
1815 return;1634 return;
1816 }1635 }
18171636
1818 TypeTableEntry *fn_type = resolve_qual_type(c, fn_decl->getType(), fn_decl);1637 AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), fn_decl->getLocation());
18191638 if (proto_node == nullptr) {
1820 if (fn_type->id == TypeTableEntryIdInvalid) {1639 emit_warning(c, fn_decl->getLocation(), "unable to resolve prototype of function '%s'", buf_ptr(fn_name));
1821 emit_warning(c, fn_decl->getLocation(), "ignoring function '%s' - unable to resolve type", buf_ptr(fn_name));
1822 return;1640 return;
1823 }1641 }
1824 assert(fn_type->id == TypeTableEntryIdFn);
18251642
1826 FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong);1643 proto_node->data.fn_proto.name = fn_name;
1827 buf_init_from_buf(&fn_entry->symbol_name, fn_name);1644 proto_node->data.fn_proto.is_extern = !fn_decl->hasBody();
1828 fn_entry->type_entry = fn_type;
18291645
1830 assert(fn_type->data.fn.fn_type_id.cc != CallingConventionNaked);1646 StorageClass sc = fn_decl->getStorageClass();
1647 if (sc == SC_None) {
1648 proto_node->data.fn_proto.visib_mod = fn_decl->hasBody() ? VisibModExport : c->visib_mod;
1649 } else if (sc == SC_Extern || sc == SC_Static) {
1650 proto_node->data.fn_proto.visib_mod = c->visib_mod;
1651 } else if (sc == SC_PrivateExtern) {
1652 emit_warning(c, fn_decl->getLocation(), "unsupported storage class: private extern");
1653 return;
1654 } else {
1655 emit_warning(c, fn_decl->getLocation(), "unsupported storage class: unknown");
1656 return;
1657 }
18311658
1832 size_t arg_count = fn_type->data.fn.fn_type_id.param_count;1659 const FunctionProtoType *fn_proto_ty = (const FunctionProtoType *) fn_decl->getType().getTypePtr();
1833 fn_entry->param_names = allocate<Buf *>(arg_count);1660 size_t arg_count = fn_proto_ty->getNumParams();
1834 Buf *name_buf;
1835 for (size_t i = 0; i < arg_count; i += 1) {1661 for (size_t i = 0; i < arg_count; i += 1) {
1662 AstNode *param_node = proto_node->data.fn_proto.params.at(i);
1836 const ParmVarDecl *param = fn_decl->getParamDecl(i);1663 const ParmVarDecl *param = fn_decl->getParamDecl(i);
1837 const char *name = decl_name(param);1664 const char *name = decl_name(param);
1838 if (strlen(name) == 0) {1665 if (strlen(name) != 0) {
1839 name_buf = buf_sprintf("arg%" ZIG_PRI_usize "", i);1666 param_node->data.param_decl.name = buf_create_from_str(name);
1840 } else {
1841 name_buf = buf_create_from_str(name);
1842 }1667 }
1843 fn_entry->param_names[i] = name_buf;
1844 }1668 }
18451669
1846 TldFn *tld_fn = allocate<TldFn>(1);1670 if (fn_decl->hasBody()) {
1847 parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name);1671 Stmt *body = fn_decl->getBody();
1848 tld_fn->fn_entry = fn_entry;1672
1849 add_global(c, &tld_fn->base);1673 AstNode *fn_def_node = trans_create_node(c, NodeTypeFnDef);
1674 fn_def_node->data.fn_def.fn_proto = proto_node;
1675 fn_def_node->data.fn_def.body = trans_stmt(c, nullptr, body);
18501676
1851 c->codegen->fn_protos.append(fn_entry);1677 proto_node->data.fn_proto.fn_def_node = fn_def_node;
1678 c->root->data.root.top_level_decls.append(fn_def_node);
1679 return;
1680 }
1681
1682 c->root->data.root.top_level_decls.append(proto_node);
1852}1683}
18531684
1854static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) {1685static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) {
...@@ -1874,53 +1705,36 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)...@@ -1874,53 +1705,36 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)
1874 // use the name of this typedef1705 // use the name of this typedef
1875 // TODO1706 // TODO
18761707
1877 TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl);1708 AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation());
1878 if (child_type->id == TypeTableEntryIdInvalid) {1709 if (type_node == nullptr) {
1879 emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name));1710 emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name));
1880 return;1711 return;
1881 }1712 }
1882 add_const_type(c, type_name, child_type);1713 add_global_var(c, type_name, type_node);
1883}1714 c->global_type_table.put(type_name, type_node);
1884
1885static void replace_with_fwd_decl(Context *c, TypeTableEntry *struct_type, Buf *full_type_name) {
1886 unsigned line = c->source_node ? c->source_node->line : 0;
1887 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugForwardDeclType(c->codegen->dbuilder,
1888 ZigLLVMTag_DW_structure_type(), buf_ptr(full_type_name),
1889 ZigLLVMFileToScope(c->import->di_file), c->import->di_file, line);
1890
1891 ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type);
1892 struct_type->di_type = replacement_di_type;
1893 struct_type->id = TypeTableEntryIdOpaque;
1894}1715}
18951716
1896static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {1717static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
1897 auto existing_entry = c->decl_table.maybe_get((void*)enum_decl);1718 auto existing_entry = c->decl_table.maybe_get((void*)enum_decl);
1898 if (existing_entry) {1719 if (existing_entry) {
1899 return existing_entry->value;1720 return existing_entry->value;
1900 }1721 }
19011722
1902 const char *raw_name = decl_name(enum_decl);1723 const char *raw_name = decl_name(enum_decl);
19031724 bool is_anonymous = (raw_name[0] == 0);
1904 Buf *bare_name;1725 Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
1905 if (raw_name[0] == 0) {1726 Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name));
1906 bare_name = buf_sprintf("anon_$%" PRIu32, get_next_anon_index(c));
1907 } else {
1908 bare_name = buf_create_from_str(raw_name);
1909 }
1910
1911 Buf *full_type_name = buf_sprintf("enum_%s", buf_ptr(bare_name));
19121727
1913 const EnumDecl *enum_def = enum_decl->getDefinition();1728 const EnumDecl *enum_def = enum_decl->getDefinition();
1914 if (!enum_def) {1729 if (!enum_def) {
1915 TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base,1730 AstNode *opaque_node = trans_create_node_opaque(c);
1916 ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern);1731 if (!is_anonymous) {
1917 enum_type->data.enumeration.zero_bits_known = true;1732 c->enum_type_table.put(bare_name, opaque_node);
1918 enum_type->data.enumeration.abi_alignment = 1;1733 add_global_weak_alias(c, bare_name, opaque_node);
1919 c->enum_type_table.put(bare_name, enum_type);1734 add_global_var(c, full_type_name, opaque_node);
1920 c->decl_table.put(enum_decl, enum_type);1735 }
1921 replace_with_fwd_decl(c, enum_type, full_type_name);1736 c->decl_table.put(enum_decl, opaque_node);
19221737 return opaque_node;
1923 return enum_type;
1924 }1738 }
19251739
1926 bool pure_enum = true;1740 bool pure_enum = true;
...@@ -1935,25 +1749,16 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)...@@ -1935,25 +1749,16 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
1935 }1749 }
1936 }1750 }
19371751
1938 TypeTableEntry *tag_int_type = resolve_qual_type(c, enum_decl->getIntegerType(), enum_decl);1752 AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation());
1753 assert(tag_int_type);
19391754
1940 if (pure_enum) {1755 if (pure_enum) {
1941 TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base,1756 AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl);
1942 ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern);1757 enum_node->data.container_decl.kind = ContainerKindEnum;
1943 TypeTableEntry *tag_type_entry = create_enum_tag_type(c->codegen, enum_type, tag_int_type);1758 enum_node->data.container_decl.layout = ContainerLayoutExtern;
1944 c->enum_type_table.put(bare_name, enum_type);1759 enum_node->data.container_decl.init_arg_expr = tag_int_type;
1945 c->decl_table.put(enum_decl, enum_type);
1946
1947 enum_type->data.enumeration.gen_field_count = 0;
1948 enum_type->data.enumeration.complete = true;
1949 enum_type->data.enumeration.zero_bits_known = true;
1950 enum_type->data.enumeration.abi_alignment = 1;
1951 enum_type->data.enumeration.tag_type = tag_type_entry;
1952
1953 enum_type->data.enumeration.src_field_count = field_count;
1954 enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
1955 ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count);
19561760
1761 enum_node->data.container_decl.fields.resize(field_count);
1957 uint32_t i = 0;1762 uint32_t i = 0;
1958 for (auto it = enum_def->enumerator_begin(),1763 for (auto it = enum_def->enumerator_begin(),
1959 it_end = enum_def->enumerator_end();1764 it_end = enum_def->enumerator_end();
...@@ -1963,92 +1768,63 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)...@@ -1963,92 +1768,63 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
19631768
1964 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));1769 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
1965 Buf *field_name;1770 Buf *field_name;
1966 if (buf_starts_with_buf(enum_val_name, bare_name)) {1771 if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) {
1967 field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name));1772 field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name));
1968 } else {1773 } else {
1969 field_name = enum_val_name;1774 field_name = enum_val_name;
1970 }1775 }
19711776
1972 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];1777 AstNode *field_node = trans_create_node(c, NodeTypeStructField);
1973 type_enum_field->name = field_name;1778 field_node->data.struct_field.name = field_name;
1974 type_enum_field->type_entry = c->codegen->builtin_types.entry_void;1779 field_node->data.struct_field.type = nullptr;
1975 type_enum_field->value = i;1780 enum_node->data.container_decl.fields.items[i] = field_node;
1976
1977 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(c->codegen->dbuilder, buf_ptr(type_enum_field->name), i);
1978
19791781
1980 // in C each enum value is in the global namespace. so we put them there too.1782 // in C each enum value is in the global namespace. so we put them there too.
1981 // at this point we can rely on the enum emitting successfully1783 // at this point we can rely on the enum emitting successfully
1982 add_global(c, create_global_num_lit_unsigned_negative(c, enum_val_name, i, false));1784 AstNode *field_access_node = trans_create_node_field_access(c,
1785 trans_create_node_symbol(c, full_type_name), field_name);
1786 add_global_var(c, enum_val_name, field_access_node);
1983 }1787 }
19841788
1985 // create llvm type for root struct1789 if (!is_anonymous) {
1986 enum_type->type_ref = tag_type_entry->type_ref;1790 c->enum_type_table.put(bare_name, enum_node);
19871791 add_global_weak_alias(c, bare_name, enum_node);
1988 enum_type->data.enumeration.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref,1792 add_global_var(c, full_type_name, enum_node);
1989 enum_type->type_ref);
1990
1991 // create debug type for tag
1992 unsigned line = c->source_node ? (c->source_node->line + 1) : 0;
1993 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, enum_type->type_ref);
1994 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, enum_type->type_ref);
1995 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(c->codegen->dbuilder,
1996 ZigLLVMFileToScope(c->import->di_file), buf_ptr(bare_name),
1997 c->import->di_file, line,
1998 debug_size_in_bits,
1999 debug_align_in_bits,
2000 di_enumerators, field_count, tag_type_entry->di_type, "");
2001
2002 ZigLLVMReplaceTemporary(c->codegen->dbuilder, enum_type->di_type, tag_di_type);
2003 enum_type->di_type = tag_di_type;
2004
2005 return enum_type;
2006 } else {
2007 // TODO after issue #305 is solved, make this be an enum with tag_int_type
2008 // as the integer type and set the custom enum values
2009 TypeTableEntry *enum_type = tag_int_type;
2010 c->enum_type_table.put(bare_name, enum_type);
2011 c->decl_table.put(enum_decl, enum_type);
2012
2013 // add variables for all the values with enum_type
2014 for (auto it = enum_def->enumerator_begin(),
2015 it_end = enum_def->enumerator_end();
2016 it != it_end; ++it)
2017 {
2018 const EnumConstantDecl *enum_const = *it;
2019
2020 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
2021
2022 Tld *tld = create_global_num_lit_ap(c, enum_decl, enum_val_name, enum_const->getInitVal());
2023 if (!tld)
2024 return c->codegen->builtin_types.entry_invalid;
2025
2026 add_global(c, tld);
2027 }1793 }
1794 c->decl_table.put(enum_decl, enum_node);
20281795
2029 return enum_type;1796 return enum_node;
2030 }1797 }
2031}
20321798
2033static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {1799 // TODO after issue #305 is solved, make this be an enum with tag_int_type
2034 TypeTableEntry *enum_type = resolve_enum_decl(c, enum_decl);1800 // as the integer type and set the custom enum values
1801 AstNode *enum_node = tag_int_type;
20351802
2036 if (enum_type->id == TypeTableEntryIdInvalid)
2037 return;
20381803
2039 // make an alias without the "enum_" prefix. this will get emitted at the1804 // add variables for all the values with enum_node
2040 // end if it doesn't conflict with anything else1805 for (auto it = enum_def->enumerator_begin(),
2041 bool is_anonymous = (decl_name(enum_decl)[0] == 0);1806 it_end = enum_def->enumerator_end();
2042 if (is_anonymous)1807 it != it_end; ++it)
2043 return;1808 {
1809 const EnumConstantDecl *enum_const = *it;
1810
1811 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
1812 AstNode *int_node = trans_create_node_apint(c, enum_const->getInitVal());
1813 AstNode *var_node = add_global_var(c, enum_val_name, int_node);
1814 var_node->data.variable_declaration.type = tag_int_type;
1815 }
20441816
2045 Buf *bare_name = buf_create_from_str(decl_name(enum_decl));1817 if (!is_anonymous) {
1818 c->enum_type_table.put(bare_name, enum_node);
1819 add_global_weak_alias(c, bare_name, enum_node);
1820 add_global_var(c, full_type_name, enum_node);
1821 }
1822 c->decl_table.put(enum_decl, enum_node);
20461823
2047 Tld *tld = add_container_tld(c, enum_type);1824 return enum_node;
2048 add_global_weak_alias(c, bare_name, tld);
2049}1825}
20501826
2051static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl) {1827static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
2052 auto existing_entry = c->decl_table.maybe_get((void*)record_decl);1828 auto existing_entry = c->decl_table.maybe_get((void*)record_decl);
2053 if (existing_entry) {1829 if (existing_entry) {
2054 return existing_entry->value;1830 return existing_entry->value;
...@@ -2058,35 +1834,26 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_...@@ -2058,35 +1834,26 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
20581834
2059 if (!record_decl->isStruct()) {1835 if (!record_decl->isStruct()) {
2060 emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name);1836 emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name);
2061 return c->codegen->builtin_types.entry_invalid;1837 c->decl_table.put(record_decl, nullptr);
2062 }1838 return nullptr;
2063
2064 Buf *bare_name;
2065 if (record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0) {
2066 bare_name = buf_sprintf("anon_$%" PRIu32, get_next_anon_index(c));
2067 } else {
2068 bare_name = buf_create_from_str(raw_name);
2069 }1839 }
20701840
2071 Buf *full_type_name = buf_sprintf("struct_%s", buf_ptr(bare_name));1841 bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0;
20721842 Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
20731843 Buf *full_type_name = (bare_name == nullptr) ? nullptr : buf_sprintf("struct_%s", buf_ptr(bare_name));
2074 TypeTableEntry *struct_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base,
2075 ContainerKindStruct, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern);
2076 struct_type->data.structure.zero_bits_known = true;
2077 struct_type->data.structure.abi_alignment = 1;
2078
2079 c->struct_type_table.put(bare_name, struct_type);
2080 c->decl_table.put(record_decl, struct_type);
20811844
2082 RecordDecl *record_def = record_decl->getDefinition();1845 RecordDecl *record_def = record_decl->getDefinition();
2083 unsigned line = c->source_node ? c->source_node->line : 0;1846 if (record_def == nullptr) {
2084 if (!record_def) {1847 AstNode *opaque_node = trans_create_node_opaque(c);
2085 replace_with_fwd_decl(c, struct_type, full_type_name);1848 if (!is_anonymous) {
2086 return struct_type;1849 c->struct_type_table.put(bare_name, opaque_node);
1850 add_global_weak_alias(c, bare_name, opaque_node);
1851 add_global_var(c, full_type_name, opaque_node);
1852 }
1853 c->decl_table.put(record_decl, opaque_node);
1854 return opaque_node;
2087 }1855 }
20881856
2089
2090 // count fields and validate1857 // count fields and validate
2091 uint32_t field_count = 0;1858 uint32_t field_count = 0;
2092 for (auto it = record_def->field_begin(),1859 for (auto it = record_def->field_begin(),
...@@ -2096,105 +1863,69 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_...@@ -2096,105 +1863,69 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
2096 const FieldDecl *field_decl = *it;1863 const FieldDecl *field_decl = *it;
20971864
2098 if (field_decl->isBitField()) {1865 if (field_decl->isBitField()) {
2099 emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield\n", buf_ptr(bare_name));1866 emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield",
2100 replace_with_fwd_decl(c, struct_type, full_type_name);1867 is_anonymous ? "(anon)" : buf_ptr(bare_name));
2101 return struct_type;1868
1869 AstNode *opaque_node = trans_create_node_opaque(c);
1870
1871 if (!is_anonymous) {
1872 c->struct_type_table.put(bare_name, opaque_node);
1873 add_global_weak_alias(c, bare_name, opaque_node);
1874 add_global_var(c, full_type_name, opaque_node);
1875 }
1876 c->decl_table.put(record_decl, opaque_node);
1877 return opaque_node;;
2102 }1878 }
2103 }1879 }
21041880
2105 struct_type->data.structure.src_field_count = field_count;1881 AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl);
2106 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);1882 struct_node->data.container_decl.kind = ContainerKindStruct;
2107 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);1883 struct_node->data.container_decl.layout = ContainerLayoutExtern;
2108 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count);
21091884
2110 // next, populate element_types as its needed for LLVMStructSetBody which is needed for LLVMOffsetOfElement1885 // TODO handle attribute packed
2111 uint32_t i = 0;
2112 for (auto it = record_def->field_begin(),
2113 it_end = record_def->field_end();
2114 it != it_end; ++it, i += 1)
2115 {
2116 const FieldDecl *field_decl = *it;
21171886
2118 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];1887 struct_node->data.container_decl.fields.resize(field_count);
2119 type_struct_field->name = buf_create_from_str(decl_name(field_decl));
2120 type_struct_field->src_index = i;
2121 type_struct_field->gen_index = i;
2122 TypeTableEntry *field_type = resolve_qual_type(c, field_decl->getType(), field_decl);
2123 type_struct_field->type_entry = field_type;
2124
2125 if (type_is_invalid(field_type) || !type_is_complete(field_type)) {
2126 emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - unresolved type\n", buf_ptr(bare_name));
2127 replace_with_fwd_decl(c, struct_type, full_type_name);
2128 return struct_type;
2129 }
21301888
2131 element_types[i] = field_type->type_ref;1889 // must be before fields in case a circular reference happens
2132 assert(element_types[i]);1890 if (!is_anonymous) {
1891 c->struct_type_table.put(bare_name, struct_node);
1892 add_global_weak_alias(c, bare_name, struct_node);
1893 add_global_var(c, full_type_name, struct_node);
2133 }1894 }
1895 c->decl_table.put(record_decl, struct_node);
21341896
2135 LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);1897 uint32_t i = 0;
2136
2137 // finally populate debug info
2138 i = 0;
2139 for (auto it = record_def->field_begin(),1898 for (auto it = record_def->field_begin(),
2140 it_end = record_def->field_end();1899 it_end = record_def->field_end();
2141 it != it_end; ++it, i += 1)1900 it != it_end; ++it, i += 1)
2142 {1901 {
2143 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];1902 const FieldDecl *field_decl = *it;
2144 TypeTableEntry *field_type = type_struct_field->type_entry;
2145
2146 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, field_type->type_ref);
2147 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, field_type->type_ref);
2148 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(c->codegen->target_data_ref, struct_type->type_ref, i);
2149 di_element_types[i] = ZigLLVMCreateDebugMemberType(c->codegen->dbuilder,
2150 ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
2151 c->import->di_file, line + 1,
2152 debug_size_in_bits,
2153 debug_align_in_bits,
2154 debug_offset_in_bits,
2155 0, field_type->di_type);
2156
2157 assert(di_element_types[i]);
21581903
2159 }1904 AstNode *field_node = trans_create_node(c, NodeTypeStructField);
2160 struct_type->data.structure.embedded_in_current = false;1905 field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl));
21611906 field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), field_decl->getLocation());
2162 struct_type->data.structure.gen_field_count = field_count;
2163 struct_type->data.structure.complete = true;
2164 struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref,
2165 struct_type->type_ref);
2166
2167 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, struct_type->type_ref);
2168 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, struct_type->type_ref);
2169 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(c->codegen->dbuilder,
2170 ZigLLVMFileToScope(c->import->di_file),
2171 buf_ptr(full_type_name), c->import->di_file, line + 1,
2172 debug_size_in_bits,
2173 debug_align_in_bits,
2174 0,
2175 nullptr, di_element_types, field_count, 0, nullptr, "");
2176
2177 ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type);
2178 struct_type->di_type = replacement_di_type;
2179
2180 return struct_type;
2181}
21821907
2183static void visit_record_decl(Context *c, const RecordDecl *record_decl) {1908 if (field_node->data.struct_field.type == nullptr) {
2184 TypeTableEntry *struct_type = resolve_record_decl(c, record_decl);1909 emit_warning(c, field_decl->getLocation(),
1910 "struct %s demoted to opaque type - unresolved type",
1911 is_anonymous ? "(anon)" : buf_ptr(bare_name));
21851912
2186 if (struct_type->id == TypeTableEntryIdInvalid) {1913 AstNode *opaque_node = trans_create_node_opaque(c);
2187 return;1914 if (!is_anonymous) {
2188 }1915 c->struct_type_table.put(bare_name, opaque_node);
1916 add_global_weak_alias(c, bare_name, opaque_node);
1917 add_global_var(c, full_type_name, opaque_node);
1918 }
1919 c->decl_table.put(record_decl, opaque_node);
21891920
2190 bool is_anonymous = (record_decl->isAnonymousStructOrUnion() || decl_name(record_decl)[0] == 0);1921 return opaque_node;
2191 if (is_anonymous)1922 }
2192 return;1923
1924 struct_node->data.container_decl.fields.items[i] = field_node;
1925 }
21931926
2194 Buf *bare_name = buf_create_from_str(decl_name(record_decl));
21951927
2196 Tld *tld = add_container_tld(c, struct_type);1928 return struct_node;
2197 add_global_weak_alias(c, bare_name, tld);
2198}1929}
21991930
2200static void visit_var_decl(Context *c, const VarDecl *var_decl) {1931static void visit_var_decl(Context *c, const VarDecl *var_decl) {
...@@ -2204,17 +1935,19 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {...@@ -2204,17 +1935,19 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
2204 case VarDecl::TLS_None:1935 case VarDecl::TLS_None:
2205 break;1936 break;
2206 case VarDecl::TLS_Static:1937 case VarDecl::TLS_Static:
2207 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - static thread local storage\n", buf_ptr(name));1938 emit_warning(c, var_decl->getLocation(),
1939 "ignoring variable '%s' - static thread local storage", buf_ptr(name));
2208 return;1940 return;
2209 case VarDecl::TLS_Dynamic:1941 case VarDecl::TLS_Dynamic:
2210 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - dynamic thread local storage\n", buf_ptr(name));1942 emit_warning(c, var_decl->getLocation(),
1943 "ignoring variable '%s' - dynamic thread local storage", buf_ptr(name));
2211 return;1944 return;
2212 }1945 }
22131946
2214 QualType qt = var_decl->getType();1947 QualType qt = var_decl->getType();
2215 TypeTableEntry *var_type = resolve_qual_type(c, qt, var_decl);1948 AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation());
2216 if (var_type->id == TypeTableEntryIdInvalid) {1949 if (var_type == nullptr) {
2217 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type\n", buf_ptr(name));1950 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name));
2218 return;1951 return;
2219 }1952 }
22201953
...@@ -2223,59 +1956,53 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {...@@ -2223,59 +1956,53 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
2223 bool is_const = qt.isConstQualified();1956 bool is_const = qt.isConstQualified();
22241957
2225 if (is_static && !is_extern) {1958 if (is_static && !is_extern) {
2226 if (!var_decl->hasInit()) {1959 AstNode *init_node;
2227 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - no initializer\n", buf_ptr(name));1960 if (var_decl->hasInit()) {
2228 return;1961 APValue *ap_value = var_decl->evaluateValue();
2229 }1962 if (ap_value == nullptr) {
2230 APValue *ap_value = var_decl->evaluateValue();
2231 if (!ap_value) {
2232 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unable to evaluate initializer\n", buf_ptr(name));
2233 return;
2234 }
2235 ConstExprValue *init_value = nullptr;
2236 switch (ap_value->getKind()) {
2237 case APValue::Int:
2238 {
2239 if (var_type->id != TypeTableEntryIdInt) {
2240 emit_warning(c, var_decl->getLocation(),
2241 "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name));
2242 return;
2243 }
2244 init_value = create_const_int_ap(c, var_type, var_decl, ap_value->getInt());
2245 if (!init_value)
2246 return;
2247
2248 break;
2249 }
2250 case APValue::Uninitialized:
2251 case APValue::Float:
2252 case APValue::ComplexInt:
2253 case APValue::ComplexFloat:
2254 case APValue::LValue:
2255 case APValue::Vector:
2256 case APValue::Array:
2257 case APValue::Struct:
2258 case APValue::Union:
2259 case APValue::MemberPointer:
2260 case APValue::AddrLabelDiff:
2261 emit_warning(c, var_decl->getLocation(),1963 emit_warning(c, var_decl->getLocation(),
2262 "ignoring variable '%s' - unrecognized initializer value kind\n", buf_ptr(name));1964 "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name));
2263 return;1965 return;
1966 }
1967 switch (ap_value->getKind()) {
1968 case APValue::Int:
1969 init_node = trans_create_node_apint(c, ap_value->getInt());
1970 break;
1971 case APValue::Uninitialized:
1972 init_node = trans_create_node_symbol_str(c, "undefined");
1973 break;
1974 case APValue::Float:
1975 case APValue::ComplexInt:
1976 case APValue::ComplexFloat:
1977 case APValue::LValue:
1978 case APValue::Vector:
1979 case APValue::Array:
1980 case APValue::Struct:
1981 case APValue::Union:
1982 case APValue::MemberPointer:
1983 case APValue::AddrLabelDiff:
1984 emit_warning(c, var_decl->getLocation(),
1985 "ignoring variable '%s' - unrecognized initializer value kind", buf_ptr(name));
1986 return;
1987 }
1988 } else {
1989 init_node = trans_create_node_symbol_str(c, "undefined");
2264 }1990 }
22651991
2266 TldVar *tld_var = create_global_var(c, name, init_value, true);1992 AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, init_node);
2267 add_global(c, &tld_var->base);1993 c->root->data.root.top_level_decls.append(var_node);
2268 return;1994 return;
2269 }1995 }
22701996
2271 if (is_extern) {1997 if (is_extern) {
2272 TldVar *tld_var = create_global_var(c, name, create_const_runtime(var_type), is_const);1998 AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, nullptr);
2273 tld_var->var->linkage = VarLinkageExternal;1999 var_node->data.variable_declaration.is_extern = true;
2274 add_global(c, &tld_var->base);2000 c->root->data.root.top_level_decls.append(var_node);
2275 return;2001 return;
2276 }2002 }
22772003
2278 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - non-extern, non-static variable\n", buf_ptr(name));2004 emit_warning(c, var_decl->getLocation(),
2005 "ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name));
2279 return;2006 return;
2280}2007}
22812008
...@@ -2290,25 +2017,22 @@ static bool decl_visitor(void *context, const Decl *decl) {...@@ -2290,25 +2017,22 @@ static bool decl_visitor(void *context, const Decl *decl) {
2290 visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl));2017 visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl));
2291 break;2018 break;
2292 case Decl::Enum:2019 case Decl::Enum:
2293 visit_enum_decl(c, static_cast<const EnumDecl *>(decl));2020 resolve_enum_decl(c, static_cast<const EnumDecl *>(decl));
2294 break;2021 break;
2295 case Decl::Record:2022 case Decl::Record:
2296 visit_record_decl(c, static_cast<const RecordDecl *>(decl));2023 resolve_record_decl(c, static_cast<const RecordDecl *>(decl));
2297 break;2024 break;
2298 case Decl::Var:2025 case Decl::Var:
2299 visit_var_decl(c, static_cast<const VarDecl *>(decl));2026 visit_var_decl(c, static_cast<const VarDecl *>(decl));
2300 break;2027 break;
2301 default:2028 default:
2302 emit_warning(c, decl->getLocation(), "ignoring %s decl\n", decl->getDeclKindName());2029 emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName());
2303 }2030 }
23042031
2305 return true;2032 return true;
2306}2033}
23072034
2308static bool name_exists(Context *c, Buf *name) {2035static bool name_exists(Context *c, Buf *name) {
2309 if (c->global_type_table.maybe_get(name)) {
2310 return true;
2311 }
2312 if (get_global(c, name)) {2036 if (get_global(c, name)) {
2313 return true;2037 return true;
2314 }2038 }
...@@ -2324,7 +2048,7 @@ static void render_aliases(Context *c) {...@@ -2324,7 +2048,7 @@ static void render_aliases(Context *c) {
2324 if (name_exists(c, alias->name))2048 if (name_exists(c, alias->name))
2325 continue;2049 continue;
23262050
2327 add_global_alias(c, alias->name, alias->tld);2051 add_global_var(c, alias->name, alias->node);
2328 }2052 }
2329}2053}
23302054
...@@ -2335,8 +2059,7 @@ static void render_macros(Context *c) {...@@ -2335,8 +2059,7 @@ static void render_macros(Context *c) {
2335 if (!entry)2059 if (!entry)
2336 break;2060 break;
23372061
2338 Tld *var_tld = entry->value;2062 add_global_var(c, entry->key, entry->value);
2339 add_global(c, var_tld);
2340 }2063 }
2341}2064}
23422065
...@@ -2355,52 +2078,52 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch...@@ -2355,52 +2078,52 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch
2355 switch (tok->id) {2078 switch (tok->id) {
2356 case CTokIdCharLit:2079 case CTokIdCharLit:
2357 if (is_last && is_first) {2080 if (is_last && is_first) {
2358 Tld *tld = create_global_num_lit_unsigned_negative(c, name, tok->data.char_lit, false);2081 AstNode *node = trans_create_node_unsigned(c, tok->data.char_lit);
2359 c->macro_table.put(name, tld);2082 c->macro_table.put(name, node);
2360 }2083 }
2361 return;2084 return;
2362 case CTokIdStrLit:2085 case CTokIdStrLit:
2363 if (is_last && is_first) {2086 if (is_last && is_first) {
2364 Tld *tld = create_global_str_lit_var(c, name, buf_create_from_buf(&tok->data.str_lit));2087 AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit));
2365 c->macro_table.put(name, tld);2088 c->macro_table.put(name, node);
2366 }2089 }
2367 return;2090 return;
2368 case CTokIdNumLitInt:2091 case CTokIdNumLitInt:
2369 if (is_last) {2092 if (is_last) {
2370 Tld *tld;2093 AstNode *node;
2371 switch (tok->data.num_lit_int.suffix) {2094 switch (tok->data.num_lit_int.suffix) {
2372 case CNumLitSuffixNone:2095 case CNumLitSuffixNone:
2373 tld = create_global_num_lit_unsigned_negative(c, name, tok->data.num_lit_int.x, negate);2096 node = trans_create_node_unsigned_negative(c, tok->data.num_lit_int.x, negate);
2374 break;2097 break;
2375 case CNumLitSuffixL:2098 case CNumLitSuffixL:
2376 tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,2099 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2377 c->codegen->builtin_types.entry_c_int[CIntTypeLong]);2100 "c_long");
2378 break;2101 break;
2379 case CNumLitSuffixU:2102 case CNumLitSuffixU:
2380 tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,2103 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2381 c->codegen->builtin_types.entry_c_int[CIntTypeUInt]);2104 "c_uint");
2382 break;2105 break;
2383 case CNumLitSuffixLU:2106 case CNumLitSuffixLU:
2384 tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,2107 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2385 c->codegen->builtin_types.entry_c_int[CIntTypeULong]);2108 "c_ulong");
2386 break;2109 break;
2387 case CNumLitSuffixLL:2110 case CNumLitSuffixLL:
2388 tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,2111 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2389 c->codegen->builtin_types.entry_c_int[CIntTypeLongLong]);2112 "c_longlong");
2390 break;2113 break;
2391 case CNumLitSuffixLLU:2114 case CNumLitSuffixLLU:
2392 tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,2115 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2393 c->codegen->builtin_types.entry_c_int[CIntTypeULongLong]);2116 "c_ulonglong");
2394 break;2117 break;
2395 }2118 }
2396 c->macro_table.put(name, tld);2119 c->macro_table.put(name, node);
2397 }2120 }
2398 return;2121 return;
2399 case CTokIdNumLitFloat:2122 case CTokIdNumLitFloat:
2400 if (is_last) {2123 if (is_last) {
2401 double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float;2124 double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float;
2402 Tld *tld = create_global_num_lit_float(c, name, value);2125 AstNode *node = trans_create_node_float_lit(c, value);
2403 c->macro_table.put(name, tld);2126 c->macro_table.put(name, node);
2404 }2127 }
2405 return;2128 return;
2406 case CTokIdSymbol:2129 case CTokIdSymbol:
...@@ -2429,29 +2152,29 @@ static void process_symbol_macros(Context *c) {...@@ -2429,29 +2152,29 @@ static void process_symbol_macros(Context *c) {
2429 for (size_t i = 0; i < c->macro_symbols.length; i += 1) {2152 for (size_t i = 0; i < c->macro_symbols.length; i += 1) {
2430 MacroSymbol ms = c->macro_symbols.at(i);2153 MacroSymbol ms = c->macro_symbols.at(i);
24312154
2432 // If this macro aliases another top level declaration, we can make that happen by2155 // Check if this macro aliases another top level declaration
2433 // putting another entry in the decl table pointing to the same top level decl.2156 AstNode *existing_node = get_global(c, ms.value);
2434 Tld *existing_tld = get_global(c, ms.value);2157 if (!existing_node || name_exists(c, ms.name))
2435 if (!existing_tld)
2436 continue;2158 continue;
24372159
2438 // If a macro aliases a global variable which is a function pointer, we conclude that2160 // If a macro aliases a global variable which is a function pointer, we conclude that
2439 // the macro is intended to represent a function that assumes the function pointer2161 // the macro is intended to represent a function that assumes the function pointer
2440 // variable is non-null and calls it.2162 // variable is non-null and calls it.
2441 if (existing_tld->id == TldIdVar) {2163 if (existing_node->type == NodeTypeVariableDeclaration) {
2442 TldVar *tld_var = (TldVar *)existing_tld;2164 AstNode *var_expr = existing_node->data.variable_declaration.expr;
2443 TypeTableEntry *var_type = tld_var->var->value->type;2165 if (var_expr != nullptr && var_expr->type == NodeTypePrefixOpExpr &&
2444 if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) {2166 var_expr->data.prefix_op_expr.prefix_op == PrefixOpMaybe)
2445 TypeTableEntry *child_type = var_type->data.maybe.child_type;2167 {
2446 if (child_type->id == TypeTableEntryIdFn) {2168 AstNode *fn_proto_node = var_expr->data.prefix_op_expr.primary_expr;
2447 Tld *tld = create_inline_fn_tld(c, ms.name, tld_var);2169 if (fn_proto_node->type == NodeTypeFnProto) {
2448 c->macro_table.put(ms.name, tld);2170 AstNode *inline_fn_node = trans_create_node_inline_fn(c, ms.name, ms.value, fn_proto_node);
2171 c->macro_table.put(ms.name, inline_fn_node);
2449 continue;2172 continue;
2450 }2173 }
2451 }2174 }
2452 }2175 }
24532176
2454 add_global_alias(c, ms.name, existing_tld);2177 add_global_var(c, ms.name, existing_node);
2455 }2178 }
2456}2179}
24572180
...@@ -2651,15 +2374,17 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch...@@ -2651,15 +2374,17 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
26512374
2652 c->ctx = &ast_unit->getASTContext();2375 c->ctx = &ast_unit->getASTContext();
2653 c->source_manager = &ast_unit->getSourceManager();2376 c->source_manager = &ast_unit->getSourceManager();
2377 c->root = trans_create_node(c, NodeTypeRoot);
26542378
2655 ast_unit->visitLocalTopLevelDecls(c, decl_visitor);2379 ast_unit->visitLocalTopLevelDecls(c, decl_visitor);
26562380
2657 process_preprocessor_entities(c, *ast_unit);2381 process_preprocessor_entities(c, *ast_unit);
26582382
2659 process_symbol_macros(c);
2660
2661 render_macros(c);2383 render_macros(c);
2384 process_symbol_macros(c);
2662 render_aliases(c);2385 render_aliases(c);
26632386
2387 import->root = c->root;
2388
2664 return 0;2389 return 0;
2665}2390}
test/parseh.zig+14-4
...@@ -21,6 +21,16 @@ pub fn addCases(cases: &tests.ParseHContext) {...@@ -21,6 +21,16 @@ pub fn addCases(cases: &tests.ParseHContext) {
21 \\pub extern fn foo() -> noreturn;21 \\pub extern fn foo() -> noreturn;
22 );22 );
2323
24 cases.add("simple function",
25 \\int abs(int a) {
26 \\ return a < 0 ? -a : a;
27 \\}
28 ,
29 \\export fn abs(a: c_int) -> c_int {
30 \\ return if (a < 0) -a else a;
31 \\}
32 );
33
24 cases.add("enums",34 cases.add("enums",
25 \\enum Foo {35 \\enum Foo {
26 \\ FooA,36 \\ FooA,
...@@ -34,13 +44,13 @@ pub fn addCases(cases: &tests.ParseHContext) {...@@ -34,13 +44,13 @@ pub fn addCases(cases: &tests.ParseHContext) {
34 \\ @"1",44 \\ @"1",
35 \\};45 \\};
36 ,46 ,
37 \\pub const FooA = 0;47 \\pub const FooA = Foo.A;
38 ,48 ,
39 \\pub const FooB = 1;49 \\pub const FooB = Foo.B;
40 ,50 ,
41 \\pub const Foo1 = 2;51 \\pub const Foo1 = Foo.1;
42 ,52 ,
43 \\pub const Foo = enum_Foo53 \\pub const Foo = enum_Foo;
44 );54 );
4555
46 cases.add("restrict -> noalias",56 cases.add("restrict -> noalias",