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 {
751751 ZigList<AstNode *> fields;
752752 ZigList<AstNode *> decls;
753753 ContainerLayout layout;
754 AstNode *init_arg_expr; // enum(T) or struct(endianness)
754755};
755756
756757struct AstNodeStructField {
src/ast_render.cpp+20-158
......@@ -112,16 +112,16 @@ static const char *extern_string(bool is_extern) {
112112 return is_extern ? "extern " : "";
113113}
114114
115static const char *calling_convention_string(CallingConvention cc) {
116 switch (cc) {
117 case CallingConventionUnspecified: return "";
118 case CallingConventionC: return "extern ";
119 case CallingConventionCold: return "coldcc ";
120 case CallingConventionNaked: return "nakedcc ";
121 case CallingConventionStdcall: return "stdcallcc ";
122 }
123 zig_unreachable();
124}
115//static const char *calling_convention_string(CallingConvention cc) {
116// switch (cc) {
117// case CallingConventionUnspecified: return "";
118// case CallingConventionC: return "extern ";
119// case CallingConventionCold: return "coldcc ";
120// case CallingConventionNaked: return "nakedcc ";
121// case CallingConventionStdcall: return "stdcallcc ";
122// }
123// zig_unreachable();
124//}
125125
126126static const char *inline_string(bool is_inline) {
127127 return is_inline ? "inline " : "";
......@@ -439,8 +439,10 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
439439 fprintf(ar->f, ")");
440440
441441 AstNode *return_type_node = node->data.fn_proto.return_type;
442 fprintf(ar->f, " -> ");
443 render_node_grouped(ar, return_type_node);
442 if (return_type_node != nullptr) {
443 fprintf(ar->f, " -> ");
444 render_node_grouped(ar, return_type_node);
445 }
444446 break;
445447 }
446448 case NodeTypeFnDef:
......@@ -651,16 +653,19 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
651653 break;
652654 case NodeTypeContainerDecl:
653655 {
656 const char *layout_str = layout_string(node->data.container_decl.layout);
654657 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);
656659 ar->indent += ar->indent_size;
657660 for (size_t field_i = 0; field_i < node->data.container_decl.fields.length; field_i += 1) {
658661 AstNode *field_node = node->data.container_decl.fields.at(field_i);
659662 assert(field_node->type == NodeTypeStructField);
660663 print_indent(ar);
661664 print_symbol(ar, field_node->data.struct_field.name);
662 fprintf(ar->f, ": ");
663 render_node_grouped(ar, field_node->data.struct_field.type);
665 if (field_node->data.struct_field.type != nullptr) {
666 fprintf(ar->f, ": ");
667 render_node_grouped(ar, field_node->data.struct_field.type);
668 }
664669 fprintf(ar->f, ",\n");
665670 }
666671
......@@ -989,146 +994,3 @@ void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size) {
989994
990995 render_node_grouped(&ar, node);
991996}
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);
1919
2020const char *container_string(ContainerKind kind);
2121
22void ast_render_decls(CodeGen *codegen, FILE *f, int indent_size, ImportTableEntry *import);
23
2422#endif
2523
src/bigint.cpp+19
......@@ -165,6 +165,25 @@ void bigint_init_signed(BigInt *dest, int64_t x) {
165165 dest->data.digit = ((uint64_t)(-(x + 1))) + 1;
166166}
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
168187void bigint_init_bigint(BigInt *dest, const BigInt *src) {
169188 if (src->digit_count == 0) {
170189 return bigint_init_unsigned(dest, 0);
src/bigint.hpp+1
......@@ -34,6 +34,7 @@ void bigint_init_u128(BigInt *dest, unsigned __int128 x);
3434void bigint_init_signed(BigInt *dest, int64_t x);
3535void bigint_init_bigint(BigInt *dest, const BigInt *src);
3636void 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
3839// panics if number won't fit
3940uint64_t bigint_as_unsigned(const BigInt *bigint);
src/codegen.hpp-1
......@@ -55,7 +55,6 @@ void codegen_add_assembly(CodeGen *g, Buf *path);
5555void codegen_add_object(CodeGen *g, Buf *object_path);
5656
5757void codegen_parseh(CodeGen *g, Buf *path);
58void codegen_render_ast(CodeGen *g, FILE *f, int indent_size);
5958
6059
6160#endif
src/ir.cpp+11-66
......@@ -6114,9 +6114,14 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
61146114 return irb->codegen->invalid_instruction;
61156115 }
61166116
6117 IrInstruction *return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope);
6118 if (return_type == irb->codegen->invalid_instruction)
6119 return irb->codegen->invalid_instruction;
6117 IrInstruction *return_type;
6118 if (node->data.fn_proto.return_type == nullptr) {
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
61216126 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, is_var_args);
61226127}
......@@ -13358,9 +13363,11 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc
1335813363 if (ira->codegen->verbose) {
1335913364 fprintf(stderr, "\nC imports:\n");
1336013365 fprintf(stderr, "-----------\n");
13361 ast_render_decls(ira->codegen, stderr, 4, child_import);
13366 ast_render(ira->codegen, stderr, child_import->root, 4);
1336213367 }
1336313368
13369 scan_decls(ira->codegen, child_import->decls_scope, child_import->root);
13370
1336413371 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1336513372 out_val->data.x_import = child_import;
1336613373 return ira->codegen->builtin_types.entry_namespace;
......@@ -15515,65 +15522,3 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1551515522 }
1551615523 zig_unreachable();
1551715524}
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
2424bool ir_has_side_effects(IrInstruction *instruction);
2525ConstExprValue *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
2927#endif
src/main.cpp+1-1
......@@ -670,7 +670,7 @@ int main(int argc, char **argv) {
670670 return EXIT_SUCCESS;
671671 } else if (cmd == CmdParseH) {
672672 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);
674674 if (timing_info)
675675 codegen_print_timing_report(g, stdout);
676676 return EXIT_SUCCESS;
src/parseh.cpp+643-918
......@@ -15,6 +15,7 @@
1515#include "parseh.hpp"
1616#include "parser.hpp"
1717
18
1819#include <clang/Frontend/ASTUnit.h>
1920#include <clang/Frontend/CompilerInstance.h>
2021#include <clang/AST/Expr.h>
......@@ -28,14 +29,9 @@ struct MacroSymbol {
2829 Buf *value;
2930};
3031
31struct GlobalValue {
32 TypeTableEntry *type;
33 bool is_const;
34};
35
3632struct Alias {
3733 Buf *name;
38 Tld *tld;
34 AstNode *node;
3935};
4036
4137struct Context {
......@@ -43,30 +39,26 @@ struct Context {
4339 ZigList<ErrorMsg *> *errors;
4440 bool warnings_on;
4541 VisibMod visib_mod;
46
47 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> global_type_table;
48 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_type_table2;
49
50 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table;
51 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table;
52 HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table;
53 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> macro_table;
42 AstNode *root;
43 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_type_table;
44 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> struct_type_table;
45 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> enum_type_table;
46 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
47 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
5448 SourceManager *source_manager;
5549 ZigList<Alias> aliases;
5650 ZigList<MacroSymbol> macro_symbols;
5751 AstNode *source_node;
58 uint32_t next_anon_index;
5952
6053 CodeGen *codegen;
6154 ASTContext *ctx;
6255};
6356
64static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl,
65 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table);
66
67static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl);
68static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl);
69static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
57static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);
58static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
59static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc,
60 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> *type_table);
61static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
7062
7163
7264__attribute__ ((format (printf, 3, 4)))
......@@ -93,522 +85,226 @@ static void emit_warning(Context *c, const SourceLocation &sl, const char *forma
9385 fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg));
9486}
9587
96static uint32_t get_next_anon_index(Context *c) {
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) {
88static void add_global_weak_alias(Context *c, Buf *name, AstNode *node) {
10789 Alias *alias = c->aliases.add_one();
10890 alias->name = name;
109 alias->tld = tld;
91 alias->node = node;
11092}
11193
112static void add_global(Context *c, Tld *tld) {
113 return add_global_alias(c, tld->name, tld);
94static AstNode * trans_create_node(Context *c, NodeType id) {
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;
114100}
115101
116static Tld *get_global(Context *c, Buf *name) {
117 {
118 auto entry = c->import->decls_scope->decl_table.maybe_get(name);
119 if (entry)
120 return entry->value;
121 }
122 {
123 auto entry = c->macro_table.maybe_get(name);
124 if (entry)
125 return entry->value;
126 }
127 return nullptr;
102static AstNode *trans_create_node_float_lit(Context *c, double value) {
103 AstNode *node = trans_create_node(c, NodeTypeFloatLiteral);
104 node->data.float_literal.bigfloat = allocate<BigFloat>(1);
105 bigfloat_init_64(node->data.float_literal.bigfloat, value);
106 return node;
128107}
129108
130static const char *decl_name(const Decl *decl) {
131 const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);
132 return (const char *)named_decl->getName().bytes_begin();
109static AstNode *trans_create_node_symbol(Context *c, Buf *name) {
110 AstNode *node = trans_create_node(c, NodeTypeSymbol);
111 node->data.symbol_expr.symbol = name;
112 return node;
133113}
134114
135static void parseh_init_tld(Context *c, Tld *tld, TldId id, Buf *name) {
136 init_tld(tld, id, name, c->visib_mod, c->source_node, &c->import->decls_scope->base);
137 tld->resolution = TldResolutionOk;
138 tld->import = c->import;
115static AstNode *trans_create_node_symbol_str(Context *c, const char *name) {
116 return trans_create_node_symbol(c, buf_create_from_str(name));
139117}
140118
141static Tld *create_inline_fn_tld(Context *c, Buf *fn_name, TldVar *tld_var) {
142 TldFn *tld_fn = allocate<TldFn>(1);
143 parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name);
144 tld_fn->fn_entry = ir_create_inline_fn(c->codegen, fn_name, tld_var->var, &c->import->decls_scope->base);
145 return &tld_fn->base;
119static AstNode *trans_create_node_builtin_fn_call(Context *c, Buf *name) {
120 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
121 node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, name);
122 node->data.fn_call_expr.is_builtin = true;
123 return node;
146124}
147125
148static TldVar *create_global_var(Context *c, Buf *name, ConstExprValue *var_value, bool is_const) {
149 auto entry = c->import->decls_scope->decl_table.maybe_get(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;
126static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *name) {
127 return trans_create_node_builtin_fn_call(c, buf_create_from_str(name));
161128}
162129
163static Tld *create_global_str_lit_var(Context *c, Buf *name, Buf *value) {
164 TldVar *tld_var = create_global_var(c, name, create_const_c_str_lit(c->codegen, value), true);
165 return &tld_var->base;
130static AstNode *trans_create_node_opaque(Context *c) {
131 return trans_create_node_builtin_fn_call_str(c, "opaque");
166132}
167133
168static Tld *create_global_num_lit_unsigned_negative_type(Context *c, Buf *name, uint64_t x, bool negative, TypeTableEntry *type_entry) {
169 ConstExprValue *var_val = create_const_unsigned_negative(type_entry, x, negative);
170 TldVar *tld_var = create_global_var(c, name, var_val, true);
171 return &tld_var->base;
134static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) {
135 AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr);
136 node->data.field_access_expr.struct_expr = container;
137 node->data.field_access_expr.field_name = field_name;
138 return node;
172139}
173140
174static Tld *create_global_num_lit_unsigned_negative(Context *c, Buf *name, uint64_t x, bool negative) {
175 return create_global_num_lit_unsigned_negative_type(c, name, x, negative, c->codegen->builtin_types.entry_num_lit_int);
141static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) {
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;
176146}
177147
178static Tld *create_global_num_lit_float(Context *c, Buf *name, double value) {
179 ConstExprValue *var_val = create_const_float(c->codegen->builtin_types.entry_num_lit_float, value);
180 TldVar *tld_var = create_global_var(c, name, var_val, true);
181 return &tld_var->base;
148static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) {
149 AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr);
150 node->data.addr_of_expr.is_const = is_const;
151 node->data.addr_of_expr.is_volatile = is_volatile;
152 node->data.addr_of_expr.op_expr = child_node;
153 return node;
182154}
183155
184static ConstExprValue *create_const_int_ap(Context *c, TypeTableEntry *type, const Decl *source_decl,
185 const llvm::APSInt &aps_int)
186{
187 if (aps_int.isSigned()) {
188 if (aps_int > INT64_MAX || aps_int < INT64_MIN) {
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 }
156static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) {
157 AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
158 node->data.string_literal.buf = buf;
159 node->data.string_literal.c = true;
160 return node;
202161}
203162
204static Tld *create_global_num_lit_ap(Context *c, const Decl *source_decl, Buf *name,
205 const llvm::APSInt &aps_int)
206{
207 ConstExprValue *const_value = create_const_int_ap(c, c->codegen->builtin_types.entry_num_lit_int,
208 source_decl, aps_int);
209 if (!const_value)
210 return nullptr;
211 TldVar *tld_var = create_global_var(c, name, const_value, true);
212 return &tld_var->base;
163static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) {
164 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
165 node->data.int_literal.bigint = allocate<BigInt>(1);
166 bigint_init_data(node->data.int_literal.bigint, &x, 1, is_negative);
167 return node;
213168}
214169
215
216static Tld *add_const_type(Context *c, Buf *name, TypeTableEntry *type_entry) {
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;
170static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) {
171 return trans_create_node_unsigned_negative(c, x, false);
223172}
224173
225static Tld *add_container_tld(Context *c, TypeTableEntry *type_entry) {
226 return add_const_type(c, &type_entry->name, type_entry);
174static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) {
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;
227180}
228181
229static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) {
230 return (type_entry == c->codegen->builtin_types.entry_c_void);
182static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative,
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);
231187}
232188
233static bool qual_type_child_is_fn_proto(const QualType &qt) {
234 if (qt.getTypePtr()->getTypeClass() == Type::Paren) {
235 const ParenType *paren_type = static_cast<const ParenType *>(qt.getTypePtr());
236 if (paren_type->getInnerType()->getTypeClass() == Type::FunctionProto) {
237 return true;
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;
189static AstNode *trans_create_node_array_type(Context *c, AstNode *size_node, AstNode *child_type_node) {
190 AstNode *node = trans_create_node(c, NodeTypeArrayType);
191 node->data.array_type.size = size_node;
192 node->data.array_type.child_type = child_type_node;
193 return node;
244194}
245195
246static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl,
247 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table)
196static AstNode *trans_create_node_var_decl(Context *c, bool is_const, Buf *var_name, AstNode *type_node,
197 AstNode *init_node)
248198{
249 switch (ty->getTypeClass()) {
250 case Type::Builtin:
251 {
252 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
253 switch (builtin_ty->getKind()) {
254 case BuiltinType::Void:
255 return c->codegen->builtin_types.entry_c_void;
256 case BuiltinType::Bool:
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:
199 AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration);
200 node->data.variable_declaration.visib_mod = c->visib_mod;
201 node->data.variable_declaration.symbol = var_name;
202 node->data.variable_declaration.is_const = is_const;
203 node->data.variable_declaration.type = type_node;
204 node->data.variable_declaration.expr = init_node;
205 return node;
206}
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)) {
367 return get_maybe_type(c->codegen, child_type);
368 }
369 bool is_const = child_qt.isConstQualified();
209static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_name, AstNode *src_proto_node) {
210 AstNode *fn_def = trans_create_node(c, NodeTypeFnDef);
211 AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto);
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);
372 return get_maybe_type(c->codegen, non_null_pointer_type);
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);
217 fn_def->data.fn_def.fn_proto = fn_proto;
218 fn_proto->data.fn_proto.fn_def_node = fn_def;
434219
435 switch (fn_proto_ty->getCallConv()) {
436 case CC_C: // __attribute__((cdecl))
437 break;
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 }
220 AstNode *unwrap_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, trans_create_node_symbol(c, var_name));
221 AstNode *fn_call_node = trans_create_node(c, NodeTypeFnCallExpr);
222 fn_call_node->data.fn_call_expr.fn_ref_expr = unwrap_node;
487223
488 FnTypeId fn_type_id = {0};
489 fn_type_id.cc = CallingConventionC;
490 fn_type_id.is_var_args = fn_proto_ty->isVariadic();
491 fn_type_id.param_count = fn_proto_ty->getNumParams();
224 for (size_t i = 0; i < src_proto_node->data.fn_proto.params.length; i += 1) {
225 AstNode *src_param_node = src_proto_node->data.fn_proto.params.at(i);
226 Buf *param_name = src_param_node->data.param_decl.name;
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()) {
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 }
234 fn_call_node->data.fn_call_expr.params.append(trans_create_node_symbol(c, param_name));
507235
508 fn_type_id.param_info = allocate_nonzero<FnTypeParamInfo>(fn_type_id.param_count);
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);
236 }
512237
513 if (type_is_invalid(param_type)) {
514 emit_warning(c, decl->getLocation(), "unresolved function proto parameter type");
515 return c->codegen->builtin_types.entry_invalid;
516 }
238 AstNode *block = trans_create_node(c, NodeTypeBlock);
239 block->data.block.statements.resize(1);
240 block->data.block.statements.items[0] = fn_call_node;
517241
518 FnTypeParamInfo *param_info = &fn_type_id.param_info[i];
519 param_info->type = param_type;
520 param_info->is_noalias = qt.isRestrictQualified();
521 }
242 fn_def->data.fn_def.body = block;
243 return fn_def;
244}
522245
523 return get_fn_type(c->codegen, &fn_type_id);
524 }
525 case Type::Record:
526 {
527 const RecordType *record_ty = static_cast<const RecordType*>(ty);
528 return resolve_record_decl(c, record_ty->getDecl());
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());
246static AstNode *get_global(Context *c, Buf *name) {
247 for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) {
248 AstNode *decl_node = c->root->data.root.top_level_decls.items[i];
249 if (decl_node->type == NodeTypeVariableDeclaration) {
250 if (buf_eql_buf(decl_node->data.variable_declaration.symbol, name)) {
251 return decl_node;
534252 }
535 case Type::ConstantArray:
536 {
537 const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty);
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);
253 } else if (decl_node->type == NodeTypeFnDef) {
254 if (buf_eql_buf(decl_node->data.fn_def.fn_proto->data.fn_proto.name, name)) {
255 return decl_node;
545256 }
546 case Type::Paren:
547 {
548 const ParenType *paren_ty = static_cast<const ParenType *>(ty);
549 return resolve_qual_type(c, paren_ty->getInnerType(), decl);
257 } else if (decl_node->type == NodeTypeFnProto) {
258 if (buf_eql_buf(decl_node->data.fn_proto.name, name)) {
259 return decl_node;
550260 }
551 case Type::Decayed:
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;
261 }
597262 }
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();
599282}
600283
601static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl,
602 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table)
603{
604 return resolve_type_with_table(c, qt.getTypePtr(), decl, type_table);
284static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) {
285 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
286 node->data.int_literal.bigint = allocate<BigInt>(1);
287 bigint_init_data(node->data.int_literal.bigint, aps_int.getRawData(), aps_int.getNumWords(), aps_int.isNegative());
288 return node;
289
605290}
606291
607static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl) {
608 return resolve_qual_type_with_table(c, qt, decl, &c->global_type_table);
292static bool is_c_void_type(AstNode *node) {
293 return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
609294}
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
613309static bool c_is_signed_integer(Context *c, QualType qt) {
614310 const Type *c_type = qt.getTypePtr();
......@@ -668,19 +364,12 @@ static bool c_is_float(Context *c, QualType qt) {
668364}
669365
670366static AstNode * trans_stmt(Context *c, AstNode *block, Stmt *stmt);
671static AstNode * trans_create_node(Context *c, NodeType id);
672367static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
673368
674369static AstNode * trans_expr(Context *c, AstNode *block, Expr *expr) {
675370 return trans_stmt(c, block, expr);
676371}
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
684373static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLocation &source_loc,
685374 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> *type_table)
686375{
......@@ -690,43 +379,43 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo
690379 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
691380 switch (builtin_ty->getKind()) {
692381 case BuiltinType::Void:
693 return trans_create_symbol_node(c, "c_void");
382 return trans_create_node_symbol_str(c, "c_void");
694383 case BuiltinType::Bool:
695 return trans_create_symbol_node(c, "bool");
384 return trans_create_node_symbol_str(c, "bool");
696385 case BuiltinType::Char_U:
697386 case BuiltinType::UChar:
698387 case BuiltinType::Char_S:
699 return trans_create_symbol_node(c, "u8");
388 return trans_create_node_symbol_str(c, "u8");
700389 case BuiltinType::SChar:
701 return trans_create_symbol_node(c, "i8");
390 return trans_create_node_symbol_str(c, "i8");
702391 case BuiltinType::UShort:
703 return trans_create_symbol_node(c, "c_ushort");
392 return trans_create_node_symbol_str(c, "c_ushort");
704393 case BuiltinType::UInt:
705 return trans_create_symbol_node(c, "c_uint");
394 return trans_create_node_symbol_str(c, "c_uint");
706395 case BuiltinType::ULong:
707 return trans_create_symbol_node(c, "c_ulong");
396 return trans_create_node_symbol_str(c, "c_ulong");
708397 case BuiltinType::ULongLong:
709 return trans_create_symbol_node(c, "c_ulonglong");
398 return trans_create_node_symbol_str(c, "c_ulonglong");
710399 case BuiltinType::Short:
711 return trans_create_symbol_node(c, "c_short");
400 return trans_create_node_symbol_str(c, "c_short");
712401 case BuiltinType::Int:
713 return trans_create_symbol_node(c, "c_int");
402 return trans_create_node_symbol_str(c, "c_int");
714403 case BuiltinType::Long:
715 return trans_create_symbol_node(c, "c_long");
404 return trans_create_node_symbol_str(c, "c_long");
716405 case BuiltinType::LongLong:
717 return trans_create_symbol_node(c, "c_longlong");
406 return trans_create_node_symbol_str(c, "c_longlong");
718407 case BuiltinType::UInt128:
719 return trans_create_symbol_node(c, "u128");
408 return trans_create_node_symbol_str(c, "u128");
720409 case BuiltinType::Int128:
721 return trans_create_symbol_node(c, "i128");
410 return trans_create_node_symbol_str(c, "i128");
722411 case BuiltinType::Float:
723 return trans_create_symbol_node(c, "f32");
412 return trans_create_node_symbol_str(c, "f32");
724413 case BuiltinType::Double:
725 return trans_create_symbol_node(c, "f64");
414 return trans_create_node_symbol_str(c, "f64");
726415 case BuiltinType::Float128:
727 return trans_create_symbol_node(c, "f128");
416 return trans_create_node_symbol_str(c, "f128");
728417 case BuiltinType::LongDouble:
729 return trans_create_symbol_node(c, "c_longdouble");
418 return trans_create_node_symbol_str(c, "c_longdouble");
730419 case BuiltinType::WChar_U:
731420 case BuiltinType::Char16:
732421 case BuiltinType::Char32:
......@@ -786,7 +475,8 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo
786475 case BuiltinType::OCLClkEvent:
787476 case BuiltinType::OCLQueue:
788477 case BuiltinType::OCLReserveID:
789 zig_panic("TODO more c type");
478 emit_warning(c, source_loc, "unsupported builtin type");
479 return nullptr;
790480 }
791481 break;
792482 }
......@@ -795,40 +485,218 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo
795485 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
796486 QualType child_qt = pointer_ty->getPointeeType();
797487 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
800493 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);
802495 }
803496
804 AstNode *pointer_node = trans_create_node(c, NodeTypeAddrOfExpr);
805 pointer_node->data.addr_of_expr.is_const = child_qt.isConstQualified();
806 pointer_node->data.addr_of_expr.is_volatile = child_qt.isVolatileQualified();
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;
497 AstNode *pointer_node = trans_create_node_addr_of(c, child_qt.isConstQualified(),
498 child_qt.isVolatileQualified(), child_node);
499 return trans_create_node_prefix_op(c, PrefixOpMaybe, pointer_node);
813500 }
814501 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 }
816535 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 }
818554 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 }
820663 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 }
822668 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 }
824673 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 }
826685 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 }
828690 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 }
830695 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 }
832700 case Type::BlockPointer:
833701 case Type::LValueReference:
834702 case Type::RValueReference:
......@@ -863,7 +731,8 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo
863731 case Type::Pipe:
864732 case Type::ObjCTypeParam:
865733 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;
867736 }
868737 zig_unreachable();
869738}
......@@ -875,15 +744,7 @@ static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const Sourc
875744}
876745
877746static 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);
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;
747 return trans_qual_type_with_table(c, qt, source_loc, &c->global_type_table);
887748}
888749
889750static 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)
907768 }
908769}
909770
910static void aps_int_to_bigint(Context *c, const llvm::APSInt &aps_int, BigInt *bigint) {
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);
771static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) {
929772 llvm::APSInt result;
930773 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");
932775 }
933 node->data.int_literal.bigint = allocate<BigInt>(1);
934 aps_int_to_bigint(c, result, node->data.int_literal.bigint);
935 return node;
776 return trans_create_node_apint(c, result);
936777}
937778
938static AstNode * trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) {
779static AstNode *trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) {
939780 AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
940781
941782 Expr *cond_expr = stmt->getCond();
......@@ -1034,9 +875,7 @@ static AstNode * trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCa
1034875 return trans_expr(c, block, stmt->getSubExpr());
1035876 case CK_IntegralCast:
1036877 {
1037 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
1038 node->data.fn_call_expr.fn_ref_expr = trans_create_symbol_node(c, "bitCast");
1039 node->data.fn_call_expr.is_builtin = true;
878 AstNode *node = trans_create_node_builtin_fn_call_str(c, "bitCast");
1040879 node->data.fn_call_expr.params.append(trans_qual_type(c, stmt->getType(), stmt->getExprLoc()));
1041880 node->data.fn_call_expr.params.append(trans_expr(c, block, stmt->getSubExpr()));
1042881 return node;
......@@ -1166,13 +1005,6 @@ static AstNode * trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) {
11661005 return node;
11671006}
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
11761008static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) {
11771009 switch (stmt->getOpcode()) {
11781010 case UO_PostInc:
......@@ -1200,7 +1032,7 @@ static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator
12001032 } else if (c_is_unsigned_integer(c, op_expr->getType())) {
12011033 // we gotta emit 0 -% x
12021034 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);
12041036 node->data.bin_op_expr.op2 = trans_expr(c, block, op_expr);
12051037 node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;
12061038 return node;
......@@ -1230,19 +1062,14 @@ static AstNode * trans_local_declaration(Context *c, AstNode *block, DeclStmt *s
12301062 switch (decl->getKind()) {
12311063 case Decl::Var: {
12321064 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));
12351065 QualType qual_type = var_decl->getTypeSourceInfo()->getType();
1236 node->data.variable_declaration.is_const = qual_type.isConstQualified();
1237 node->data.variable_declaration.type = trans_qual_type(c, qual_type, stmt->getStartLoc());
1238 if (var_decl->hasInit()) {
1239 node->data.variable_declaration.expr = trans_expr(c, block, var_decl->getInit());
1240 }
1241
1066 AstNode *init_node = var_decl->hasInit() ? trans_expr(c, block, var_decl->getInit()) : nullptr;
1067 AstNode *type_node = trans_qual_type(c, qual_type, stmt->getStartLoc());
1068 AstNode *node = trans_create_node_var_decl(c, qual_type.isConstQualified(),
1069 buf_create_from_str(decl_name(var_decl)), type_node, init_node);
12421070 block->data.block.statements.append(node);
12431071 continue;
12441072 }
1245
12461073 case Decl::AccessSpec:
12471074 zig_panic("TODO handle decl kind AccessSpec");
12481075 case Decl::Block:
......@@ -1802,53 +1629,57 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) {
18021629static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
18031630 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
18131632 if (get_global(c, fn_name)) {
18141633 // we already saw this function
18151634 return;
18161635 }
18171636
1818 TypeTableEntry *fn_type = resolve_qual_type(c, fn_decl->getType(), fn_decl);
1819
1820 if (fn_type->id == TypeTableEntryIdInvalid) {
1821 emit_warning(c, fn_decl->getLocation(), "ignoring function '%s' - unable to resolve type", buf_ptr(fn_name));
1637 AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), fn_decl->getLocation());
1638 if (proto_node == nullptr) {
1639 emit_warning(c, fn_decl->getLocation(), "unable to resolve prototype of function '%s'", buf_ptr(fn_name));
18221640 return;
18231641 }
1824 assert(fn_type->id == TypeTableEntryIdFn);
18251642
1826 FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong);
1827 buf_init_from_buf(&fn_entry->symbol_name, fn_name);
1828 fn_entry->type_entry = fn_type;
1643 proto_node->data.fn_proto.name = fn_name;
1644 proto_node->data.fn_proto.is_extern = !fn_decl->hasBody();
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;
1833 fn_entry->param_names = allocate<Buf *>(arg_count);
1834 Buf *name_buf;
1659 const FunctionProtoType *fn_proto_ty = (const FunctionProtoType *) fn_decl->getType().getTypePtr();
1660 size_t arg_count = fn_proto_ty->getNumParams();
18351661 for (size_t i = 0; i < arg_count; i += 1) {
1662 AstNode *param_node = proto_node->data.fn_proto.params.at(i);
18361663 const ParmVarDecl *param = fn_decl->getParamDecl(i);
18371664 const char *name = decl_name(param);
1838 if (strlen(name) == 0) {
1839 name_buf = buf_sprintf("arg%" ZIG_PRI_usize "", i);
1840 } else {
1841 name_buf = buf_create_from_str(name);
1665 if (strlen(name) != 0) {
1666 param_node->data.param_decl.name = buf_create_from_str(name);
18421667 }
1843 fn_entry->param_names[i] = name_buf;
18441668 }
18451669
1846 TldFn *tld_fn = allocate<TldFn>(1);
1847 parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name);
1848 tld_fn->fn_entry = fn_entry;
1849 add_global(c, &tld_fn->base);
1670 if (fn_decl->hasBody()) {
1671 Stmt *body = fn_decl->getBody();
1672
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);
18521683}
18531684
18541685static 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)
18741705 // use the name of this typedef
18751706 // TODO
18761707
1877 TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl);
1878 if (child_type->id == TypeTableEntryIdInvalid) {
1708 AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation());
1709 if (type_node == nullptr) {
18791710 emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name));
18801711 return;
18811712 }
1882 add_const_type(c, type_name, child_type);
1883}
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;
1713 add_global_var(c, type_name, type_node);
1714 c->global_type_table.put(type_name, type_node);
18941715}
18951716
1896static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
1717static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
18971718 auto existing_entry = c->decl_table.maybe_get((void*)enum_decl);
18981719 if (existing_entry) {
18991720 return existing_entry->value;
19001721 }
19011722
19021723 const char *raw_name = decl_name(enum_decl);
1903
1904 Buf *bare_name;
1905 if (raw_name[0] == 0) {
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));
1724 bool is_anonymous = (raw_name[0] == 0);
1725 Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
1726 Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name));
19121727
19131728 const EnumDecl *enum_def = enum_decl->getDefinition();
19141729 if (!enum_def) {
1915 TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base,
1916 ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern);
1917 enum_type->data.enumeration.zero_bits_known = true;
1918 enum_type->data.enumeration.abi_alignment = 1;
1919 c->enum_type_table.put(bare_name, enum_type);
1920 c->decl_table.put(enum_decl, enum_type);
1921 replace_with_fwd_decl(c, enum_type, full_type_name);
1922
1923 return enum_type;
1730 AstNode *opaque_node = trans_create_node_opaque(c);
1731 if (!is_anonymous) {
1732 c->enum_type_table.put(bare_name, opaque_node);
1733 add_global_weak_alias(c, bare_name, opaque_node);
1734 add_global_var(c, full_type_name, opaque_node);
1735 }
1736 c->decl_table.put(enum_decl, opaque_node);
1737 return opaque_node;
19241738 }
19251739
19261740 bool pure_enum = true;
......@@ -1935,25 +1749,16 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
19351749 }
19361750 }
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
19401755 if (pure_enum) {
1941 TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base,
1942 ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern);
1943 TypeTableEntry *tag_type_entry = create_enum_tag_type(c->codegen, enum_type, tag_int_type);
1944 c->enum_type_table.put(bare_name, enum_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);
1756 AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl);
1757 enum_node->data.container_decl.kind = ContainerKindEnum;
1758 enum_node->data.container_decl.layout = ContainerLayoutExtern;
1759 enum_node->data.container_decl.init_arg_expr = tag_int_type;
19561760
1761 enum_node->data.container_decl.fields.resize(field_count);
19571762 uint32_t i = 0;
19581763 for (auto it = enum_def->enumerator_begin(),
19591764 it_end = enum_def->enumerator_end();
......@@ -1963,92 +1768,63 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
19631768
19641769 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
19651770 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)) {
19671772 field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name));
19681773 } else {
19691774 field_name = enum_val_name;
19701775 }
19711776
1972 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
1973 type_enum_field->name = field_name;
1974 type_enum_field->type_entry = c->codegen->builtin_types.entry_void;
1975 type_enum_field->value = i;
1976
1977 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(c->codegen->dbuilder, buf_ptr(type_enum_field->name), i);
1978
1777 AstNode *field_node = trans_create_node(c, NodeTypeStructField);
1778 field_node->data.struct_field.name = field_name;
1779 field_node->data.struct_field.type = nullptr;
1780 enum_node->data.container_decl.fields.items[i] = field_node;
19791781
19801782 // in C each enum value is in the global namespace. so we put them there too.
19811783 // 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);
19831787 }
19841788
1985 // create llvm type for root struct
1986 enum_type->type_ref = tag_type_entry->type_ref;
1987
1988 enum_type->data.enumeration.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref,
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);
1789 if (!is_anonymous) {
1790 c->enum_type_table.put(bare_name, enum_node);
1791 add_global_weak_alias(c, bare_name, enum_node);
1792 add_global_var(c, full_type_name, enum_node);
20271793 }
1794 c->decl_table.put(enum_decl, enum_node);
20281795
2029 return enum_type;
1796 return enum_node;
20301797 }
2031}
20321798
2033static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
2034 TypeTableEntry *enum_type = resolve_enum_decl(c, enum_decl);
1799 // TODO after issue #305 is solved, make this be an enum with tag_int_type
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 the
2040 // end if it doesn't conflict with anything else
2041 bool is_anonymous = (decl_name(enum_decl)[0] == 0);
2042 if (is_anonymous)
2043 return;
1804 // add variables for all the values with enum_node
1805 for (auto it = enum_def->enumerator_begin(),
1806 it_end = enum_def->enumerator_end();
1807 it != it_end; ++it)
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);
2048 add_global_weak_alias(c, bare_name, tld);
1824 return enum_node;
20491825}
20501826
2051static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
1827static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
20521828 auto existing_entry = c->decl_table.maybe_get((void*)record_decl);
20531829 if (existing_entry) {
20541830 return existing_entry->value;
......@@ -2058,35 +1834,26 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
20581834
20591835 if (!record_decl->isStruct()) {
20601836 emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name);
2061 return c->codegen->builtin_types.entry_invalid;
2062 }
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);
1837 c->decl_table.put(record_decl, nullptr);
1838 return nullptr;
20691839 }
20701840
2071 Buf *full_type_name = buf_sprintf("struct_%s", buf_ptr(bare_name));
2072
2073
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);
1841 bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0;
1842 Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
1843 Buf *full_type_name = (bare_name == nullptr) ? nullptr : buf_sprintf("struct_%s", buf_ptr(bare_name));
20811844
20821845 RecordDecl *record_def = record_decl->getDefinition();
2083 unsigned line = c->source_node ? c->source_node->line : 0;
2084 if (!record_def) {
2085 replace_with_fwd_decl(c, struct_type, full_type_name);
2086 return struct_type;
1846 if (record_def == nullptr) {
1847 AstNode *opaque_node = trans_create_node_opaque(c);
1848 if (!is_anonymous) {
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;
20871855 }
20881856
2089
20901857 // count fields and validate
20911858 uint32_t field_count = 0;
20921859 for (auto it = record_def->field_begin(),
......@@ -2096,105 +1863,69 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
20961863 const FieldDecl *field_decl = *it;
20971864
20981865 if (field_decl->isBitField()) {
2099 emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield\n", buf_ptr(bare_name));
2100 replace_with_fwd_decl(c, struct_type, full_type_name);
2101 return struct_type;
1866 emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield",
1867 is_anonymous ? "(anon)" : buf_ptr(bare_name));
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;;
21021878 }
21031879 }
21041880
2105 struct_type->data.structure.src_field_count = field_count;
2106 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
2107 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
2108 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count);
1881 AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl);
1882 struct_node->data.container_decl.kind = ContainerKindStruct;
1883 struct_node->data.container_decl.layout = ContainerLayoutExtern;
21091884
2110 // next, populate element_types as its needed for LLVMStructSetBody which is needed for LLVMOffsetOfElement
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;
1885 // TODO handle attribute packed
21171886
2118 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
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 }
1887 struct_node->data.container_decl.fields.resize(field_count);
21301888
2131 element_types[i] = field_type->type_ref;
2132 assert(element_types[i]);
1889 // must be before fields in case a circular reference happens
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);
21331894 }
1895 c->decl_table.put(record_decl, struct_node);
21341896
2135 LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);
2136
2137 // finally populate debug info
2138 i = 0;
1897 uint32_t i = 0;
21391898 for (auto it = record_def->field_begin(),
21401899 it_end = record_def->field_end();
21411900 it != it_end; ++it, i += 1)
21421901 {
2143 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
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]);
1902 const FieldDecl *field_decl = *it;
21581903
2159 }
2160 struct_type->data.structure.embedded_in_current = false;
2161
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}
1904 AstNode *field_node = trans_create_node(c, NodeTypeStructField);
1905 field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl));
1906 field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), field_decl->getLocation());
21821907
2183static void visit_record_decl(Context *c, const RecordDecl *record_decl) {
2184 TypeTableEntry *struct_type = resolve_record_decl(c, record_decl);
1908 if (field_node->data.struct_field.type == nullptr) {
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) {
2187 return;
2188 }
1913 AstNode *opaque_node = trans_create_node_opaque(c);
1914 if (!is_anonymous) {
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);
2191 if (is_anonymous)
2192 return;
1921 return opaque_node;
1922 }
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);
2197 add_global_weak_alias(c, bare_name, tld);
1928 return struct_node;
21981929}
21991930
22001931static 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) {
22041935 case VarDecl::TLS_None:
22051936 break;
22061937 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));
22081940 return;
22091941 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));
22111944 return;
22121945 }
22131946
22141947 QualType qt = var_decl->getType();
2215 TypeTableEntry *var_type = resolve_qual_type(c, qt, var_decl);
2216 if (var_type->id == TypeTableEntryIdInvalid) {
2217 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type\n", buf_ptr(name));
1948 AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation());
1949 if (var_type == nullptr) {
1950 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name));
22181951 return;
22191952 }
22201953
......@@ -2223,59 +1956,53 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
22231956 bool is_const = qt.isConstQualified();
22241957
22251958 if (is_static && !is_extern) {
2226 if (!var_decl->hasInit()) {
2227 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - no initializer\n", buf_ptr(name));
2228 return;
2229 }
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:
1959 AstNode *init_node;
1960 if (var_decl->hasInit()) {
1961 APValue *ap_value = var_decl->evaluateValue();
1962 if (ap_value == nullptr) {
22611963 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));
22631965 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");
22641990 }
22651991
2266 TldVar *tld_var = create_global_var(c, name, init_value, true);
2267 add_global(c, &tld_var->base);
1992 AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, init_node);
1993 c->root->data.root.top_level_decls.append(var_node);
22681994 return;
22691995 }
22701996
22711997 if (is_extern) {
2272 TldVar *tld_var = create_global_var(c, name, create_const_runtime(var_type), is_const);
2273 tld_var->var->linkage = VarLinkageExternal;
2274 add_global(c, &tld_var->base);
1998 AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, nullptr);
1999 var_node->data.variable_declaration.is_extern = true;
2000 c->root->data.root.top_level_decls.append(var_node);
22752001 return;
22762002 }
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));
22792006 return;
22802007}
22812008
......@@ -2290,25 +2017,22 @@ static bool decl_visitor(void *context, const Decl *decl) {
22902017 visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl));
22912018 break;
22922019 case Decl::Enum:
2293 visit_enum_decl(c, static_cast<const EnumDecl *>(decl));
2020 resolve_enum_decl(c, static_cast<const EnumDecl *>(decl));
22942021 break;
22952022 case Decl::Record:
2296 visit_record_decl(c, static_cast<const RecordDecl *>(decl));
2023 resolve_record_decl(c, static_cast<const RecordDecl *>(decl));
22972024 break;
22982025 case Decl::Var:
22992026 visit_var_decl(c, static_cast<const VarDecl *>(decl));
23002027 break;
23012028 default:
2302 emit_warning(c, decl->getLocation(), "ignoring %s decl\n", decl->getDeclKindName());
2029 emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName());
23032030 }
23042031
23052032 return true;
23062033}
23072034
23082035static bool name_exists(Context *c, Buf *name) {
2309 if (c->global_type_table.maybe_get(name)) {
2310 return true;
2311 }
23122036 if (get_global(c, name)) {
23132037 return true;
23142038 }
......@@ -2324,7 +2048,7 @@ static void render_aliases(Context *c) {
23242048 if (name_exists(c, alias->name))
23252049 continue;
23262050
2327 add_global_alias(c, alias->name, alias->tld);
2051 add_global_var(c, alias->name, alias->node);
23282052 }
23292053}
23302054
......@@ -2335,8 +2059,7 @@ static void render_macros(Context *c) {
23352059 if (!entry)
23362060 break;
23372061
2338 Tld *var_tld = entry->value;
2339 add_global(c, var_tld);
2062 add_global_var(c, entry->key, entry->value);
23402063 }
23412064}
23422065
......@@ -2355,52 +2078,52 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch
23552078 switch (tok->id) {
23562079 case CTokIdCharLit:
23572080 if (is_last && is_first) {
2358 Tld *tld = create_global_num_lit_unsigned_negative(c, name, tok->data.char_lit, false);
2359 c->macro_table.put(name, tld);
2081 AstNode *node = trans_create_node_unsigned(c, tok->data.char_lit);
2082 c->macro_table.put(name, node);
23602083 }
23612084 return;
23622085 case CTokIdStrLit:
23632086 if (is_last && is_first) {
2364 Tld *tld = create_global_str_lit_var(c, name, buf_create_from_buf(&tok->data.str_lit));
2365 c->macro_table.put(name, tld);
2087 AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit));
2088 c->macro_table.put(name, node);
23662089 }
23672090 return;
23682091 case CTokIdNumLitInt:
23692092 if (is_last) {
2370 Tld *tld;
2093 AstNode *node;
23712094 switch (tok->data.num_lit_int.suffix) {
23722095 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);
23742097 break;
23752098 case CNumLitSuffixL:
2376 tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,
2377 c->codegen->builtin_types.entry_c_int[CIntTypeLong]);
2099 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2100 "c_long");
23782101 break;
23792102 case CNumLitSuffixU:
2380 tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,
2381 c->codegen->builtin_types.entry_c_int[CIntTypeUInt]);
2103 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2104 "c_uint");
23822105 break;
23832106 case CNumLitSuffixLU:
2384 tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,
2385 c->codegen->builtin_types.entry_c_int[CIntTypeULong]);
2107 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2108 "c_ulong");
23862109 break;
23872110 case CNumLitSuffixLL:
2388 tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,
2389 c->codegen->builtin_types.entry_c_int[CIntTypeLongLong]);
2111 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2112 "c_longlong");
23902113 break;
23912114 case CNumLitSuffixLLU:
2392 tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate,
2393 c->codegen->builtin_types.entry_c_int[CIntTypeULongLong]);
2115 node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate,
2116 "c_ulonglong");
23942117 break;
23952118 }
2396 c->macro_table.put(name, tld);
2119 c->macro_table.put(name, node);
23972120 }
23982121 return;
23992122 case CTokIdNumLitFloat:
24002123 if (is_last) {
24012124 double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float;
2402 Tld *tld = create_global_num_lit_float(c, name, value);
2403 c->macro_table.put(name, tld);
2125 AstNode *node = trans_create_node_float_lit(c, value);
2126 c->macro_table.put(name, node);
24042127 }
24052128 return;
24062129 case CTokIdSymbol:
......@@ -2429,29 +2152,29 @@ static void process_symbol_macros(Context *c) {
24292152 for (size_t i = 0; i < c->macro_symbols.length; i += 1) {
24302153 MacroSymbol ms = c->macro_symbols.at(i);
24312154
2432 // If this macro aliases another top level declaration, we can make that happen by
2433 // putting another entry in the decl table pointing to the same top level decl.
2434 Tld *existing_tld = get_global(c, ms.value);
2435 if (!existing_tld)
2155 // Check if this macro aliases another top level declaration
2156 AstNode *existing_node = get_global(c, ms.value);
2157 if (!existing_node || name_exists(c, ms.name))
24362158 continue;
24372159
24382160 // If a macro aliases a global variable which is a function pointer, we conclude that
24392161 // the macro is intended to represent a function that assumes the function pointer
24402162 // variable is non-null and calls it.
2441 if (existing_tld->id == TldIdVar) {
2442 TldVar *tld_var = (TldVar *)existing_tld;
2443 TypeTableEntry *var_type = tld_var->var->value->type;
2444 if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) {
2445 TypeTableEntry *child_type = var_type->data.maybe.child_type;
2446 if (child_type->id == TypeTableEntryIdFn) {
2447 Tld *tld = create_inline_fn_tld(c, ms.name, tld_var);
2448 c->macro_table.put(ms.name, tld);
2163 if (existing_node->type == NodeTypeVariableDeclaration) {
2164 AstNode *var_expr = existing_node->data.variable_declaration.expr;
2165 if (var_expr != nullptr && var_expr->type == NodeTypePrefixOpExpr &&
2166 var_expr->data.prefix_op_expr.prefix_op == PrefixOpMaybe)
2167 {
2168 AstNode *fn_proto_node = var_expr->data.prefix_op_expr.primary_expr;
2169 if (fn_proto_node->type == NodeTypeFnProto) {
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);
24492172 continue;
24502173 }
24512174 }
24522175 }
24532176
2454 add_global_alias(c, ms.name, existing_tld);
2177 add_global_var(c, ms.name, existing_node);
24552178 }
24562179}
24572180
......@@ -2651,15 +2374,17 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
26512374
26522375 c->ctx = &ast_unit->getASTContext();
26532376 c->source_manager = &ast_unit->getSourceManager();
2377 c->root = trans_create_node(c, NodeTypeRoot);
26542378
26552379 ast_unit->visitLocalTopLevelDecls(c, decl_visitor);
26562380
26572381 process_preprocessor_entities(c, *ast_unit);
26582382
2659 process_symbol_macros(c);
2660
26612383 render_macros(c);
2384 process_symbol_macros(c);
26622385 render_aliases(c);
26632386
2387 import->root = c->root;
2388
26642389 return 0;
26652390}
test/parseh.zig+14-4
......@@ -21,6 +21,16 @@ pub fn addCases(cases: &tests.ParseHContext) {
2121 \\pub extern fn foo() -> noreturn;
2222 );
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
2434 cases.add("enums",
2535 \\enum Foo {
2636 \\ FooA,
......@@ -34,13 +44,13 @@ pub fn addCases(cases: &tests.ParseHContext) {
3444 \\ @"1",
3545 \\};
3646 ,
37 \\pub const FooA = 0;
47 \\pub const FooA = Foo.A;
3848 ,
39 \\pub const FooB = 1;
49 \\pub const FooB = Foo.B;
4050 ,
41 \\pub const Foo1 = 2;
51 \\pub const Foo1 = Foo.1;
4252 ,
43 \\pub const Foo = enum_Foo
53 \\pub const Foo = enum_Foo;
4454 );
4555
4656 cases.add("restrict -> noalias",