| ... | @@ -15,8 +15,10 @@ | ... | @@ -15,8 +15,10 @@ |
| 15 | #include "parseh.hpp" | 15 | #include "parseh.hpp" |
| 16 | #include "parser.hpp" | 16 | #include "parser.hpp" |
| 17 | | 17 | |
| | 18 | |
| 18 | #include <clang/Frontend/ASTUnit.h> | 19 | #include <clang/Frontend/ASTUnit.h> |
| 19 | #include <clang/Frontend/CompilerInstance.h> | 20 | #include <clang/Frontend/CompilerInstance.h> |
| | 21 | #include <clang/AST/Expr.h> |
| 20 | | 22 | |
| 21 | #include <string.h> | 23 | #include <string.h> |
| 22 | | 24 | |
| ... | @@ -27,14 +29,9 @@ struct MacroSymbol { | ... | @@ -27,14 +29,9 @@ struct MacroSymbol { |
| 27 | Buf *value; | 29 | Buf *value; |
| 28 | }; | 30 | }; |
| 29 | | 31 | |
| 30 | struct GlobalValue { | | |
| 31 | TypeTableEntry *type; | | |
| 32 | bool is_const; | | |
| 33 | }; | | |
| 34 | | | |
| 35 | struct Alias { | 32 | struct Alias { |
| 36 | Buf *name; | 33 | Buf *new_name; |
| 37 | Tld *tld; | 34 | Buf *canon_name; |
| 38 | }; | 35 | }; |
| 39 | | 36 | |
| 40 | struct Context { | 37 | struct Context { |
| ... | @@ -42,30 +39,27 @@ struct Context { | ... | @@ -42,30 +39,27 @@ struct Context { |
| 42 | ZigList<ErrorMsg *> *errors; | 39 | ZigList<ErrorMsg *> *errors; |
| 43 | bool warnings_on; | 40 | bool warnings_on; |
| 44 | VisibMod visib_mod; | 41 | VisibMod visib_mod; |
| 45 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> global_type_table; | 42 | AstNode *root; |
| 46 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table; | 43 | HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table; |
| 47 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table; | 44 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; |
| 48 | HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table; | | |
| 49 | HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> macro_table; | | |
| 50 | SourceManager *source_manager; | 45 | SourceManager *source_manager; |
| 51 | ZigList<Alias> aliases; | 46 | ZigList<Alias> aliases; |
| 52 | ZigList<MacroSymbol> macro_symbols; | 47 | ZigList<MacroSymbol> macro_symbols; |
| 53 | AstNode *source_node; | 48 | AstNode *source_node; |
| 54 | uint32_t next_anon_index; | | |
| 55 | | 49 | |
| 56 | CodeGen *codegen; | 50 | CodeGen *codegen; |
| | 51 | ASTContext *ctx; |
| 57 | }; | 52 | }; |
| 58 | | 53 | |
| 59 | static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl, | 54 | static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl); |
| 60 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table); | 55 | static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); |
| 61 | | 56 | static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl); |
| 62 | static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl); | 57 | static AstNode *trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc); |
| 63 | static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl); | 58 | static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc); |
| 64 | static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); | | |
| 65 | | 59 | |
| 66 | | 60 | |
| 67 | __attribute__ ((format (printf, 3, 4))) | 61 | __attribute__ ((format (printf, 3, 4))) |
| 68 | static void emit_warning(Context *c, const Decl *decl, const char *format, ...) { | 62 | static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) { |
| 69 | if (!c->warnings_on) { | 63 | if (!c->warnings_on) { |
| 70 | return; | 64 | return; |
| 71 | } | 65 | } |
| ... | @@ -75,8 +69,6 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...) | ... | @@ -75,8 +69,6 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...) |
| 75 | Buf *msg = buf_vprintf(format, ap); | 69 | Buf *msg = buf_vprintf(format, ap); |
| 76 | va_end(ap); | 70 | va_end(ap); |
| 77 | | 71 | |
| 78 | SourceLocation sl = decl->getLocation(); | | |
| 79 | | | |
| 80 | StringRef filename = c->source_manager->getFilename(sl); | 72 | StringRef filename = c->source_manager->getFilename(sl); |
| 81 | const char *filename_bytes = (const char *)filename.bytes_begin(); | 73 | const char *filename_bytes = (const char *)filename.bytes_begin(); |
| 82 | Buf *path; | 74 | Buf *path; |
| ... | @@ -90,141 +82,214 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...) | ... | @@ -90,141 +82,214 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...) |
| 90 | fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg)); | 82 | fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg)); |
| 91 | } | 83 | } |
| 92 | | 84 | |
| 93 | static uint32_t get_next_anon_index(Context *c) { | 85 | static void add_global_weak_alias(Context *c, Buf *new_name, Buf *canon_name) { |
| 94 | uint32_t result = c->next_anon_index; | 86 | Alias *alias = c->aliases.add_one(); |
| 95 | c->next_anon_index += 1; | 87 | alias->new_name = new_name; |
| 96 | return result; | 88 | alias->canon_name = canon_name; |
| 97 | } | 89 | } |
| 98 | | 90 | |
| 99 | static void add_global_alias(Context *c, Buf *name, Tld *tld) { | 91 | static AstNode * trans_create_node(Context *c, NodeType id) { |
| 100 | c->import->decls_scope->decl_table.put(name, tld); | 92 | AstNode *node = allocate<AstNode>(1); |
| | 93 | node->type = id; |
| | 94 | node->owner = c->import; |
| | 95 | // TODO line/column. mapping to C file?? |
| | 96 | return node; |
| 101 | } | 97 | } |
| 102 | | 98 | |
| 103 | static void add_global_weak_alias(Context *c, Buf *name, Tld *tld) { | 99 | static AstNode *trans_create_node_float_lit(Context *c, double value) { |
| 104 | Alias *alias = c->aliases.add_one(); | 100 | AstNode *node = trans_create_node(c, NodeTypeFloatLiteral); |
| 105 | alias->name = name; | 101 | node->data.float_literal.bigfloat = allocate<BigFloat>(1); |
| 106 | alias->tld = tld; | 102 | bigfloat_init_64(node->data.float_literal.bigfloat, value); |
| | 103 | return node; |
| 107 | } | 104 | } |
| 108 | | 105 | |
| 109 | static void add_global(Context *c, Tld *tld) { | 106 | static AstNode *trans_create_node_symbol(Context *c, Buf *name) { |
| 110 | return add_global_alias(c, tld->name, tld); | 107 | AstNode *node = trans_create_node(c, NodeTypeSymbol); |
| | 108 | node->data.symbol_expr.symbol = name; |
| | 109 | return node; |
| 111 | } | 110 | } |
| 112 | | 111 | |
| 113 | static Tld *get_global(Context *c, Buf *name) { | 112 | static AstNode *trans_create_node_symbol_str(Context *c, const char *name) { |
| 114 | { | 113 | return trans_create_node_symbol(c, buf_create_from_str(name)); |
| 115 | auto entry = c->import->decls_scope->decl_table.maybe_get(name); | | |
| 116 | if (entry) | | |
| 117 | return entry->value; | | |
| 118 | } | | |
| 119 | { | | |
| 120 | auto entry = c->macro_table.maybe_get(name); | | |
| 121 | if (entry) | | |
| 122 | return entry->value; | | |
| 123 | } | | |
| 124 | return nullptr; | | |
| 125 | } | 114 | } |
| 126 | | 115 | |
| 127 | static const char *decl_name(const Decl *decl) { | 116 | static AstNode *trans_create_node_builtin_fn_call(Context *c, Buf *name) { |
| 128 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); | 117 | AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); |
| 129 | return (const char *)named_decl->getName().bytes_begin(); | 118 | node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, name); |
| | 119 | node->data.fn_call_expr.is_builtin = true; |
| | 120 | return node; |
| 130 | } | 121 | } |
| 131 | | 122 | |
| 132 | static void parseh_init_tld(Context *c, Tld *tld, TldId id, Buf *name) { | 123 | static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *name) { |
| 133 | init_tld(tld, id, name, c->visib_mod, c->source_node, &c->import->decls_scope->base); | 124 | return trans_create_node_builtin_fn_call(c, buf_create_from_str(name)); |
| 134 | tld->resolution = TldResolutionOk; | | |
| 135 | tld->import = c->import; | | |
| 136 | } | 125 | } |
| 137 | | 126 | |
| 138 | static Tld *create_inline_fn_tld(Context *c, Buf *fn_name, TldVar *tld_var) { | 127 | static AstNode *trans_create_node_opaque(Context *c) { |
| 139 | TldFn *tld_fn = allocate<TldFn>(1); | 128 | return trans_create_node_builtin_fn_call_str(c, "OpaqueType"); |
| 140 | parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name); | | |
| 141 | tld_fn->fn_entry = ir_create_inline_fn(c->codegen, fn_name, tld_var->var, &c->import->decls_scope->base); | | |
| 142 | return &tld_fn->base; | | |
| 143 | } | 129 | } |
| 144 | | 130 | |
| 145 | static TldVar *create_global_var(Context *c, Buf *name, ConstExprValue *var_value, bool is_const) { | 131 | static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) { |
| 146 | auto entry = c->import->decls_scope->decl_table.maybe_get(name); | 132 | AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr); |
| 147 | if (entry) { | 133 | node->data.field_access_expr.struct_expr = container; |
| 148 | Tld *existing_tld = entry->value; | 134 | node->data.field_access_expr.field_name = field_name; |
| 149 | assert(existing_tld->id == TldIdVar); | 135 | return node; |
| 150 | return (TldVar *)existing_tld; | | |
| 151 | } | | |
| 152 | TldVar *tld_var = allocate<TldVar>(1); | | |
| 153 | parseh_init_tld(c, &tld_var->base, TldIdVar, name); | | |
| 154 | tld_var->var = add_variable(c->codegen, c->source_node, &c->import->decls_scope->base, | | |
| 155 | name, is_const, var_value, &tld_var->base); | | |
| 156 | c->codegen->global_vars.append(tld_var); | | |
| 157 | return tld_var; | | |
| 158 | } | 136 | } |
| 159 | | 137 | |
| 160 | static Tld *create_global_str_lit_var(Context *c, Buf *name, Buf *value) { | 138 | static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) { |
| 161 | TldVar *tld_var = create_global_var(c, name, create_const_c_str_lit(c->codegen, value), true); | 139 | AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr); |
| 162 | return &tld_var->base; | 140 | node->data.prefix_op_expr.prefix_op = op; |
| | 141 | node->data.prefix_op_expr.primary_expr = child_node; |
| | 142 | return node; |
| 163 | } | 143 | } |
| 164 | | 144 | |
| 165 | static Tld *create_global_num_lit_unsigned_negative_type(Context *c, Buf *name, uint64_t x, bool negative, TypeTableEntry *type_entry) { | 145 | static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) { |
| 166 | ConstExprValue *var_val = create_const_unsigned_negative(type_entry, x, negative); | 146 | AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr); |
| 167 | TldVar *tld_var = create_global_var(c, name, var_val, true); | 147 | node->data.addr_of_expr.is_const = is_const; |
| 168 | return &tld_var->base; | 148 | node->data.addr_of_expr.is_volatile = is_volatile; |
| | 149 | node->data.addr_of_expr.op_expr = child_node; |
| | 150 | return node; |
| 169 | } | 151 | } |
| 170 | | 152 | |
| 171 | static Tld *create_global_num_lit_unsigned_negative(Context *c, Buf *name, uint64_t x, bool negative) { | 153 | static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) { |
| 172 | return create_global_num_lit_unsigned_negative_type(c, name, x, negative, c->codegen->builtin_types.entry_num_lit_int); | 154 | AstNode *node = trans_create_node(c, NodeTypeStringLiteral); |
| | 155 | node->data.string_literal.buf = buf; |
| | 156 | node->data.string_literal.c = true; |
| | 157 | return node; |
| 173 | } | 158 | } |
| 174 | | 159 | |
| 175 | static Tld *create_global_num_lit_float(Context *c, Buf *name, double value) { | 160 | static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) { |
| 176 | ConstExprValue *var_val = create_const_float(c->codegen->builtin_types.entry_num_lit_float, value); | 161 | AstNode *node = trans_create_node(c, NodeTypeIntLiteral); |
| 177 | TldVar *tld_var = create_global_var(c, name, var_val, true); | 162 | node->data.int_literal.bigint = allocate<BigInt>(1); |
| 178 | return &tld_var->base; | 163 | bigint_init_data(node->data.int_literal.bigint, &x, 1, is_negative); |
| | 164 | return node; |
| 179 | } | 165 | } |
| 180 | | 166 | |
| 181 | static ConstExprValue *create_const_int_ap(Context *c, TypeTableEntry *type, const Decl *source_decl, | 167 | static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) { |
| 182 | const llvm::APSInt &aps_int) | 168 | return trans_create_node_unsigned_negative(c, x, false); |
| | 169 | } |
| | 170 | |
| | 171 | static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) { |
| | 172 | AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); |
| | 173 | node->data.fn_call_expr.fn_ref_expr = dest; |
| | 174 | node->data.fn_call_expr.params.resize(1); |
| | 175 | node->data.fn_call_expr.params.items[0] = src; |
| | 176 | return node; |
| | 177 | } |
| | 178 | |
| | 179 | static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative, |
| | 180 | const char *type_name) |
| 183 | { | 181 | { |
| 184 | if (aps_int.isSigned()) { | 182 | AstNode *lit_node = trans_create_node_unsigned_negative(c, x, is_negative); |
| 185 | if (aps_int > INT64_MAX || aps_int < INT64_MIN) { | 183 | return trans_create_node_cast(c, trans_create_node_symbol_str(c, type_name), lit_node); |
| 186 | emit_warning(c, source_decl, "integer overflow\n"); | | |
| 187 | return nullptr; | | |
| 188 | } else { | | |
| 189 | return create_const_signed(type, aps_int.getExtValue()); | | |
| 190 | } | | |
| 191 | } else { | | |
| 192 | if (aps_int > INT64_MAX) { | | |
| 193 | emit_warning(c, source_decl, "integer overflow\n"); | | |
| 194 | return nullptr; | | |
| 195 | } else { | | |
| 196 | return create_const_unsigned_negative(type, aps_int.getExtValue(), false); | | |
| 197 | } | | |
| 198 | } | | |
| 199 | } | 184 | } |
| 200 | | 185 | |
| 201 | static Tld *create_global_num_lit_ap(Context *c, const Decl *source_decl, Buf *name, | 186 | static AstNode *trans_create_node_array_type(Context *c, AstNode *size_node, AstNode *child_type_node) { |
| 202 | const llvm::APSInt &aps_int) | 187 | AstNode *node = trans_create_node(c, NodeTypeArrayType); |
| | 188 | node->data.array_type.size = size_node; |
| | 189 | node->data.array_type.child_type = child_type_node; |
| | 190 | return node; |
| | 191 | } |
| | 192 | |
| | 193 | static AstNode *trans_create_node_var_decl(Context *c, bool is_const, Buf *var_name, AstNode *type_node, |
| | 194 | AstNode *init_node) |
| 203 | { | 195 | { |
| 204 | ConstExprValue *const_value = create_const_int_ap(c, c->codegen->builtin_types.entry_num_lit_int, | 196 | AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration); |
| 205 | source_decl, aps_int); | 197 | node->data.variable_declaration.visib_mod = c->visib_mod; |
| 206 | if (!const_value) | 198 | node->data.variable_declaration.symbol = var_name; |
| 207 | return nullptr; | 199 | node->data.variable_declaration.is_const = is_const; |
| 208 | TldVar *tld_var = create_global_var(c, name, const_value, true); | 200 | node->data.variable_declaration.type = type_node; |
| 209 | return &tld_var->base; | 201 | node->data.variable_declaration.expr = init_node; |
| | 202 | return node; |
| 210 | } | 203 | } |
| 211 | | 204 | |
| 212 | | 205 | |
| 213 | static Tld *add_const_type(Context *c, Buf *name, TypeTableEntry *type_entry) { | 206 | static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_name, AstNode *src_proto_node) { |
| 214 | ConstExprValue *var_value = create_const_type(c->codegen, type_entry); | 207 | AstNode *fn_def = trans_create_node(c, NodeTypeFnDef); |
| 215 | TldVar *tld_var = create_global_var(c, name, var_value, true); | 208 | AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto); |
| 216 | add_global(c, &tld_var->base); | 209 | fn_proto->data.fn_proto.visib_mod = c->visib_mod; |
| | 210 | fn_proto->data.fn_proto.name = fn_name; |
| | 211 | fn_proto->data.fn_proto.is_inline = true; |
| | 212 | fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias? |
| | 213 | |
| | 214 | fn_def->data.fn_def.fn_proto = fn_proto; |
| | 215 | fn_proto->data.fn_proto.fn_def_node = fn_def; |
| | 216 | |
| | 217 | AstNode *unwrap_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, trans_create_node_symbol(c, var_name)); |
| | 218 | AstNode *fn_call_node = trans_create_node(c, NodeTypeFnCallExpr); |
| | 219 | fn_call_node->data.fn_call_expr.fn_ref_expr = unwrap_node; |
| | 220 | |
| | 221 | for (size_t i = 0; i < src_proto_node->data.fn_proto.params.length; i += 1) { |
| | 222 | AstNode *src_param_node = src_proto_node->data.fn_proto.params.at(i); |
| | 223 | Buf *param_name = src_param_node->data.param_decl.name; |
| | 224 | if (!param_name) param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i); |
| | 225 | |
| | 226 | AstNode *dest_param_node = trans_create_node(c, NodeTypeParamDecl); |
| | 227 | dest_param_node->data.param_decl.name = param_name; |
| | 228 | dest_param_node->data.param_decl.type = src_param_node->data.param_decl.type; |
| | 229 | dest_param_node->data.param_decl.is_noalias = src_param_node->data.param_decl.is_noalias; |
| | 230 | fn_proto->data.fn_proto.params.append(dest_param_node); |
| | 231 | |
| | 232 | fn_call_node->data.fn_call_expr.params.append(trans_create_node_symbol(c, param_name)); |
| | 233 | |
| | 234 | } |
| | 235 | |
| | 236 | AstNode *block = trans_create_node(c, NodeTypeBlock); |
| | 237 | block->data.block.statements.resize(1); |
| | 238 | block->data.block.statements.items[0] = fn_call_node; |
| | 239 | block->data.block.last_statement_is_result_expression = true; |
| | 240 | |
| | 241 | fn_def->data.fn_def.body = block; |
| | 242 | return fn_def; |
| | 243 | } |
| | 244 | |
| | 245 | static AstNode *get_global(Context *c, Buf *name) { |
| | 246 | for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) { |
| | 247 | AstNode *decl_node = c->root->data.root.top_level_decls.items[i]; |
| | 248 | if (decl_node->type == NodeTypeVariableDeclaration) { |
| | 249 | if (buf_eql_buf(decl_node->data.variable_declaration.symbol, name)) { |
| | 250 | return decl_node; |
| | 251 | } |
| | 252 | } else if (decl_node->type == NodeTypeFnDef) { |
| | 253 | if (buf_eql_buf(decl_node->data.fn_def.fn_proto->data.fn_proto.name, name)) { |
| | 254 | return decl_node; |
| | 255 | } |
| | 256 | } else if (decl_node->type == NodeTypeFnProto) { |
| | 257 | if (buf_eql_buf(decl_node->data.fn_proto.name, name)) { |
| | 258 | return decl_node; |
| | 259 | } |
| | 260 | } |
| | 261 | } |
| | 262 | { |
| | 263 | auto entry = c->macro_table.maybe_get(name); |
| | 264 | if (entry) |
| | 265 | return entry->value; |
| | 266 | } |
| | 267 | return nullptr; |
| | 268 | } |
| | 269 | |
| | 270 | static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) { |
| | 271 | bool is_const = true; |
| | 272 | AstNode *type_node = nullptr; |
| | 273 | AstNode *node = trans_create_node_var_decl(c, is_const, var_name, type_node, value_node); |
| | 274 | c->root->data.root.top_level_decls.append(node); |
| | 275 | return node; |
| | 276 | } |
| 217 | | 277 | |
| 218 | c->global_type_table.put(name, type_entry); | 278 | static const char *decl_name(const Decl *decl) { |
| 219 | return &tld_var->base; | 279 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); |
| | 280 | return (const char *)named_decl->getName().bytes_begin(); |
| 220 | } | 281 | } |
| 221 | | 282 | |
| 222 | static Tld *add_container_tld(Context *c, TypeTableEntry *type_entry) { | 283 | static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) { |
| 223 | return add_const_type(c, &type_entry->name, type_entry); | 284 | AstNode *node = trans_create_node(c, NodeTypeIntLiteral); |
| | 285 | node->data.int_literal.bigint = allocate<BigInt>(1); |
| | 286 | bigint_init_data(node->data.int_literal.bigint, aps_int.getRawData(), aps_int.getNumWords(), aps_int.isNegative()); |
| | 287 | return node; |
| | 288 | |
| 224 | } | 289 | } |
| 225 | | 290 | |
| 226 | static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) { | 291 | static bool is_c_void_type(AstNode *node) { |
| 227 | return (type_entry == c->codegen->builtin_types.entry_c_void); | 292 | return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void")); |
| 228 | } | 293 | } |
| 229 | | 294 | |
| 230 | static bool qual_type_child_is_fn_proto(const QualType &qt) { | 295 | static bool qual_type_child_is_fn_proto(const QualType &qt) { |
| ... | @@ -240,52 +305,118 @@ static bool qual_type_child_is_fn_proto(const QualType &qt) { | ... | @@ -240,52 +305,118 @@ static bool qual_type_child_is_fn_proto(const QualType &qt) { |
| 240 | return false; | 305 | return false; |
| 241 | } | 306 | } |
| 242 | | 307 | |
| 243 | static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl, | 308 | static bool c_is_signed_integer(Context *c, QualType qt) { |
| 244 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table) | 309 | const Type *c_type = qt.getTypePtr(); |
| 245 | { | 310 | if (c_type->getTypeClass() != Type::Builtin) |
| | 311 | return false; |
| | 312 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type); |
| | 313 | switch (builtin_ty->getKind()) { |
| | 314 | case BuiltinType::SChar: |
| | 315 | case BuiltinType::Short: |
| | 316 | case BuiltinType::Int: |
| | 317 | case BuiltinType::Long: |
| | 318 | case BuiltinType::LongLong: |
| | 319 | case BuiltinType::Int128: |
| | 320 | case BuiltinType::WChar_S: |
| | 321 | return true; |
| | 322 | default: |
| | 323 | return false; |
| | 324 | } |
| | 325 | } |
| | 326 | |
| | 327 | static bool c_is_unsigned_integer(Context *c, QualType qt) { |
| | 328 | const Type *c_type = qt.getTypePtr(); |
| | 329 | if (c_type->getTypeClass() != Type::Builtin) |
| | 330 | return false; |
| | 331 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type); |
| | 332 | switch (builtin_ty->getKind()) { |
| | 333 | case BuiltinType::Char_U: |
| | 334 | case BuiltinType::UChar: |
| | 335 | case BuiltinType::Char_S: |
| | 336 | case BuiltinType::UShort: |
| | 337 | case BuiltinType::UInt: |
| | 338 | case BuiltinType::ULong: |
| | 339 | case BuiltinType::ULongLong: |
| | 340 | case BuiltinType::UInt128: |
| | 341 | case BuiltinType::WChar_U: |
| | 342 | return true; |
| | 343 | default: |
| | 344 | return false; |
| | 345 | } |
| | 346 | } |
| | 347 | |
| | 348 | static bool c_is_float(Context *c, QualType qt) { |
| | 349 | const Type *c_type = qt.getTypePtr(); |
| | 350 | if (c_type->getTypeClass() != Type::Builtin) |
| | 351 | return false; |
| | 352 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type); |
| | 353 | switch (builtin_ty->getKind()) { |
| | 354 | case BuiltinType::Half: |
| | 355 | case BuiltinType::Float: |
| | 356 | case BuiltinType::Double: |
| | 357 | case BuiltinType::Float128: |
| | 358 | case BuiltinType::LongDouble: |
| | 359 | return true; |
| | 360 | default: |
| | 361 | return false; |
| | 362 | } |
| | 363 | } |
| | 364 | |
| | 365 | static AstNode * trans_stmt(Context *c, AstNode *block, Stmt *stmt); |
| | 366 | static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc); |
| | 367 | |
| | 368 | static AstNode * trans_expr(Context *c, AstNode *block, Expr *expr) { |
| | 369 | return trans_stmt(c, block, expr); |
| | 370 | } |
| | 371 | |
| | 372 | static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLocation &source_loc) { |
| 246 | switch (ty->getTypeClass()) { | 373 | switch (ty->getTypeClass()) { |
| 247 | case Type::Builtin: | 374 | case Type::Builtin: |
| 248 | { | 375 | { |
| 249 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); | 376 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); |
| 250 | switch (builtin_ty->getKind()) { | 377 | switch (builtin_ty->getKind()) { |
| 251 | case BuiltinType::Void: | 378 | case BuiltinType::Void: |
| 252 | return c->codegen->builtin_types.entry_c_void; | 379 | return trans_create_node_symbol_str(c, "c_void"); |
| 253 | case BuiltinType::Bool: | 380 | case BuiltinType::Bool: |
| 254 | return c->codegen->builtin_types.entry_bool; | 381 | return trans_create_node_symbol_str(c, "bool"); |
| 255 | case BuiltinType::Char_U: | 382 | case BuiltinType::Char_U: |
| 256 | case BuiltinType::UChar: | 383 | case BuiltinType::UChar: |
| 257 | case BuiltinType::Char_S: | 384 | case BuiltinType::Char_S: |
| 258 | return c->codegen->builtin_types.entry_u8; | 385 | return trans_create_node_symbol_str(c, "u8"); |
| 259 | case BuiltinType::SChar: | 386 | case BuiltinType::SChar: |
| 260 | return c->codegen->builtin_types.entry_i8; | 387 | return trans_create_node_symbol_str(c, "i8"); |
| 261 | case BuiltinType::UShort: | 388 | case BuiltinType::UShort: |
| 262 | return get_c_int_type(c->codegen, CIntTypeUShort); | 389 | return trans_create_node_symbol_str(c, "c_ushort"); |
| 263 | case BuiltinType::UInt: | 390 | case BuiltinType::UInt: |
| 264 | return get_c_int_type(c->codegen, CIntTypeUInt); | 391 | return trans_create_node_symbol_str(c, "c_uint"); |
| 265 | case BuiltinType::ULong: | 392 | case BuiltinType::ULong: |
| 266 | return get_c_int_type(c->codegen, CIntTypeULong); | 393 | return trans_create_node_symbol_str(c, "c_ulong"); |
| 267 | case BuiltinType::ULongLong: | 394 | case BuiltinType::ULongLong: |
| 268 | return get_c_int_type(c->codegen, CIntTypeULongLong); | 395 | return trans_create_node_symbol_str(c, "c_ulonglong"); |
| 269 | case BuiltinType::Short: | 396 | case BuiltinType::Short: |
| 270 | return get_c_int_type(c->codegen, CIntTypeShort); | 397 | return trans_create_node_symbol_str(c, "c_short"); |
| 271 | case BuiltinType::Int: | 398 | case BuiltinType::Int: |
| 272 | return get_c_int_type(c->codegen, CIntTypeInt); | 399 | return trans_create_node_symbol_str(c, "c_int"); |
| 273 | case BuiltinType::Long: | 400 | case BuiltinType::Long: |
| 274 | return get_c_int_type(c->codegen, CIntTypeLong); | 401 | return trans_create_node_symbol_str(c, "c_long"); |
| 275 | case BuiltinType::LongLong: | 402 | case BuiltinType::LongLong: |
| 276 | return get_c_int_type(c->codegen, CIntTypeLongLong); | 403 | return trans_create_node_symbol_str(c, "c_longlong"); |
| | 404 | case BuiltinType::UInt128: |
| | 405 | return trans_create_node_symbol_str(c, "u128"); |
| | 406 | case BuiltinType::Int128: |
| | 407 | return trans_create_node_symbol_str(c, "i128"); |
| 277 | case BuiltinType::Float: | 408 | case BuiltinType::Float: |
| 278 | return c->codegen->builtin_types.entry_f32; | 409 | return trans_create_node_symbol_str(c, "f32"); |
| 279 | case BuiltinType::Double: | 410 | case BuiltinType::Double: |
| 280 | return c->codegen->builtin_types.entry_f64; | 411 | return trans_create_node_symbol_str(c, "f64"); |
| | 412 | case BuiltinType::Float128: |
| | 413 | return trans_create_node_symbol_str(c, "f128"); |
| 281 | case BuiltinType::LongDouble: | 414 | case BuiltinType::LongDouble: |
| 282 | return c->codegen->builtin_types.entry_c_longdouble; | 415 | return trans_create_node_symbol_str(c, "c_longdouble"); |
| 283 | case BuiltinType::WChar_U: | 416 | case BuiltinType::WChar_U: |
| 284 | case BuiltinType::Char16: | 417 | case BuiltinType::Char16: |
| 285 | case BuiltinType::Char32: | 418 | case BuiltinType::Char32: |
| 286 | case BuiltinType::UInt128: | | |
| 287 | case BuiltinType::WChar_S: | 419 | case BuiltinType::WChar_S: |
| 288 | case BuiltinType::Int128: | | |
| 289 | case BuiltinType::Half: | 420 | case BuiltinType::Half: |
| 290 | case BuiltinType::NullPtr: | 421 | case BuiltinType::NullPtr: |
| 291 | case BuiltinType::ObjCId: | 422 | case BuiltinType::ObjCId: |
| ... | @@ -336,14 +467,13 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const | ... | @@ -336,14 +467,13 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 336 | case BuiltinType::OCLImage2dMSAADepthRW: | 467 | case BuiltinType::OCLImage2dMSAADepthRW: |
| 337 | case BuiltinType::OCLImage2dArrayMSAADepthRW: | 468 | case BuiltinType::OCLImage2dArrayMSAADepthRW: |
| 338 | case BuiltinType::OCLImage3dRW: | 469 | case BuiltinType::OCLImage3dRW: |
| 339 | case BuiltinType::Float128: | | |
| 340 | case BuiltinType::OCLSampler: | 470 | case BuiltinType::OCLSampler: |
| 341 | case BuiltinType::OCLEvent: | 471 | case BuiltinType::OCLEvent: |
| 342 | case BuiltinType::OCLClkEvent: | 472 | case BuiltinType::OCLClkEvent: |
| 343 | case BuiltinType::OCLQueue: | 473 | case BuiltinType::OCLQueue: |
| 344 | case BuiltinType::OCLReserveID: | 474 | case BuiltinType::OCLReserveID: |
| 345 | emit_warning(c, decl, "missed a builtin type"); | 475 | emit_warning(c, source_loc, "unsupported builtin type"); |
| 346 | return c->codegen->builtin_types.entry_invalid; | 476 | return nullptr; |
| 347 | } | 477 | } |
| 348 | break; | 478 | break; |
| 349 | } | 479 | } |
| ... | @@ -351,170 +481,150 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const | ... | @@ -351,170 +481,150 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 351 | { | 481 | { |
| 352 | const PointerType *pointer_ty = static_cast<const PointerType*>(ty); | 482 | const PointerType *pointer_ty = static_cast<const PointerType*>(ty); |
| 353 | QualType child_qt = pointer_ty->getPointeeType(); | 483 | QualType child_qt = pointer_ty->getPointeeType(); |
| 354 | TypeTableEntry *child_type = resolve_qual_type(c, child_qt, decl); | 484 | AstNode *child_node = trans_qual_type(c, child_qt, source_loc); |
| 355 | if (type_is_invalid(child_type)) { | 485 | if (child_node == nullptr) { |
| 356 | emit_warning(c, decl, "pointer to unresolved type"); | 486 | emit_warning(c, source_loc, "pointer to unsupported type"); |
| 357 | return c->codegen->builtin_types.entry_invalid; | 487 | return nullptr; |
| 358 | } | 488 | } |
| 359 | | 489 | |
| 360 | if (qual_type_child_is_fn_proto(child_qt)) { | 490 | if (qual_type_child_is_fn_proto(child_qt)) { |
| 361 | return get_maybe_type(c->codegen, child_type); | 491 | return trans_create_node_prefix_op(c, PrefixOpMaybe, child_node); |
| 362 | } | 492 | } |
| 363 | bool is_const = child_qt.isConstQualified(); | | |
| 364 | | 493 | |
| 365 | TypeTableEntry *non_null_pointer_type = get_pointer_to_type(c->codegen, child_type, is_const); | 494 | AstNode *pointer_node = trans_create_node_addr_of(c, child_qt.isConstQualified(), |
| 366 | return get_maybe_type(c->codegen, non_null_pointer_type); | 495 | child_qt.isVolatileQualified(), child_node); |
| | 496 | return trans_create_node_prefix_op(c, PrefixOpMaybe, pointer_node); |
| 367 | } | 497 | } |
| 368 | case Type::Typedef: | 498 | case Type::Typedef: |
| 369 | { | 499 | { |
| 370 | const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty); | 500 | const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty); |
| 371 | const TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); | 501 | const TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); |
| 372 | Buf *type_name = buf_create_from_str(decl_name(typedef_decl)); | 502 | return resolve_typedef_decl(c, typedef_decl); |
| 373 | if (buf_eql_str(type_name, "uint8_t")) { | | |
| 374 | return c->codegen->builtin_types.entry_u8; | | |
| 375 | } else if (buf_eql_str(type_name, "int8_t")) { | | |
| 376 | return c->codegen->builtin_types.entry_i8; | | |
| 377 | } else if (buf_eql_str(type_name, "uint16_t")) { | | |
| 378 | return c->codegen->builtin_types.entry_u16; | | |
| 379 | } else if (buf_eql_str(type_name, "int16_t")) { | | |
| 380 | return c->codegen->builtin_types.entry_i16; | | |
| 381 | } else if (buf_eql_str(type_name, "uint32_t")) { | | |
| 382 | return c->codegen->builtin_types.entry_u32; | | |
| 383 | } else if (buf_eql_str(type_name, "int32_t")) { | | |
| 384 | return c->codegen->builtin_types.entry_i32; | | |
| 385 | } else if (buf_eql_str(type_name, "uint64_t")) { | | |
| 386 | return c->codegen->builtin_types.entry_u64; | | |
| 387 | } else if (buf_eql_str(type_name, "int64_t")) { | | |
| 388 | return c->codegen->builtin_types.entry_i64; | | |
| 389 | } else if (buf_eql_str(type_name, "intptr_t")) { | | |
| 390 | return c->codegen->builtin_types.entry_isize; | | |
| 391 | } else if (buf_eql_str(type_name, "uintptr_t")) { | | |
| 392 | return c->codegen->builtin_types.entry_usize; | | |
| 393 | } else { | | |
| 394 | auto entry = type_table->maybe_get(type_name); | | |
| 395 | if (entry) { | | |
| 396 | if (type_is_invalid(entry->value)) { | | |
| 397 | return c->codegen->builtin_types.entry_invalid; | | |
| 398 | } else { | | |
| 399 | return entry->value; | | |
| 400 | } | | |
| 401 | } else { | | |
| 402 | return c->codegen->builtin_types.entry_invalid; | | |
| 403 | } | | |
| 404 | } | | |
| 405 | } | 503 | } |
| 406 | case Type::Elaborated: | 504 | case Type::Elaborated: |
| 407 | { | 505 | { |
| 408 | const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty); | 506 | const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty); |
| 409 | switch (elaborated_ty->getKeyword()) { | 507 | switch (elaborated_ty->getKeyword()) { |
| 410 | case ETK_Struct: | 508 | case ETK_Struct: |
| 411 | return resolve_qual_type_with_table(c, elaborated_ty->getNamedType(), | 509 | return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), source_loc); |
| 412 | decl, &c->struct_type_table); | | |
| 413 | case ETK_Enum: | 510 | case ETK_Enum: |
| 414 | return resolve_qual_type_with_table(c, elaborated_ty->getNamedType(), | 511 | return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), source_loc); |
| 415 | decl, &c->enum_type_table); | | |
| 416 | case ETK_Interface: | 512 | case ETK_Interface: |
| 417 | case ETK_Union: | 513 | case ETK_Union: |
| 418 | case ETK_Class: | 514 | case ETK_Class: |
| 419 | case ETK_Typename: | 515 | case ETK_Typename: |
| 420 | case ETK_None: | 516 | case ETK_None: |
| 421 | emit_warning(c, decl, "unsupported elaborated type"); | 517 | emit_warning(c, source_loc, "unsupported elaborated type"); |
| 422 | return c->codegen->builtin_types.entry_invalid; | 518 | return nullptr; |
| 423 | } | 519 | } |
| 424 | } | 520 | } |
| 425 | case Type::FunctionProto: | 521 | case Type::FunctionProto: |
| 426 | { | 522 | { |
| 427 | const FunctionProtoType *fn_proto_ty = static_cast<const FunctionProtoType*>(ty); | 523 | const FunctionProtoType *fn_proto_ty = static_cast<const FunctionProtoType*>(ty); |
| 428 | | 524 | |
| | 525 | AstNode *proto_node = trans_create_node(c, NodeTypeFnProto); |
| 429 | switch (fn_proto_ty->getCallConv()) { | 526 | switch (fn_proto_ty->getCallConv()) { |
| 430 | case CC_C: // __attribute__((cdecl)) | 527 | case CC_C: // __attribute__((cdecl)) |
| | 528 | proto_node->data.fn_proto.cc = CallingConventionC; |
| | 529 | proto_node->data.fn_proto.is_extern = true; |
| 431 | break; | 530 | break; |
| 432 | case CC_X86StdCall: // __attribute__((stdcall)) | 531 | case CC_X86StdCall: // __attribute__((stdcall)) |
| 433 | emit_warning(c, decl, "function type has x86 stdcall calling convention"); | 532 | proto_node->data.fn_proto.cc = CallingConventionStdcall; |
| 434 | return c->codegen->builtin_types.entry_invalid; | 533 | break; |
| 435 | case CC_X86FastCall: // __attribute__((fastcall)) | 534 | case CC_X86FastCall: // __attribute__((fastcall)) |
| 436 | emit_warning(c, decl, "function type has x86 fastcall calling convention"); | 535 | emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall"); |
| 437 | return c->codegen->builtin_types.entry_invalid; | 536 | return nullptr; |
| 438 | case CC_X86ThisCall: // __attribute__((thiscall)) | 537 | case CC_X86ThisCall: // __attribute__((thiscall)) |
| 439 | emit_warning(c, decl, "function type has x86 thiscall calling convention"); | 538 | emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall"); |
| 440 | return c->codegen->builtin_types.entry_invalid; | 539 | return nullptr; |
| 441 | case CC_X86VectorCall: // __attribute__((vectorcall)) | 540 | case CC_X86VectorCall: // __attribute__((vectorcall)) |
| 442 | emit_warning(c, decl, "function type has x86 vectorcall calling convention"); | 541 | emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall"); |
| 443 | return c->codegen->builtin_types.entry_invalid; | 542 | return nullptr; |
| 444 | case CC_X86Pascal: // __attribute__((pascal)) | 543 | case CC_X86Pascal: // __attribute__((pascal)) |
| 445 | emit_warning(c, decl, "function type has x86 pascal calling convention"); | 544 | emit_warning(c, source_loc, "unsupported calling convention: x86 pascal"); |
| 446 | return c->codegen->builtin_types.entry_invalid; | 545 | return nullptr; |
| 447 | case CC_Win64: // __attribute__((ms_abi)) | 546 | case CC_Win64: // __attribute__((ms_abi)) |
| 448 | emit_warning(c, decl, "function type has win64 calling convention"); | 547 | emit_warning(c, source_loc, "unsupported calling convention: win64"); |
| 449 | return c->codegen->builtin_types.entry_invalid; | 548 | return nullptr; |
| 450 | case CC_X86_64SysV: // __attribute__((sysv_abi)) | 549 | case CC_X86_64SysV: // __attribute__((sysv_abi)) |
| 451 | emit_warning(c, decl, "function type has x86 64sysv calling convention"); | 550 | emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv"); |
| 452 | return c->codegen->builtin_types.entry_invalid; | 551 | return nullptr; |
| 453 | case CC_X86RegCall: | 552 | case CC_X86RegCall: |
| 454 | emit_warning(c, decl, "function type has x86 reg calling convention"); | 553 | emit_warning(c, source_loc, "unsupported calling convention: x86 reg"); |
| 455 | return c->codegen->builtin_types.entry_invalid; | 554 | return nullptr; |
| 456 | case CC_AAPCS: // __attribute__((pcs("aapcs"))) | 555 | case CC_AAPCS: // __attribute__((pcs("aapcs"))) |
| 457 | emit_warning(c, decl, "function type has aapcs calling convention"); | 556 | emit_warning(c, source_loc, "unsupported calling convention: aapcs"); |
| 458 | return c->codegen->builtin_types.entry_invalid; | 557 | return nullptr; |
| 459 | case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp"))) | 558 | case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp"))) |
| 460 | emit_warning(c, decl, "function type has aapcs-vfp calling convention"); | 559 | emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp"); |
| 461 | return c->codegen->builtin_types.entry_invalid; | 560 | return nullptr; |
| 462 | case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc)) | 561 | case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc)) |
| 463 | emit_warning(c, decl, "function type has intel_ocl_bicc calling convention"); | 562 | emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc"); |
| 464 | return c->codegen->builtin_types.entry_invalid; | 563 | return nullptr; |
| 465 | case CC_SpirFunction: // default for OpenCL functions on SPIR target | 564 | case CC_SpirFunction: // default for OpenCL functions on SPIR target |
| 466 | emit_warning(c, decl, "function type has SPIR function calling convention"); | 565 | emit_warning(c, source_loc, "unsupported calling convention: SPIR function"); |
| 467 | return c->codegen->builtin_types.entry_invalid; | 566 | return nullptr; |
| 468 | case CC_OpenCLKernel: | 567 | case CC_OpenCLKernel: |
| 469 | emit_warning(c, decl, "function type has OpenCLKernel calling convention"); | 568 | emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel"); |
| 470 | return c->codegen->builtin_types.entry_invalid; | 569 | return nullptr; |
| 471 | case CC_Swift: | 570 | case CC_Swift: |
| 472 | emit_warning(c, decl, "function type has Swift calling convention"); | 571 | emit_warning(c, source_loc, "unsupported calling convention: Swift"); |
| 473 | return c->codegen->builtin_types.entry_invalid; | 572 | return nullptr; |
| 474 | case CC_PreserveMost: | 573 | case CC_PreserveMost: |
| 475 | emit_warning(c, decl, "function type has PreserveMost calling convention"); | 574 | emit_warning(c, source_loc, "unsupported calling convention: PreserveMost"); |
| 476 | return c->codegen->builtin_types.entry_invalid; | 575 | return nullptr; |
| 477 | case CC_PreserveAll: | 576 | case CC_PreserveAll: |
| 478 | emit_warning(c, decl, "function type has PreserveAll calling convention"); | 577 | emit_warning(c, source_loc, "unsupported calling convention: PreserveAll"); |
| 479 | return c->codegen->builtin_types.entry_invalid; | 578 | return nullptr; |
| 480 | } | 579 | } |
| 481 | | 580 | |
| 482 | FnTypeId fn_type_id = {0}; | 581 | proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic(); |
| 483 | fn_type_id.cc = CallingConventionC; | 582 | size_t param_count = fn_proto_ty->getNumParams(); |
| 484 | fn_type_id.is_var_args = fn_proto_ty->isVariadic(); | | |
| 485 | fn_type_id.param_count = fn_proto_ty->getNumParams(); | | |
| 486 | | | |
| 487 | | 583 | |
| 488 | if (fn_proto_ty->getNoReturnAttr()) { | 584 | if (fn_proto_ty->getNoReturnAttr()) { |
| 489 | fn_type_id.return_type = c->codegen->builtin_types.entry_unreachable; | 585 | proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn"); |
| 490 | } else { | 586 | } else { |
| 491 | fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl); | 587 | proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_proto_ty->getReturnType(), |
| 492 | if (type_is_invalid(fn_type_id.return_type)) { | 588 | source_loc); |
| 493 | emit_warning(c, decl, "unresolved function proto return type"); | 589 | if (proto_node->data.fn_proto.return_type == nullptr) { |
| 494 | return c->codegen->builtin_types.entry_invalid; | 590 | emit_warning(c, source_loc, "unsupported function proto return type"); |
| | 591 | return nullptr; |
| 495 | } | 592 | } |
| 496 | // convert c_void to actual void (only for return type) | 593 | // convert c_void to actual void (only for return type) |
| 497 | if (is_c_void_type(c, fn_type_id.return_type)) { | 594 | if (is_c_void_type(proto_node->data.fn_proto.return_type)) { |
| 498 | fn_type_id.return_type = c->codegen->builtin_types.entry_void; | 595 | proto_node->data.fn_proto.return_type = nullptr; |
| 499 | } | 596 | } |
| 500 | } | 597 | } |
| 501 | | 598 | |
| 502 | fn_type_id.param_info = allocate_nonzero<FnTypeParamInfo>(fn_type_id.param_count); | 599 | //emit_warning(c, source_loc, "TODO figure out fn prototype fn name"); |
| 503 | for (size_t i = 0; i < fn_type_id.param_count; i += 1) { | 600 | const char *fn_name = nullptr; |
| | 601 | if (fn_name != nullptr) { |
| | 602 | proto_node->data.fn_proto.name = buf_create_from_str(fn_name); |
| | 603 | } |
| | 604 | |
| | 605 | for (size_t i = 0; i < param_count; i += 1) { |
| 504 | QualType qt = fn_proto_ty->getParamType(i); | 606 | QualType qt = fn_proto_ty->getParamType(i); |
| 505 | TypeTableEntry *param_type = resolve_qual_type(c, qt, decl); | 607 | AstNode *param_type_node = trans_qual_type(c, qt, source_loc); |
| 506 | | 608 | |
| 507 | if (type_is_invalid(param_type)) { | 609 | if (param_type_node == nullptr) { |
| 508 | emit_warning(c, decl, "unresolved function proto parameter type"); | 610 | emit_warning(c, source_loc, "unresolved function proto parameter type"); |
| 509 | return c->codegen->builtin_types.entry_invalid; | 611 | return nullptr; |
| 510 | } | 612 | } |
| 511 | | 613 | |
| 512 | FnTypeParamInfo *param_info = &fn_type_id.param_info[i]; | 614 | AstNode *param_node = trans_create_node(c, NodeTypeParamDecl); |
| 513 | param_info->type = param_type; | 615 | //emit_warning(c, source_loc, "TODO figure out fn prototype param name"); |
| 514 | param_info->is_noalias = qt.isRestrictQualified(); | 616 | const char *param_name = nullptr; |
| | 617 | if (param_name != nullptr) { |
| | 618 | param_node->data.param_decl.name = buf_create_from_str(param_name); |
| | 619 | } |
| | 620 | param_node->data.param_decl.is_noalias = qt.isRestrictQualified(); |
| | 621 | param_node->data.param_decl.type = param_type_node; |
| | 622 | proto_node->data.fn_proto.params.append(param_node); |
| 515 | } | 623 | } |
| | 624 | // TODO check for always_inline attribute |
| | 625 | // TODO check for align attribute |
| 516 | | 626 | |
| 517 | return get_fn_type(c->codegen, &fn_type_id); | 627 | return proto_node; |
| 518 | } | 628 | } |
| 519 | case Type::Record: | 629 | case Type::Record: |
| 520 | { | 630 | { |
| ... | @@ -529,28 +639,29 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const | ... | @@ -529,28 +639,29 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 529 | case Type::ConstantArray: | 639 | case Type::ConstantArray: |
| 530 | { | 640 | { |
| 531 | const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty); | 641 | const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty); |
| 532 | TypeTableEntry *child_type = resolve_qual_type(c, const_arr_ty->getElementType(), decl); | 642 | AstNode *child_type_node = trans_qual_type(c, const_arr_ty->getElementType(), source_loc); |
| 533 | if (child_type->id == TypeTableEntryIdInvalid) { | 643 | if (child_type_node == nullptr) { |
| 534 | emit_warning(c, decl, "unresolved array element type"); | 644 | emit_warning(c, source_loc, "unresolved array element type"); |
| 535 | return child_type; | 645 | return nullptr; |
| 536 | } | 646 | } |
| 537 | uint64_t size = const_arr_ty->getSize().getLimitedValue(); | 647 | uint64_t size = const_arr_ty->getSize().getLimitedValue(); |
| 538 | return get_array_type(c->codegen, child_type, size); | 648 | AstNode *size_node = trans_create_node_unsigned(c, size); |
| | 649 | return trans_create_node_array_type(c, size_node, child_type_node); |
| 539 | } | 650 | } |
| 540 | case Type::Paren: | 651 | case Type::Paren: |
| 541 | { | 652 | { |
| 542 | const ParenType *paren_ty = static_cast<const ParenType *>(ty); | 653 | const ParenType *paren_ty = static_cast<const ParenType *>(ty); |
| 543 | return resolve_qual_type(c, paren_ty->getInnerType(), decl); | 654 | return trans_qual_type(c, paren_ty->getInnerType(), source_loc); |
| 544 | } | 655 | } |
| 545 | case Type::Decayed: | 656 | case Type::Decayed: |
| 546 | { | 657 | { |
| 547 | const DecayedType *decayed_ty = static_cast<const DecayedType *>(ty); | 658 | const DecayedType *decayed_ty = static_cast<const DecayedType *>(ty); |
| 548 | return resolve_qual_type(c, decayed_ty->getDecayedType(), decl); | 659 | return trans_qual_type(c, decayed_ty->getDecayedType(), source_loc); |
| 549 | } | 660 | } |
| 550 | case Type::Attributed: | 661 | case Type::Attributed: |
| 551 | { | 662 | { |
| 552 | const AttributedType *attributed_ty = static_cast<const AttributedType *>(ty); | 663 | const AttributedType *attributed_ty = static_cast<const AttributedType *>(ty); |
| 553 | return resolve_qual_type(c, attributed_ty->getEquivalentType(), decl); | 664 | return trans_qual_type(c, attributed_ty->getEquivalentType(), source_loc); |
| 554 | } | 665 | } |
| 555 | case Type::BlockPointer: | 666 | case Type::BlockPointer: |
| 556 | case Type::LValueReference: | 667 | case Type::LValueReference: |
| ... | @@ -586,20 +697,897 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const | ... | @@ -586,20 +697,897 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 586 | case Type::Pipe: | 697 | case Type::Pipe: |
| 587 | case Type::ObjCTypeParam: | 698 | case Type::ObjCTypeParam: |
| 588 | case Type::DeducedTemplateSpecialization: | 699 | case Type::DeducedTemplateSpecialization: |
| 589 | emit_warning(c, decl, "missed a '%s' type", ty->getTypeClassName()); | 700 | emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName()); |
| 590 | return c->codegen->builtin_types.entry_invalid; | 701 | return nullptr; |
| 591 | } | 702 | } |
| 592 | zig_unreachable(); | 703 | zig_unreachable(); |
| 593 | } | 704 | } |
| 594 | | 705 | |
| 595 | static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl, | 706 | static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc) { |
| 596 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table) | 707 | return trans_type_with_table(c, qt.getTypePtr(), source_loc); |
| 597 | { | 708 | } |
| 598 | return resolve_type_with_table(c, qt.getTypePtr(), decl, type_table); | 709 | |
| | 710 | static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc) { |
| | 711 | return trans_qual_type_with_table(c, qt, source_loc); |
| 599 | } | 712 | } |
| 600 | | 713 | |
| 601 | static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl) { | 714 | static AstNode * trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) { |
| 602 | return resolve_qual_type_with_table(c, qt, decl, &c->global_type_table); | 715 | AstNode *child_block = trans_create_node(c, NodeTypeBlock); |
| | 716 | for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) { |
| | 717 | AstNode *child_node = trans_stmt(c, child_block, *it); |
| | 718 | if (child_node != nullptr) |
| | 719 | child_block->data.block.statements.append(child_node); |
| | 720 | } |
| | 721 | return child_block; |
| | 722 | } |
| | 723 | |
| | 724 | static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt) { |
| | 725 | Expr *value_expr = stmt->getRetValue(); |
| | 726 | if (value_expr == nullptr) { |
| | 727 | zig_panic("TODO handle C return void"); |
| | 728 | } else { |
| | 729 | AstNode *return_node = trans_create_node(c, NodeTypeReturnExpr); |
| | 730 | return_node->data.return_expr.expr = trans_expr(c, block, value_expr); |
| | 731 | return return_node; |
| | 732 | } |
| | 733 | } |
| | 734 | |
| | 735 | static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) { |
| | 736 | llvm::APSInt result; |
| | 737 | if (!stmt->EvaluateAsInt(result, *c->ctx)) { |
| | 738 | zig_panic("TODO handle libclang unable to evaluate C integer literal"); |
| | 739 | } |
| | 740 | return trans_create_node_apint(c, result); |
| | 741 | } |
| | 742 | |
| | 743 | static AstNode *trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) { |
| | 744 | AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr); |
| | 745 | |
| | 746 | Expr *cond_expr = stmt->getCond(); |
| | 747 | Expr *true_expr = stmt->getTrueExpr(); |
| | 748 | Expr *false_expr = stmt->getFalseExpr(); |
| | 749 | |
| | 750 | node->data.if_bool_expr.condition = trans_expr(c, block, cond_expr); |
| | 751 | node->data.if_bool_expr.then_block = trans_expr(c, block, true_expr); |
| | 752 | node->data.if_bool_expr.else_node = trans_expr(c, block, false_expr); |
| | 753 | |
| | 754 | return node; |
| | 755 | } |
| | 756 | |
| | 757 | static AstNode * trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOpType bin_op, Expr *rhs) { |
| | 758 | AstNode *node = trans_create_node(c, NodeTypeBinOpExpr); |
| | 759 | node->data.bin_op_expr.bin_op = bin_op; |
| | 760 | node->data.bin_op_expr.op1 = trans_expr(c, block, lhs); |
| | 761 | node->data.bin_op_expr.op2 = trans_expr(c, block, rhs); |
| | 762 | return node; |
| | 763 | } |
| | 764 | |
| | 765 | static AstNode * trans_binary_operator(Context *c, AstNode *block, BinaryOperator *stmt) { |
| | 766 | switch (stmt->getOpcode()) { |
| | 767 | case BO_PtrMemD: |
| | 768 | zig_panic("TODO handle more C binary operators: BO_PtrMemD"); |
| | 769 | case BO_PtrMemI: |
| | 770 | zig_panic("TODO handle more C binary operators: BO_PtrMemI"); |
| | 771 | case BO_Mul: |
| | 772 | zig_panic("TODO handle more C binary operators: BO_Mul"); |
| | 773 | case BO_Div: |
| | 774 | zig_panic("TODO handle more C binary operators: BO_Div"); |
| | 775 | case BO_Rem: |
| | 776 | zig_panic("TODO handle more C binary operators: BO_Rem"); |
| | 777 | case BO_Add: |
| | 778 | zig_panic("TODO handle more C binary operators: BO_Add"); |
| | 779 | case BO_Sub: |
| | 780 | zig_panic("TODO handle more C binary operators: BO_Sub"); |
| | 781 | case BO_Shl: |
| | 782 | zig_panic("TODO handle more C binary operators: BO_Shl"); |
| | 783 | case BO_Shr: |
| | 784 | zig_panic("TODO handle more C binary operators: BO_Shr"); |
| | 785 | case BO_LT: |
| | 786 | return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS()); |
| | 787 | case BO_GT: |
| | 788 | return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS()); |
| | 789 | case BO_LE: |
| | 790 | return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS()); |
| | 791 | case BO_GE: |
| | 792 | return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS()); |
| | 793 | case BO_EQ: |
| | 794 | zig_panic("TODO handle more C binary operators: BO_EQ"); |
| | 795 | case BO_NE: |
| | 796 | zig_panic("TODO handle more C binary operators: BO_NE"); |
| | 797 | case BO_And: |
| | 798 | zig_panic("TODO handle more C binary operators: BO_And"); |
| | 799 | case BO_Xor: |
| | 800 | zig_panic("TODO handle more C binary operators: BO_Xor"); |
| | 801 | case BO_Or: |
| | 802 | zig_panic("TODO handle more C binary operators: BO_Or"); |
| | 803 | case BO_LAnd: |
| | 804 | zig_panic("TODO handle more C binary operators: BO_LAnd"); |
| | 805 | case BO_LOr: |
| | 806 | zig_panic("TODO handle more C binary operators: BO_LOr"); |
| | 807 | case BO_Assign: |
| | 808 | zig_panic("TODO handle more C binary operators: BO_Assign"); |
| | 809 | case BO_MulAssign: |
| | 810 | zig_panic("TODO handle more C binary operators: BO_MulAssign"); |
| | 811 | case BO_DivAssign: |
| | 812 | zig_panic("TODO handle more C binary operators: BO_DivAssign"); |
| | 813 | case BO_RemAssign: |
| | 814 | zig_panic("TODO handle more C binary operators: BO_RemAssign"); |
| | 815 | case BO_AddAssign: |
| | 816 | zig_panic("TODO handle more C binary operators: BO_AddAssign"); |
| | 817 | case BO_SubAssign: |
| | 818 | zig_panic("TODO handle more C binary operators: BO_SubAssign"); |
| | 819 | case BO_ShlAssign: |
| | 820 | zig_panic("TODO handle more C binary operators: BO_ShlAssign"); |
| | 821 | case BO_ShrAssign: |
| | 822 | zig_panic("TODO handle more C binary operators: BO_ShrAssign"); |
| | 823 | case BO_AndAssign: |
| | 824 | zig_panic("TODO handle more C binary operators: BO_AndAssign"); |
| | 825 | case BO_XorAssign: |
| | 826 | zig_panic("TODO handle more C binary operators: BO_XorAssign"); |
| | 827 | case BO_OrAssign: |
| | 828 | zig_panic("TODO handle more C binary operators: BO_OrAssign"); |
| | 829 | case BO_Comma: |
| | 830 | zig_panic("TODO handle more C binary operators: BO_Comma"); |
| | 831 | } |
| | 832 | |
| | 833 | zig_unreachable(); |
| | 834 | } |
| | 835 | |
| | 836 | static AstNode * trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) { |
| | 837 | switch (stmt->getCastKind()) { |
| | 838 | case CK_LValueToRValue: |
| | 839 | return trans_expr(c, block, stmt->getSubExpr()); |
| | 840 | case CK_IntegralCast: |
| | 841 | { |
| | 842 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "bitCast"); |
| | 843 | node->data.fn_call_expr.params.append(trans_qual_type(c, stmt->getType(), stmt->getExprLoc())); |
| | 844 | node->data.fn_call_expr.params.append(trans_expr(c, block, stmt->getSubExpr())); |
| | 845 | return node; |
| | 846 | } |
| | 847 | case CK_Dependent: |
| | 848 | zig_panic("TODO handle C translation cast CK_Dependent"); |
| | 849 | case CK_BitCast: |
| | 850 | zig_panic("TODO handle C translation cast CK_BitCast"); |
| | 851 | case CK_LValueBitCast: |
| | 852 | zig_panic("TODO handle C translation cast CK_LValueBitCast"); |
| | 853 | case CK_NoOp: |
| | 854 | zig_panic("TODO handle C translation cast CK_NoOp"); |
| | 855 | case CK_BaseToDerived: |
| | 856 | zig_panic("TODO handle C translation cast CK_BaseToDerived"); |
| | 857 | case CK_DerivedToBase: |
| | 858 | zig_panic("TODO handle C translation cast CK_DerivedToBase"); |
| | 859 | case CK_UncheckedDerivedToBase: |
| | 860 | zig_panic("TODO handle C translation cast CK_UncheckedDerivedToBase"); |
| | 861 | case CK_Dynamic: |
| | 862 | zig_panic("TODO handle C translation cast CK_Dynamic"); |
| | 863 | case CK_ToUnion: |
| | 864 | zig_panic("TODO handle C translation cast CK_ToUnion"); |
| | 865 | case CK_ArrayToPointerDecay: |
| | 866 | zig_panic("TODO handle C translation cast CK_ArrayToPointerDecay"); |
| | 867 | case CK_FunctionToPointerDecay: |
| | 868 | zig_panic("TODO handle C translation cast CK_FunctionToPointerDecay"); |
| | 869 | case CK_NullToPointer: |
| | 870 | zig_panic("TODO handle C translation cast CK_NullToPointer"); |
| | 871 | case CK_NullToMemberPointer: |
| | 872 | zig_panic("TODO handle C translation cast CK_NullToMemberPointer"); |
| | 873 | case CK_BaseToDerivedMemberPointer: |
| | 874 | zig_panic("TODO handle C translation cast CK_BaseToDerivedMemberPointer"); |
| | 875 | case CK_DerivedToBaseMemberPointer: |
| | 876 | zig_panic("TODO handle C translation cast CK_DerivedToBaseMemberPointer"); |
| | 877 | case CK_MemberPointerToBoolean: |
| | 878 | zig_panic("TODO handle C translation cast CK_MemberPointerToBoolean"); |
| | 879 | case CK_ReinterpretMemberPointer: |
| | 880 | zig_panic("TODO handle C translation cast CK_ReinterpretMemberPointer"); |
| | 881 | case CK_UserDefinedConversion: |
| | 882 | zig_panic("TODO handle C translation cast CK_UserDefinedConversion"); |
| | 883 | case CK_ConstructorConversion: |
| | 884 | zig_panic("TODO handle C translation cast CK_ConstructorConversion"); |
| | 885 | case CK_IntegralToPointer: |
| | 886 | zig_panic("TODO handle C translation cast CK_IntegralToPointer"); |
| | 887 | case CK_PointerToIntegral: |
| | 888 | zig_panic("TODO handle C translation cast CK_PointerToIntegral"); |
| | 889 | case CK_PointerToBoolean: |
| | 890 | zig_panic("TODO handle C translation cast CK_PointerToBoolean"); |
| | 891 | case CK_ToVoid: |
| | 892 | zig_panic("TODO handle C translation cast CK_ToVoid"); |
| | 893 | case CK_VectorSplat: |
| | 894 | zig_panic("TODO handle C translation cast CK_VectorSplat"); |
| | 895 | case CK_IntegralToBoolean: |
| | 896 | zig_panic("TODO handle C translation cast CK_IntegralToBoolean"); |
| | 897 | case CK_IntegralToFloating: |
| | 898 | zig_panic("TODO handle C translation cast CK_IntegralToFloating"); |
| | 899 | case CK_FloatingToIntegral: |
| | 900 | zig_panic("TODO handle C translation cast CK_FloatingToIntegral"); |
| | 901 | case CK_FloatingToBoolean: |
| | 902 | zig_panic("TODO handle C translation cast CK_FloatingToBoolean"); |
| | 903 | case CK_BooleanToSignedIntegral: |
| | 904 | zig_panic("TODO handle C translation cast CK_BooleanToSignedIntegral"); |
| | 905 | case CK_FloatingCast: |
| | 906 | zig_panic("TODO handle C translation cast CK_FloatingCast"); |
| | 907 | case CK_CPointerToObjCPointerCast: |
| | 908 | zig_panic("TODO handle C translation cast CK_CPointerToObjCPointerCast"); |
| | 909 | case CK_BlockPointerToObjCPointerCast: |
| | 910 | zig_panic("TODO handle C translation cast CK_BlockPointerToObjCPointerCast"); |
| | 911 | case CK_AnyPointerToBlockPointerCast: |
| | 912 | zig_panic("TODO handle C translation cast CK_AnyPointerToBlockPointerCast"); |
| | 913 | case CK_ObjCObjectLValueCast: |
| | 914 | zig_panic("TODO handle C translation cast CK_ObjCObjectLValueCast"); |
| | 915 | case CK_FloatingRealToComplex: |
| | 916 | zig_panic("TODO handle C translation cast CK_FloatingRealToComplex"); |
| | 917 | case CK_FloatingComplexToReal: |
| | 918 | zig_panic("TODO handle C translation cast CK_FloatingComplexToReal"); |
| | 919 | case CK_FloatingComplexToBoolean: |
| | 920 | zig_panic("TODO handle C translation cast CK_FloatingComplexToBoolean"); |
| | 921 | case CK_FloatingComplexCast: |
| | 922 | zig_panic("TODO handle C translation cast CK_FloatingComplexCast"); |
| | 923 | case CK_FloatingComplexToIntegralComplex: |
| | 924 | zig_panic("TODO handle C translation cast CK_FloatingComplexToIntegralComplex"); |
| | 925 | case CK_IntegralRealToComplex: |
| | 926 | zig_panic("TODO handle C translation cast CK_IntegralRealToComplex"); |
| | 927 | case CK_IntegralComplexToReal: |
| | 928 | zig_panic("TODO handle C translation cast CK_IntegralComplexToReal"); |
| | 929 | case CK_IntegralComplexToBoolean: |
| | 930 | zig_panic("TODO handle C translation cast CK_IntegralComplexToBoolean"); |
| | 931 | case CK_IntegralComplexCast: |
| | 932 | zig_panic("TODO handle C translation cast CK_IntegralComplexCast"); |
| | 933 | case CK_IntegralComplexToFloatingComplex: |
| | 934 | zig_panic("TODO handle C translation cast CK_IntegralComplexToFloatingComplex"); |
| | 935 | case CK_ARCProduceObject: |
| | 936 | zig_panic("TODO handle C translation cast CK_ARCProduceObject"); |
| | 937 | case CK_ARCConsumeObject: |
| | 938 | zig_panic("TODO handle C translation cast CK_ARCConsumeObject"); |
| | 939 | case CK_ARCReclaimReturnedObject: |
| | 940 | zig_panic("TODO handle C translation cast CK_ARCReclaimReturnedObject"); |
| | 941 | case CK_ARCExtendBlockObject: |
| | 942 | zig_panic("TODO handle C translation cast CK_ARCExtendBlockObject"); |
| | 943 | case CK_AtomicToNonAtomic: |
| | 944 | zig_panic("TODO handle C translation cast CK_AtomicToNonAtomic"); |
| | 945 | case CK_NonAtomicToAtomic: |
| | 946 | zig_panic("TODO handle C translation cast CK_NonAtomicToAtomic"); |
| | 947 | case CK_CopyAndAutoreleaseBlockObject: |
| | 948 | zig_panic("TODO handle C translation cast CK_CopyAndAutoreleaseBlockObject"); |
| | 949 | case CK_BuiltinFnToFnPtr: |
| | 950 | zig_panic("TODO handle C translation cast CK_BuiltinFnToFnPtr"); |
| | 951 | case CK_ZeroToOCLEvent: |
| | 952 | zig_panic("TODO handle C translation cast CK_ZeroToOCLEvent"); |
| | 953 | case CK_ZeroToOCLQueue: |
| | 954 | zig_panic("TODO handle C translation cast CK_ZeroToOCLQueue"); |
| | 955 | case CK_AddressSpaceConversion: |
| | 956 | zig_panic("TODO handle C translation cast CK_AddressSpaceConversion"); |
| | 957 | case CK_IntToOCLSampler: |
| | 958 | zig_panic("TODO handle C translation cast CK_IntToOCLSampler"); |
| | 959 | } |
| | 960 | zig_unreachable(); |
| | 961 | } |
| | 962 | |
| | 963 | static AstNode * trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) { |
| | 964 | ValueDecl *value_decl = stmt->getDecl(); |
| | 965 | const char *name = decl_name(value_decl); |
| | 966 | |
| | 967 | AstNode *node = trans_create_node(c, NodeTypeSymbol); |
| | 968 | node->data.symbol_expr.symbol = buf_create_from_str(name); |
| | 969 | return node; |
| | 970 | } |
| | 971 | |
| | 972 | static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) { |
| | 973 | switch (stmt->getOpcode()) { |
| | 974 | case UO_PostInc: |
| | 975 | zig_panic("TODO handle C translation UO_PostInc"); |
| | 976 | case UO_PostDec: |
| | 977 | zig_panic("TODO handle C translation UO_PostDec"); |
| | 978 | case UO_PreInc: |
| | 979 | zig_panic("TODO handle C translation UO_PreInc"); |
| | 980 | case UO_PreDec: |
| | 981 | zig_panic("TODO handle C translation UO_PreDec"); |
| | 982 | case UO_AddrOf: |
| | 983 | zig_panic("TODO handle C translation UO_AddrOf"); |
| | 984 | case UO_Deref: |
| | 985 | zig_panic("TODO handle C translation UO_Deref"); |
| | 986 | case UO_Plus: |
| | 987 | zig_panic("TODO handle C translation UO_Plus"); |
| | 988 | case UO_Minus: |
| | 989 | { |
| | 990 | Expr *op_expr = stmt->getSubExpr(); |
| | 991 | if (c_is_signed_integer(c, op_expr->getType()) || c_is_float(c, op_expr->getType())) { |
| | 992 | AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr); |
| | 993 | node->data.prefix_op_expr.prefix_op = PrefixOpNegation; |
| | 994 | node->data.prefix_op_expr.primary_expr = trans_expr(c, block, op_expr); |
| | 995 | return node; |
| | 996 | } else if (c_is_unsigned_integer(c, op_expr->getType())) { |
| | 997 | // we gotta emit 0 -% x |
| | 998 | AstNode *node = trans_create_node(c, NodeTypeBinOpExpr); |
| | 999 | node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0); |
| | 1000 | node->data.bin_op_expr.op2 = trans_expr(c, block, op_expr); |
| | 1001 | node->data.bin_op_expr.bin_op = BinOpTypeSubWrap; |
| | 1002 | return node; |
| | 1003 | } else { |
| | 1004 | zig_panic("TODO translate C negation with non float non integer"); |
| | 1005 | } |
| | 1006 | } |
| | 1007 | case UO_Not: |
| | 1008 | zig_panic("TODO handle C translation UO_Not"); |
| | 1009 | case UO_LNot: |
| | 1010 | zig_panic("TODO handle C translation UO_LNot"); |
| | 1011 | case UO_Real: |
| | 1012 | zig_panic("TODO handle C translation UO_Real"); |
| | 1013 | case UO_Imag: |
| | 1014 | zig_panic("TODO handle C translation UO_Imag"); |
| | 1015 | case UO_Extension: |
| | 1016 | zig_panic("TODO handle C translation UO_Extension"); |
| | 1017 | case UO_Coawait: |
| | 1018 | zig_panic("TODO handle C translation UO_Coawait"); |
| | 1019 | } |
| | 1020 | zig_unreachable(); |
| | 1021 | } |
| | 1022 | |
| | 1023 | static AstNode * trans_local_declaration(Context *c, AstNode *block, DeclStmt *stmt) { |
| | 1024 | for (auto iter = stmt->decl_begin(); iter != stmt->decl_end(); iter++) { |
| | 1025 | Decl *decl = *iter; |
| | 1026 | switch (decl->getKind()) { |
| | 1027 | case Decl::Var: { |
| | 1028 | VarDecl *var_decl = (VarDecl *)decl; |
| | 1029 | QualType qual_type = var_decl->getTypeSourceInfo()->getType(); |
| | 1030 | AstNode *init_node = var_decl->hasInit() ? trans_expr(c, block, var_decl->getInit()) : nullptr; |
| | 1031 | AstNode *type_node = trans_qual_type(c, qual_type, stmt->getStartLoc()); |
| | 1032 | AstNode *node = trans_create_node_var_decl(c, qual_type.isConstQualified(), |
| | 1033 | buf_create_from_str(decl_name(var_decl)), type_node, init_node); |
| | 1034 | block->data.block.statements.append(node); |
| | 1035 | continue; |
| | 1036 | } |
| | 1037 | case Decl::AccessSpec: |
| | 1038 | zig_panic("TODO handle decl kind AccessSpec"); |
| | 1039 | case Decl::Block: |
| | 1040 | zig_panic("TODO handle decl kind Block"); |
| | 1041 | case Decl::Captured: |
| | 1042 | zig_panic("TODO handle decl kind Captured"); |
| | 1043 | case Decl::ClassScopeFunctionSpecialization: |
| | 1044 | zig_panic("TODO handle decl kind ClassScopeFunctionSpecialization"); |
| | 1045 | case Decl::Empty: |
| | 1046 | zig_panic("TODO handle decl kind Empty"); |
| | 1047 | case Decl::Export: |
| | 1048 | zig_panic("TODO handle decl kind Export"); |
| | 1049 | case Decl::ExternCContext: |
| | 1050 | zig_panic("TODO handle decl kind ExternCContext"); |
| | 1051 | case Decl::FileScopeAsm: |
| | 1052 | zig_panic("TODO handle decl kind FileScopeAsm"); |
| | 1053 | case Decl::Friend: |
| | 1054 | zig_panic("TODO handle decl kind Friend"); |
| | 1055 | case Decl::FriendTemplate: |
| | 1056 | zig_panic("TODO handle decl kind FriendTemplate"); |
| | 1057 | case Decl::Import: |
| | 1058 | zig_panic("TODO handle decl kind Import"); |
| | 1059 | case Decl::LinkageSpec: |
| | 1060 | zig_panic("TODO handle decl kind LinkageSpec"); |
| | 1061 | case Decl::Label: |
| | 1062 | zig_panic("TODO handle decl kind Label"); |
| | 1063 | case Decl::Namespace: |
| | 1064 | zig_panic("TODO handle decl kind Namespace"); |
| | 1065 | case Decl::NamespaceAlias: |
| | 1066 | zig_panic("TODO handle decl kind NamespaceAlias"); |
| | 1067 | case Decl::ObjCCompatibleAlias: |
| | 1068 | zig_panic("TODO handle decl kind ObjCCompatibleAlias"); |
| | 1069 | case Decl::ObjCCategory: |
| | 1070 | zig_panic("TODO handle decl kind ObjCCategory"); |
| | 1071 | case Decl::ObjCCategoryImpl: |
| | 1072 | zig_panic("TODO handle decl kind ObjCCategoryImpl"); |
| | 1073 | case Decl::ObjCImplementation: |
| | 1074 | zig_panic("TODO handle decl kind ObjCImplementation"); |
| | 1075 | case Decl::ObjCInterface: |
| | 1076 | zig_panic("TODO handle decl kind ObjCInterface"); |
| | 1077 | case Decl::ObjCProtocol: |
| | 1078 | zig_panic("TODO handle decl kind ObjCProtocol"); |
| | 1079 | case Decl::ObjCMethod: |
| | 1080 | zig_panic("TODO handle decl kind ObjCMethod"); |
| | 1081 | case Decl::ObjCProperty: |
| | 1082 | zig_panic("TODO handle decl kind ObjCProperty"); |
| | 1083 | case Decl::BuiltinTemplate: |
| | 1084 | zig_panic("TODO handle decl kind BuiltinTemplate"); |
| | 1085 | case Decl::ClassTemplate: |
| | 1086 | zig_panic("TODO handle decl kind ClassTemplate"); |
| | 1087 | case Decl::FunctionTemplate: |
| | 1088 | zig_panic("TODO handle decl kind FunctionTemplate"); |
| | 1089 | case Decl::TypeAliasTemplate: |
| | 1090 | zig_panic("TODO handle decl kind TypeAliasTemplate"); |
| | 1091 | case Decl::VarTemplate: |
| | 1092 | zig_panic("TODO handle decl kind VarTemplate"); |
| | 1093 | case Decl::TemplateTemplateParm: |
| | 1094 | zig_panic("TODO handle decl kind TemplateTemplateParm"); |
| | 1095 | case Decl::Enum: |
| | 1096 | zig_panic("TODO handle decl kind Enum"); |
| | 1097 | case Decl::Record: |
| | 1098 | zig_panic("TODO handle decl kind Record"); |
| | 1099 | case Decl::CXXRecord: |
| | 1100 | zig_panic("TODO handle decl kind CXXRecord"); |
| | 1101 | case Decl::ClassTemplateSpecialization: |
| | 1102 | zig_panic("TODO handle decl kind ClassTemplateSpecialization"); |
| | 1103 | case Decl::ClassTemplatePartialSpecialization: |
| | 1104 | zig_panic("TODO handle decl kind ClassTemplatePartialSpecialization"); |
| | 1105 | case Decl::TemplateTypeParm: |
| | 1106 | zig_panic("TODO handle decl kind TemplateTypeParm"); |
| | 1107 | case Decl::ObjCTypeParam: |
| | 1108 | zig_panic("TODO handle decl kind ObjCTypeParam"); |
| | 1109 | case Decl::TypeAlias: |
| | 1110 | zig_panic("TODO handle decl kind TypeAlias"); |
| | 1111 | case Decl::Typedef: |
| | 1112 | zig_panic("TODO handle decl kind Typedef"); |
| | 1113 | case Decl::UnresolvedUsingTypename: |
| | 1114 | zig_panic("TODO handle decl kind UnresolvedUsingTypename"); |
| | 1115 | case Decl::Using: |
| | 1116 | zig_panic("TODO handle decl kind Using"); |
| | 1117 | case Decl::UsingDirective: |
| | 1118 | zig_panic("TODO handle decl kind UsingDirective"); |
| | 1119 | case Decl::UsingPack: |
| | 1120 | zig_panic("TODO handle decl kind UsingPack"); |
| | 1121 | case Decl::UsingShadow: |
| | 1122 | zig_panic("TODO handle decl kind UsingShadow"); |
| | 1123 | case Decl::ConstructorUsingShadow: |
| | 1124 | zig_panic("TODO handle decl kind ConstructorUsingShadow"); |
| | 1125 | case Decl::Binding: |
| | 1126 | zig_panic("TODO handle decl kind Binding"); |
| | 1127 | case Decl::Field: |
| | 1128 | zig_panic("TODO handle decl kind Field"); |
| | 1129 | case Decl::ObjCAtDefsField: |
| | 1130 | zig_panic("TODO handle decl kind ObjCAtDefsField"); |
| | 1131 | case Decl::ObjCIvar: |
| | 1132 | zig_panic("TODO handle decl kind ObjCIvar"); |
| | 1133 | case Decl::Function: |
| | 1134 | zig_panic("TODO handle decl kind Function"); |
| | 1135 | case Decl::CXXDeductionGuide: |
| | 1136 | zig_panic("TODO handle decl kind CXXDeductionGuide"); |
| | 1137 | case Decl::CXXMethod: |
| | 1138 | zig_panic("TODO handle decl kind CXXMethod"); |
| | 1139 | case Decl::CXXConstructor: |
| | 1140 | zig_panic("TODO handle decl kind CXXConstructor"); |
| | 1141 | case Decl::CXXConversion: |
| | 1142 | zig_panic("TODO handle decl kind CXXConversion"); |
| | 1143 | case Decl::CXXDestructor: |
| | 1144 | zig_panic("TODO handle decl kind CXXDestructor"); |
| | 1145 | case Decl::MSProperty: |
| | 1146 | zig_panic("TODO handle decl kind MSProperty"); |
| | 1147 | case Decl::NonTypeTemplateParm: |
| | 1148 | zig_panic("TODO handle decl kind NonTypeTemplateParm"); |
| | 1149 | case Decl::Decomposition: |
| | 1150 | zig_panic("TODO handle decl kind Decomposition"); |
| | 1151 | case Decl::ImplicitParam: |
| | 1152 | zig_panic("TODO handle decl kind ImplicitParam"); |
| | 1153 | case Decl::OMPCapturedExpr: |
| | 1154 | zig_panic("TODO handle decl kind OMPCapturedExpr"); |
| | 1155 | case Decl::ParmVar: |
| | 1156 | zig_panic("TODO handle decl kind ParmVar"); |
| | 1157 | case Decl::VarTemplateSpecialization: |
| | 1158 | zig_panic("TODO handle decl kind VarTemplateSpecialization"); |
| | 1159 | case Decl::VarTemplatePartialSpecialization: |
| | 1160 | zig_panic("TODO handle decl kind VarTemplatePartialSpecialization"); |
| | 1161 | case Decl::EnumConstant: |
| | 1162 | zig_panic("TODO handle decl kind EnumConstant"); |
| | 1163 | case Decl::IndirectField: |
| | 1164 | zig_panic("TODO handle decl kind IndirectField"); |
| | 1165 | case Decl::OMPDeclareReduction: |
| | 1166 | zig_panic("TODO handle decl kind OMPDeclareReduction"); |
| | 1167 | case Decl::UnresolvedUsingValue: |
| | 1168 | zig_panic("TODO handle decl kind UnresolvedUsingValue"); |
| | 1169 | case Decl::OMPThreadPrivate: |
| | 1170 | zig_panic("TODO handle decl kind OMPThreadPrivate"); |
| | 1171 | case Decl::ObjCPropertyImpl: |
| | 1172 | zig_panic("TODO handle decl kind ObjCPropertyImpl"); |
| | 1173 | case Decl::PragmaComment: |
| | 1174 | zig_panic("TODO handle decl kind PragmaComment"); |
| | 1175 | case Decl::PragmaDetectMismatch: |
| | 1176 | zig_panic("TODO handle decl kind PragmaDetectMismatch"); |
| | 1177 | case Decl::StaticAssert: |
| | 1178 | zig_panic("TODO handle decl kind StaticAssert"); |
| | 1179 | case Decl::TranslationUnit: |
| | 1180 | zig_panic("TODO handle decl kind TranslationUnit"); |
| | 1181 | } |
| | 1182 | zig_unreachable(); |
| | 1183 | } |
| | 1184 | |
| | 1185 | // declarations were already added |
| | 1186 | return nullptr; |
| | 1187 | } |
| | 1188 | |
| | 1189 | static AstNode *trans_while_loop(Context *c, AstNode *block, WhileStmt *stmt) { |
| | 1190 | AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr); |
| | 1191 | while_node->data.while_expr.condition = trans_expr(c, block, stmt->getCond()); |
| | 1192 | while_node->data.while_expr.body = trans_stmt(c, block, stmt->getBody()); |
| | 1193 | return while_node; |
| | 1194 | } |
| | 1195 | |
| | 1196 | static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) { |
| | 1197 | Stmt::StmtClass sc = stmt->getStmtClass(); |
| | 1198 | switch (sc) { |
| | 1199 | case Stmt::ReturnStmtClass: |
| | 1200 | return trans_return_stmt(c, block, (ReturnStmt *)stmt); |
| | 1201 | case Stmt::CompoundStmtClass: |
| | 1202 | return trans_compound_stmt(c, block, (CompoundStmt *)stmt); |
| | 1203 | case Stmt::IntegerLiteralClass: |
| | 1204 | return trans_integer_literal(c, (IntegerLiteral *)stmt); |
| | 1205 | case Stmt::ConditionalOperatorClass: |
| | 1206 | return trans_conditional_operator(c, block, (ConditionalOperator *)stmt); |
| | 1207 | case Stmt::BinaryOperatorClass: |
| | 1208 | return trans_binary_operator(c, block, (BinaryOperator *)stmt); |
| | 1209 | case Stmt::ImplicitCastExprClass: |
| | 1210 | return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt); |
| | 1211 | case Stmt::DeclRefExprClass: |
| | 1212 | return trans_decl_ref_expr(c, (DeclRefExpr *)stmt); |
| | 1213 | case Stmt::UnaryOperatorClass: |
| | 1214 | return trans_unary_operator(c, block, (UnaryOperator *)stmt); |
| | 1215 | case Stmt::DeclStmtClass: |
| | 1216 | return trans_local_declaration(c, block, (DeclStmt *)stmt); |
| | 1217 | case Stmt::WhileStmtClass: |
| | 1218 | return trans_while_loop(c, block, (WhileStmt *)stmt); |
| | 1219 | case Stmt::CaseStmtClass: |
| | 1220 | zig_panic("TODO handle C CaseStmtClass"); |
| | 1221 | case Stmt::DefaultStmtClass: |
| | 1222 | zig_panic("TODO handle C DefaultStmtClass"); |
| | 1223 | case Stmt::SwitchStmtClass: |
| | 1224 | zig_panic("TODO handle C SwitchStmtClass"); |
| | 1225 | case Stmt::NoStmtClass: |
| | 1226 | zig_panic("TODO handle C NoStmtClass"); |
| | 1227 | case Stmt::GCCAsmStmtClass: |
| | 1228 | zig_panic("TODO handle C GCCAsmStmtClass"); |
| | 1229 | case Stmt::MSAsmStmtClass: |
| | 1230 | zig_panic("TODO handle C MSAsmStmtClass"); |
| | 1231 | case Stmt::AttributedStmtClass: |
| | 1232 | zig_panic("TODO handle C AttributedStmtClass"); |
| | 1233 | case Stmt::BreakStmtClass: |
| | 1234 | zig_panic("TODO handle C BreakStmtClass"); |
| | 1235 | case Stmt::CXXCatchStmtClass: |
| | 1236 | zig_panic("TODO handle C CXXCatchStmtClass"); |
| | 1237 | case Stmt::CXXForRangeStmtClass: |
| | 1238 | zig_panic("TODO handle C CXXForRangeStmtClass"); |
| | 1239 | case Stmt::CXXTryStmtClass: |
| | 1240 | zig_panic("TODO handle C CXXTryStmtClass"); |
| | 1241 | case Stmt::CapturedStmtClass: |
| | 1242 | zig_panic("TODO handle C CapturedStmtClass"); |
| | 1243 | case Stmt::ContinueStmtClass: |
| | 1244 | zig_panic("TODO handle C ContinueStmtClass"); |
| | 1245 | case Stmt::CoreturnStmtClass: |
| | 1246 | zig_panic("TODO handle C CoreturnStmtClass"); |
| | 1247 | case Stmt::CoroutineBodyStmtClass: |
| | 1248 | zig_panic("TODO handle C CoroutineBodyStmtClass"); |
| | 1249 | case Stmt::DoStmtClass: |
| | 1250 | zig_panic("TODO handle C DoStmtClass"); |
| | 1251 | case Stmt::BinaryConditionalOperatorClass: |
| | 1252 | zig_panic("TODO handle C BinaryConditionalOperatorClass"); |
| | 1253 | case Stmt::AddrLabelExprClass: |
| | 1254 | zig_panic("TODO handle C AddrLabelExprClass"); |
| | 1255 | case Stmt::ArrayInitIndexExprClass: |
| | 1256 | zig_panic("TODO handle C ArrayInitIndexExprClass"); |
| | 1257 | case Stmt::ArrayInitLoopExprClass: |
| | 1258 | zig_panic("TODO handle C ArrayInitLoopExprClass"); |
| | 1259 | case Stmt::ArraySubscriptExprClass: |
| | 1260 | zig_panic("TODO handle C ArraySubscriptExprClass"); |
| | 1261 | case Stmt::ArrayTypeTraitExprClass: |
| | 1262 | zig_panic("TODO handle C ArrayTypeTraitExprClass"); |
| | 1263 | case Stmt::AsTypeExprClass: |
| | 1264 | zig_panic("TODO handle C AsTypeExprClass"); |
| | 1265 | case Stmt::AtomicExprClass: |
| | 1266 | zig_panic("TODO handle C AtomicExprClass"); |
| | 1267 | case Stmt::CompoundAssignOperatorClass: |
| | 1268 | zig_panic("TODO handle C CompoundAssignOperatorClass"); |
| | 1269 | case Stmt::BlockExprClass: |
| | 1270 | zig_panic("TODO handle C BlockExprClass"); |
| | 1271 | case Stmt::CXXBindTemporaryExprClass: |
| | 1272 | zig_panic("TODO handle C CXXBindTemporaryExprClass"); |
| | 1273 | case Stmt::CXXBoolLiteralExprClass: |
| | 1274 | zig_panic("TODO handle C CXXBoolLiteralExprClass"); |
| | 1275 | case Stmt::CXXConstructExprClass: |
| | 1276 | zig_panic("TODO handle C CXXConstructExprClass"); |
| | 1277 | case Stmt::CXXTemporaryObjectExprClass: |
| | 1278 | zig_panic("TODO handle C CXXTemporaryObjectExprClass"); |
| | 1279 | case Stmt::CXXDefaultArgExprClass: |
| | 1280 | zig_panic("TODO handle C CXXDefaultArgExprClass"); |
| | 1281 | case Stmt::CXXDefaultInitExprClass: |
| | 1282 | zig_panic("TODO handle C CXXDefaultInitExprClass"); |
| | 1283 | case Stmt::CXXDeleteExprClass: |
| | 1284 | zig_panic("TODO handle C CXXDeleteExprClass"); |
| | 1285 | case Stmt::CXXDependentScopeMemberExprClass: |
| | 1286 | zig_panic("TODO handle C CXXDependentScopeMemberExprClass"); |
| | 1287 | case Stmt::CXXFoldExprClass: |
| | 1288 | zig_panic("TODO handle C CXXFoldExprClass"); |
| | 1289 | case Stmt::CXXInheritedCtorInitExprClass: |
| | 1290 | zig_panic("TODO handle C CXXInheritedCtorInitExprClass"); |
| | 1291 | case Stmt::CXXNewExprClass: |
| | 1292 | zig_panic("TODO handle C CXXNewExprClass"); |
| | 1293 | case Stmt::CXXNoexceptExprClass: |
| | 1294 | zig_panic("TODO handle C CXXNoexceptExprClass"); |
| | 1295 | case Stmt::CXXNullPtrLiteralExprClass: |
| | 1296 | zig_panic("TODO handle C CXXNullPtrLiteralExprClass"); |
| | 1297 | case Stmt::CXXPseudoDestructorExprClass: |
| | 1298 | zig_panic("TODO handle C CXXPseudoDestructorExprClass"); |
| | 1299 | case Stmt::CXXScalarValueInitExprClass: |
| | 1300 | zig_panic("TODO handle C CXXScalarValueInitExprClass"); |
| | 1301 | case Stmt::CXXStdInitializerListExprClass: |
| | 1302 | zig_panic("TODO handle C CXXStdInitializerListExprClass"); |
| | 1303 | case Stmt::CXXThisExprClass: |
| | 1304 | zig_panic("TODO handle C CXXThisExprClass"); |
| | 1305 | case Stmt::CXXThrowExprClass: |
| | 1306 | zig_panic("TODO handle C CXXThrowExprClass"); |
| | 1307 | case Stmt::CXXTypeidExprClass: |
| | 1308 | zig_panic("TODO handle C CXXTypeidExprClass"); |
| | 1309 | case Stmt::CXXUnresolvedConstructExprClass: |
| | 1310 | zig_panic("TODO handle C CXXUnresolvedConstructExprClass"); |
| | 1311 | case Stmt::CXXUuidofExprClass: |
| | 1312 | zig_panic("TODO handle C CXXUuidofExprClass"); |
| | 1313 | case Stmt::CallExprClass: |
| | 1314 | zig_panic("TODO handle C CallExprClass"); |
| | 1315 | case Stmt::CUDAKernelCallExprClass: |
| | 1316 | zig_panic("TODO handle C CUDAKernelCallExprClass"); |
| | 1317 | case Stmt::CXXMemberCallExprClass: |
| | 1318 | zig_panic("TODO handle C CXXMemberCallExprClass"); |
| | 1319 | case Stmt::CXXOperatorCallExprClass: |
| | 1320 | zig_panic("TODO handle C CXXOperatorCallExprClass"); |
| | 1321 | case Stmt::UserDefinedLiteralClass: |
| | 1322 | zig_panic("TODO handle C UserDefinedLiteralClass"); |
| | 1323 | case Stmt::CStyleCastExprClass: |
| | 1324 | zig_panic("TODO handle C CStyleCastExprClass"); |
| | 1325 | case Stmt::CXXFunctionalCastExprClass: |
| | 1326 | zig_panic("TODO handle C CXXFunctionalCastExprClass"); |
| | 1327 | case Stmt::CXXConstCastExprClass: |
| | 1328 | zig_panic("TODO handle C CXXConstCastExprClass"); |
| | 1329 | case Stmt::CXXDynamicCastExprClass: |
| | 1330 | zig_panic("TODO handle C CXXDynamicCastExprClass"); |
| | 1331 | case Stmt::CXXReinterpretCastExprClass: |
| | 1332 | zig_panic("TODO handle C CXXReinterpretCastExprClass"); |
| | 1333 | case Stmt::CXXStaticCastExprClass: |
| | 1334 | zig_panic("TODO handle C CXXStaticCastExprClass"); |
| | 1335 | case Stmt::ObjCBridgedCastExprClass: |
| | 1336 | zig_panic("TODO handle C ObjCBridgedCastExprClass"); |
| | 1337 | case Stmt::CharacterLiteralClass: |
| | 1338 | zig_panic("TODO handle C CharacterLiteralClass"); |
| | 1339 | case Stmt::ChooseExprClass: |
| | 1340 | zig_panic("TODO handle C ChooseExprClass"); |
| | 1341 | case Stmt::CompoundLiteralExprClass: |
| | 1342 | zig_panic("TODO handle C CompoundLiteralExprClass"); |
| | 1343 | case Stmt::ConvertVectorExprClass: |
| | 1344 | zig_panic("TODO handle C ConvertVectorExprClass"); |
| | 1345 | case Stmt::CoawaitExprClass: |
| | 1346 | zig_panic("TODO handle C CoawaitExprClass"); |
| | 1347 | case Stmt::CoyieldExprClass: |
| | 1348 | zig_panic("TODO handle C CoyieldExprClass"); |
| | 1349 | case Stmt::DependentCoawaitExprClass: |
| | 1350 | zig_panic("TODO handle C DependentCoawaitExprClass"); |
| | 1351 | case Stmt::DependentScopeDeclRefExprClass: |
| | 1352 | zig_panic("TODO handle C DependentScopeDeclRefExprClass"); |
| | 1353 | case Stmt::DesignatedInitExprClass: |
| | 1354 | zig_panic("TODO handle C DesignatedInitExprClass"); |
| | 1355 | case Stmt::DesignatedInitUpdateExprClass: |
| | 1356 | zig_panic("TODO handle C DesignatedInitUpdateExprClass"); |
| | 1357 | case Stmt::ExprWithCleanupsClass: |
| | 1358 | zig_panic("TODO handle C ExprWithCleanupsClass"); |
| | 1359 | case Stmt::ExpressionTraitExprClass: |
| | 1360 | zig_panic("TODO handle C ExpressionTraitExprClass"); |
| | 1361 | case Stmt::ExtVectorElementExprClass: |
| | 1362 | zig_panic("TODO handle C ExtVectorElementExprClass"); |
| | 1363 | case Stmt::FloatingLiteralClass: |
| | 1364 | zig_panic("TODO handle C FloatingLiteralClass"); |
| | 1365 | case Stmt::FunctionParmPackExprClass: |
| | 1366 | zig_panic("TODO handle C FunctionParmPackExprClass"); |
| | 1367 | case Stmt::GNUNullExprClass: |
| | 1368 | zig_panic("TODO handle C GNUNullExprClass"); |
| | 1369 | case Stmt::GenericSelectionExprClass: |
| | 1370 | zig_panic("TODO handle C GenericSelectionExprClass"); |
| | 1371 | case Stmt::ImaginaryLiteralClass: |
| | 1372 | zig_panic("TODO handle C ImaginaryLiteralClass"); |
| | 1373 | case Stmt::ImplicitValueInitExprClass: |
| | 1374 | zig_panic("TODO handle C ImplicitValueInitExprClass"); |
| | 1375 | case Stmt::InitListExprClass: |
| | 1376 | zig_panic("TODO handle C InitListExprClass"); |
| | 1377 | case Stmt::LambdaExprClass: |
| | 1378 | zig_panic("TODO handle C LambdaExprClass"); |
| | 1379 | case Stmt::MSPropertyRefExprClass: |
| | 1380 | zig_panic("TODO handle C MSPropertyRefExprClass"); |
| | 1381 | case Stmt::MSPropertySubscriptExprClass: |
| | 1382 | zig_panic("TODO handle C MSPropertySubscriptExprClass"); |
| | 1383 | case Stmt::MaterializeTemporaryExprClass: |
| | 1384 | zig_panic("TODO handle C MaterializeTemporaryExprClass"); |
| | 1385 | case Stmt::MemberExprClass: |
| | 1386 | zig_panic("TODO handle C MemberExprClass"); |
| | 1387 | case Stmt::NoInitExprClass: |
| | 1388 | zig_panic("TODO handle C NoInitExprClass"); |
| | 1389 | case Stmt::OMPArraySectionExprClass: |
| | 1390 | zig_panic("TODO handle C OMPArraySectionExprClass"); |
| | 1391 | case Stmt::ObjCArrayLiteralClass: |
| | 1392 | zig_panic("TODO handle C ObjCArrayLiteralClass"); |
| | 1393 | case Stmt::ObjCAvailabilityCheckExprClass: |
| | 1394 | zig_panic("TODO handle C ObjCAvailabilityCheckExprClass"); |
| | 1395 | case Stmt::ObjCBoolLiteralExprClass: |
| | 1396 | zig_panic("TODO handle C ObjCBoolLiteralExprClass"); |
| | 1397 | case Stmt::ObjCBoxedExprClass: |
| | 1398 | zig_panic("TODO handle C ObjCBoxedExprClass"); |
| | 1399 | case Stmt::ObjCDictionaryLiteralClass: |
| | 1400 | zig_panic("TODO handle C ObjCDictionaryLiteralClass"); |
| | 1401 | case Stmt::ObjCEncodeExprClass: |
| | 1402 | zig_panic("TODO handle C ObjCEncodeExprClass"); |
| | 1403 | case Stmt::ObjCIndirectCopyRestoreExprClass: |
| | 1404 | zig_panic("TODO handle C ObjCIndirectCopyRestoreExprClass"); |
| | 1405 | case Stmt::ObjCIsaExprClass: |
| | 1406 | zig_panic("TODO handle C ObjCIsaExprClass"); |
| | 1407 | case Stmt::ObjCIvarRefExprClass: |
| | 1408 | zig_panic("TODO handle C ObjCIvarRefExprClass"); |
| | 1409 | case Stmt::ObjCMessageExprClass: |
| | 1410 | zig_panic("TODO handle C ObjCMessageExprClass"); |
| | 1411 | case Stmt::ObjCPropertyRefExprClass: |
| | 1412 | zig_panic("TODO handle C ObjCPropertyRefExprClass"); |
| | 1413 | case Stmt::ObjCProtocolExprClass: |
| | 1414 | zig_panic("TODO handle C ObjCProtocolExprClass"); |
| | 1415 | case Stmt::ObjCSelectorExprClass: |
| | 1416 | zig_panic("TODO handle C ObjCSelectorExprClass"); |
| | 1417 | case Stmt::ObjCStringLiteralClass: |
| | 1418 | zig_panic("TODO handle C ObjCStringLiteralClass"); |
| | 1419 | case Stmt::ObjCSubscriptRefExprClass: |
| | 1420 | zig_panic("TODO handle C ObjCSubscriptRefExprClass"); |
| | 1421 | case Stmt::OffsetOfExprClass: |
| | 1422 | zig_panic("TODO handle C OffsetOfExprClass"); |
| | 1423 | case Stmt::OpaqueValueExprClass: |
| | 1424 | zig_panic("TODO handle C OpaqueValueExprClass"); |
| | 1425 | case Stmt::UnresolvedLookupExprClass: |
| | 1426 | zig_panic("TODO handle C UnresolvedLookupExprClass"); |
| | 1427 | case Stmt::UnresolvedMemberExprClass: |
| | 1428 | zig_panic("TODO handle C UnresolvedMemberExprClass"); |
| | 1429 | case Stmt::PackExpansionExprClass: |
| | 1430 | zig_panic("TODO handle C PackExpansionExprClass"); |
| | 1431 | case Stmt::ParenExprClass: |
| | 1432 | zig_panic("TODO handle C ParenExprClass"); |
| | 1433 | case Stmt::ParenListExprClass: |
| | 1434 | zig_panic("TODO handle C ParenListExprClass"); |
| | 1435 | case Stmt::PredefinedExprClass: |
| | 1436 | zig_panic("TODO handle C PredefinedExprClass"); |
| | 1437 | case Stmt::PseudoObjectExprClass: |
| | 1438 | zig_panic("TODO handle C PseudoObjectExprClass"); |
| | 1439 | case Stmt::ShuffleVectorExprClass: |
| | 1440 | zig_panic("TODO handle C ShuffleVectorExprClass"); |
| | 1441 | case Stmt::SizeOfPackExprClass: |
| | 1442 | zig_panic("TODO handle C SizeOfPackExprClass"); |
| | 1443 | case Stmt::StmtExprClass: |
| | 1444 | zig_panic("TODO handle C StmtExprClass"); |
| | 1445 | case Stmt::StringLiteralClass: |
| | 1446 | zig_panic("TODO handle C StringLiteralClass"); |
| | 1447 | case Stmt::SubstNonTypeTemplateParmExprClass: |
| | 1448 | zig_panic("TODO handle C SubstNonTypeTemplateParmExprClass"); |
| | 1449 | case Stmt::SubstNonTypeTemplateParmPackExprClass: |
| | 1450 | zig_panic("TODO handle C SubstNonTypeTemplateParmPackExprClass"); |
| | 1451 | case Stmt::TypeTraitExprClass: |
| | 1452 | zig_panic("TODO handle C TypeTraitExprClass"); |
| | 1453 | case Stmt::TypoExprClass: |
| | 1454 | zig_panic("TODO handle C TypoExprClass"); |
| | 1455 | case Stmt::UnaryExprOrTypeTraitExprClass: |
| | 1456 | zig_panic("TODO handle C UnaryExprOrTypeTraitExprClass"); |
| | 1457 | case Stmt::VAArgExprClass: |
| | 1458 | zig_panic("TODO handle C VAArgExprClass"); |
| | 1459 | case Stmt::ForStmtClass: |
| | 1460 | zig_panic("TODO handle C ForStmtClass"); |
| | 1461 | case Stmt::GotoStmtClass: |
| | 1462 | zig_panic("TODO handle C GotoStmtClass"); |
| | 1463 | case Stmt::IfStmtClass: |
| | 1464 | zig_panic("TODO handle C IfStmtClass"); |
| | 1465 | case Stmt::IndirectGotoStmtClass: |
| | 1466 | zig_panic("TODO handle C IndirectGotoStmtClass"); |
| | 1467 | case Stmt::LabelStmtClass: |
| | 1468 | zig_panic("TODO handle C LabelStmtClass"); |
| | 1469 | case Stmt::MSDependentExistsStmtClass: |
| | 1470 | zig_panic("TODO handle C MSDependentExistsStmtClass"); |
| | 1471 | case Stmt::NullStmtClass: |
| | 1472 | zig_panic("TODO handle C NullStmtClass"); |
| | 1473 | case Stmt::OMPAtomicDirectiveClass: |
| | 1474 | zig_panic("TODO handle C OMPAtomicDirectiveClass"); |
| | 1475 | case Stmt::OMPBarrierDirectiveClass: |
| | 1476 | zig_panic("TODO handle C OMPBarrierDirectiveClass"); |
| | 1477 | case Stmt::OMPCancelDirectiveClass: |
| | 1478 | zig_panic("TODO handle C OMPCancelDirectiveClass"); |
| | 1479 | case Stmt::OMPCancellationPointDirectiveClass: |
| | 1480 | zig_panic("TODO handle C OMPCancellationPointDirectiveClass"); |
| | 1481 | case Stmt::OMPCriticalDirectiveClass: |
| | 1482 | zig_panic("TODO handle C OMPCriticalDirectiveClass"); |
| | 1483 | case Stmt::OMPFlushDirectiveClass: |
| | 1484 | zig_panic("TODO handle C OMPFlushDirectiveClass"); |
| | 1485 | case Stmt::OMPDistributeDirectiveClass: |
| | 1486 | zig_panic("TODO handle C OMPDistributeDirectiveClass"); |
| | 1487 | case Stmt::OMPDistributeParallelForDirectiveClass: |
| | 1488 | zig_panic("TODO handle C OMPDistributeParallelForDirectiveClass"); |
| | 1489 | case Stmt::OMPDistributeParallelForSimdDirectiveClass: |
| | 1490 | zig_panic("TODO handle C OMPDistributeParallelForSimdDirectiveClass"); |
| | 1491 | case Stmt::OMPDistributeSimdDirectiveClass: |
| | 1492 | zig_panic("TODO handle C OMPDistributeSimdDirectiveClass"); |
| | 1493 | case Stmt::OMPForDirectiveClass: |
| | 1494 | zig_panic("TODO handle C OMPForDirectiveClass"); |
| | 1495 | case Stmt::OMPForSimdDirectiveClass: |
| | 1496 | zig_panic("TODO handle C OMPForSimdDirectiveClass"); |
| | 1497 | case Stmt::OMPParallelForDirectiveClass: |
| | 1498 | zig_panic("TODO handle C OMPParallelForDirectiveClass"); |
| | 1499 | case Stmt::OMPParallelForSimdDirectiveClass: |
| | 1500 | zig_panic("TODO handle C OMPParallelForSimdDirectiveClass"); |
| | 1501 | case Stmt::OMPSimdDirectiveClass: |
| | 1502 | zig_panic("TODO handle C OMPSimdDirectiveClass"); |
| | 1503 | case Stmt::OMPTargetParallelForSimdDirectiveClass: |
| | 1504 | zig_panic("TODO handle C OMPTargetParallelForSimdDirectiveClass"); |
| | 1505 | case Stmt::OMPTargetSimdDirectiveClass: |
| | 1506 | zig_panic("TODO handle C OMPTargetSimdDirectiveClass"); |
| | 1507 | case Stmt::OMPTargetTeamsDistributeDirectiveClass: |
| | 1508 | zig_panic("TODO handle C OMPTargetTeamsDistributeDirectiveClass"); |
| | 1509 | case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: |
| | 1510 | zig_panic("TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass"); |
| | 1511 | case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: |
| | 1512 | zig_panic("TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass"); |
| | 1513 | case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: |
| | 1514 | zig_panic("TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass"); |
| | 1515 | case Stmt::OMPTaskLoopDirectiveClass: |
| | 1516 | zig_panic("TODO handle C OMPTaskLoopDirectiveClass"); |
| | 1517 | case Stmt::OMPTaskLoopSimdDirectiveClass: |
| | 1518 | zig_panic("TODO handle C OMPTaskLoopSimdDirectiveClass"); |
| | 1519 | case Stmt::OMPTeamsDistributeDirectiveClass: |
| | 1520 | zig_panic("TODO handle C OMPTeamsDistributeDirectiveClass"); |
| | 1521 | case Stmt::OMPTeamsDistributeParallelForDirectiveClass: |
| | 1522 | zig_panic("TODO handle C OMPTeamsDistributeParallelForDirectiveClass"); |
| | 1523 | case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: |
| | 1524 | zig_panic("TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass"); |
| | 1525 | case Stmt::OMPTeamsDistributeSimdDirectiveClass: |
| | 1526 | zig_panic("TODO handle C OMPTeamsDistributeSimdDirectiveClass"); |
| | 1527 | case Stmt::OMPMasterDirectiveClass: |
| | 1528 | zig_panic("TODO handle C OMPMasterDirectiveClass"); |
| | 1529 | case Stmt::OMPOrderedDirectiveClass: |
| | 1530 | zig_panic("TODO handle C OMPOrderedDirectiveClass"); |
| | 1531 | case Stmt::OMPParallelDirectiveClass: |
| | 1532 | zig_panic("TODO handle C OMPParallelDirectiveClass"); |
| | 1533 | case Stmt::OMPParallelSectionsDirectiveClass: |
| | 1534 | zig_panic("TODO handle C OMPParallelSectionsDirectiveClass"); |
| | 1535 | case Stmt::OMPSectionDirectiveClass: |
| | 1536 | zig_panic("TODO handle C OMPSectionDirectiveClass"); |
| | 1537 | case Stmt::OMPSectionsDirectiveClass: |
| | 1538 | zig_panic("TODO handle C OMPSectionsDirectiveClass"); |
| | 1539 | case Stmt::OMPSingleDirectiveClass: |
| | 1540 | zig_panic("TODO handle C OMPSingleDirectiveClass"); |
| | 1541 | case Stmt::OMPTargetDataDirectiveClass: |
| | 1542 | zig_panic("TODO handle C OMPTargetDataDirectiveClass"); |
| | 1543 | case Stmt::OMPTargetDirectiveClass: |
| | 1544 | zig_panic("TODO handle C OMPTargetDirectiveClass"); |
| | 1545 | case Stmt::OMPTargetEnterDataDirectiveClass: |
| | 1546 | zig_panic("TODO handle C OMPTargetEnterDataDirectiveClass"); |
| | 1547 | case Stmt::OMPTargetExitDataDirectiveClass: |
| | 1548 | zig_panic("TODO handle C OMPTargetExitDataDirectiveClass"); |
| | 1549 | case Stmt::OMPTargetParallelDirectiveClass: |
| | 1550 | zig_panic("TODO handle C OMPTargetParallelDirectiveClass"); |
| | 1551 | case Stmt::OMPTargetParallelForDirectiveClass: |
| | 1552 | zig_panic("TODO handle C OMPTargetParallelForDirectiveClass"); |
| | 1553 | case Stmt::OMPTargetTeamsDirectiveClass: |
| | 1554 | zig_panic("TODO handle C OMPTargetTeamsDirectiveClass"); |
| | 1555 | case Stmt::OMPTargetUpdateDirectiveClass: |
| | 1556 | zig_panic("TODO handle C OMPTargetUpdateDirectiveClass"); |
| | 1557 | case Stmt::OMPTaskDirectiveClass: |
| | 1558 | zig_panic("TODO handle C OMPTaskDirectiveClass"); |
| | 1559 | case Stmt::OMPTaskgroupDirectiveClass: |
| | 1560 | zig_panic("TODO handle C OMPTaskgroupDirectiveClass"); |
| | 1561 | case Stmt::OMPTaskwaitDirectiveClass: |
| | 1562 | zig_panic("TODO handle C OMPTaskwaitDirectiveClass"); |
| | 1563 | case Stmt::OMPTaskyieldDirectiveClass: |
| | 1564 | zig_panic("TODO handle C OMPTaskyieldDirectiveClass"); |
| | 1565 | case Stmt::OMPTeamsDirectiveClass: |
| | 1566 | zig_panic("TODO handle C OMPTeamsDirectiveClass"); |
| | 1567 | case Stmt::ObjCAtCatchStmtClass: |
| | 1568 | zig_panic("TODO handle C ObjCAtCatchStmtClass"); |
| | 1569 | case Stmt::ObjCAtFinallyStmtClass: |
| | 1570 | zig_panic("TODO handle C ObjCAtFinallyStmtClass"); |
| | 1571 | case Stmt::ObjCAtSynchronizedStmtClass: |
| | 1572 | zig_panic("TODO handle C ObjCAtSynchronizedStmtClass"); |
| | 1573 | case Stmt::ObjCAtThrowStmtClass: |
| | 1574 | zig_panic("TODO handle C ObjCAtThrowStmtClass"); |
| | 1575 | case Stmt::ObjCAtTryStmtClass: |
| | 1576 | zig_panic("TODO handle C ObjCAtTryStmtClass"); |
| | 1577 | case Stmt::ObjCAutoreleasePoolStmtClass: |
| | 1578 | zig_panic("TODO handle C ObjCAutoreleasePoolStmtClass"); |
| | 1579 | case Stmt::ObjCForCollectionStmtClass: |
| | 1580 | zig_panic("TODO handle C ObjCForCollectionStmtClass"); |
| | 1581 | case Stmt::SEHExceptStmtClass: |
| | 1582 | zig_panic("TODO handle C SEHExceptStmtClass"); |
| | 1583 | case Stmt::SEHFinallyStmtClass: |
| | 1584 | zig_panic("TODO handle C SEHFinallyStmtClass"); |
| | 1585 | case Stmt::SEHLeaveStmtClass: |
| | 1586 | zig_panic("TODO handle C SEHLeaveStmtClass"); |
| | 1587 | case Stmt::SEHTryStmtClass: |
| | 1588 | zig_panic("TODO handle C SEHTryStmtClass"); |
| | 1589 | } |
| | 1590 | zig_unreachable(); |
| 603 | } | 1591 | } |
| 604 | | 1592 | |
| 605 | static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { | 1593 | static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| ... | @@ -610,112 +1598,146 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { | ... | @@ -610,112 +1598,146 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 610 | return; | 1598 | return; |
| 611 | } | 1599 | } |
| 612 | | 1600 | |
| 613 | TypeTableEntry *fn_type = resolve_qual_type(c, fn_decl->getType(), fn_decl); | 1601 | AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), fn_decl->getLocation()); |
| 614 | | 1602 | if (proto_node == nullptr) { |
| 615 | if (fn_type->id == TypeTableEntryIdInvalid) { | 1603 | emit_warning(c, fn_decl->getLocation(), "unable to resolve prototype of function '%s'", buf_ptr(fn_name)); |
| 616 | emit_warning(c, fn_decl, "ignoring function '%s' - unable to resolve type", buf_ptr(fn_name)); | | |
| 617 | return; | 1604 | return; |
| 618 | } | 1605 | } |
| 619 | assert(fn_type->id == TypeTableEntryIdFn); | | |
| 620 | | 1606 | |
| 621 | FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong); | 1607 | proto_node->data.fn_proto.name = fn_name; |
| 622 | buf_init_from_buf(&fn_entry->symbol_name, fn_name); | 1608 | proto_node->data.fn_proto.is_extern = !fn_decl->hasBody(); |
| 623 | fn_entry->type_entry = fn_type; | | |
| 624 | | 1609 | |
| 625 | assert(fn_type->data.fn.fn_type_id.cc != CallingConventionNaked); | 1610 | StorageClass sc = fn_decl->getStorageClass(); |
| | 1611 | if (sc == SC_None) { |
| | 1612 | proto_node->data.fn_proto.visib_mod = fn_decl->hasBody() ? VisibModExport : c->visib_mod; |
| | 1613 | } else if (sc == SC_Extern || sc == SC_Static) { |
| | 1614 | proto_node->data.fn_proto.visib_mod = c->visib_mod; |
| | 1615 | } else if (sc == SC_PrivateExtern) { |
| | 1616 | emit_warning(c, fn_decl->getLocation(), "unsupported storage class: private extern"); |
| | 1617 | return; |
| | 1618 | } else { |
| | 1619 | emit_warning(c, fn_decl->getLocation(), "unsupported storage class: unknown"); |
| | 1620 | return; |
| | 1621 | } |
| 626 | | 1622 | |
| 627 | size_t arg_count = fn_type->data.fn.fn_type_id.param_count; | 1623 | for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) { |
| 628 | fn_entry->param_names = allocate<Buf *>(arg_count); | 1624 | AstNode *param_node = proto_node->data.fn_proto.params.at(i); |
| 629 | Buf *name_buf; | | |
| 630 | for (size_t i = 0; i < arg_count; i += 1) { | | |
| 631 | const ParmVarDecl *param = fn_decl->getParamDecl(i); | 1625 | const ParmVarDecl *param = fn_decl->getParamDecl(i); |
| 632 | const char *name = decl_name(param); | 1626 | const char *name = decl_name(param); |
| 633 | if (strlen(name) == 0) { | 1627 | if (strlen(name) == 0) { |
| 634 | name_buf = buf_sprintf("arg%" ZIG_PRI_usize "", i); | 1628 | Buf *proto_param_name = param_node->data.param_decl.name; |
| | 1629 | if (proto_param_name == nullptr) { |
| | 1630 | param_node->data.param_decl.name = buf_sprintf("arg%" ZIG_PRI_usize "", i); |
| | 1631 | } else { |
| | 1632 | param_node->data.param_decl.name = proto_param_name; |
| | 1633 | } |
| 635 | } else { | 1634 | } else { |
| 636 | name_buf = buf_create_from_str(name); | 1635 | param_node->data.param_decl.name = buf_create_from_str(name); |
| 637 | } | 1636 | } |
| 638 | fn_entry->param_names[i] = name_buf; | | |
| 639 | } | 1637 | } |
| 640 | | 1638 | |
| 641 | TldFn *tld_fn = allocate<TldFn>(1); | 1639 | if (fn_decl->hasBody()) { |
| 642 | parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name); | 1640 | Stmt *body = fn_decl->getBody(); |
| 643 | tld_fn->fn_entry = fn_entry; | 1641 | |
| 644 | add_global(c, &tld_fn->base); | 1642 | AstNode *fn_def_node = trans_create_node(c, NodeTypeFnDef); |
| | 1643 | fn_def_node->data.fn_def.fn_proto = proto_node; |
| | 1644 | fn_def_node->data.fn_def.body = trans_stmt(c, nullptr, body); |
| 645 | | 1645 | |
| 646 | c->codegen->fn_protos.append(fn_entry); | 1646 | proto_node->data.fn_proto.fn_def_node = fn_def_node; |
| | 1647 | c->root->data.root.top_level_decls.append(fn_def_node); |
| | 1648 | return; |
| | 1649 | } |
| | 1650 | |
| | 1651 | c->root->data.root.top_level_decls.append(proto_node); |
| | 1652 | } |
| | 1653 | |
| | 1654 | static AstNode *resolve_typdef_as_builtin(Context *c, const TypedefNameDecl *typedef_decl, const char *primitive_name) { |
| | 1655 | AstNode *node = trans_create_node_symbol_str(c, primitive_name); |
| | 1656 | c->decl_table.put(typedef_decl, node); |
| | 1657 | return node; |
| 647 | } | 1658 | } |
| 648 | | 1659 | |
| 649 | static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) { | 1660 | static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) { |
| | 1661 | auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl); |
| | 1662 | if (existing_entry) { |
| | 1663 | return existing_entry->value; |
| | 1664 | } |
| | 1665 | |
| 650 | QualType child_qt = typedef_decl->getUnderlyingType(); | 1666 | QualType child_qt = typedef_decl->getUnderlyingType(); |
| 651 | Buf *type_name = buf_create_from_str(decl_name(typedef_decl)); | 1667 | Buf *type_name = buf_create_from_str(decl_name(typedef_decl)); |
| 652 | | 1668 | |
| 653 | if (buf_eql_str(type_name, "uint8_t") || | 1669 | if (buf_eql_str(type_name, "uint8_t")) { |
| 654 | buf_eql_str(type_name, "int8_t") || | 1670 | return resolve_typdef_as_builtin(c, typedef_decl, "u8"); |
| 655 | buf_eql_str(type_name, "uint16_t") || | 1671 | } else if (buf_eql_str(type_name, "int8_t")) { |
| 656 | buf_eql_str(type_name, "int16_t") || | 1672 | return resolve_typdef_as_builtin(c, typedef_decl, "i8"); |
| 657 | buf_eql_str(type_name, "uint32_t") || | 1673 | } else if (buf_eql_str(type_name, "uint16_t")) { |
| 658 | buf_eql_str(type_name, "int32_t") || | 1674 | return resolve_typdef_as_builtin(c, typedef_decl, "u16"); |
| 659 | buf_eql_str(type_name, "uint64_t") || | 1675 | } else if (buf_eql_str(type_name, "int16_t")) { |
| 660 | buf_eql_str(type_name, "int64_t") || | 1676 | return resolve_typdef_as_builtin(c, typedef_decl, "i16"); |
| 661 | buf_eql_str(type_name, "intptr_t") || | 1677 | } else if (buf_eql_str(type_name, "uint32_t")) { |
| 662 | buf_eql_str(type_name, "uintptr_t")) | 1678 | return resolve_typdef_as_builtin(c, typedef_decl, "u32"); |
| 663 | { | 1679 | } else if (buf_eql_str(type_name, "int32_t")) { |
| 664 | // special case we can just use the builtin types | 1680 | return resolve_typdef_as_builtin(c, typedef_decl, "i32"); |
| 665 | return; | 1681 | } else if (buf_eql_str(type_name, "uint64_t")) { |
| | 1682 | return resolve_typdef_as_builtin(c, typedef_decl, "u64"); |
| | 1683 | } else if (buf_eql_str(type_name, "int64_t")) { |
| | 1684 | return resolve_typdef_as_builtin(c, typedef_decl, "i64"); |
| | 1685 | } else if (buf_eql_str(type_name, "intptr_t")) { |
| | 1686 | return resolve_typdef_as_builtin(c, typedef_decl, "isize"); |
| | 1687 | } else if (buf_eql_str(type_name, "uintptr_t")) { |
| | 1688 | return resolve_typdef_as_builtin(c, typedef_decl, "usize"); |
| | 1689 | } else if (buf_eql_str(type_name, "ssize_t")) { |
| | 1690 | return resolve_typdef_as_builtin(c, typedef_decl, "isize"); |
| | 1691 | } else if (buf_eql_str(type_name, "size_t")) { |
| | 1692 | return resolve_typdef_as_builtin(c, typedef_decl, "usize"); |
| 666 | } | 1693 | } |
| 667 | | 1694 | |
| 668 | // if the underlying type is anonymous, we can special case it to just | 1695 | // if the underlying type is anonymous, we can special case it to just |
| 669 | // use the name of this typedef | 1696 | // use the name of this typedef |
| 670 | // TODO | 1697 | // TODO |
| 671 | | 1698 | |
| 672 | TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl); | 1699 | AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation()); |
| 673 | if (child_type->id == TypeTableEntryIdInvalid) { | 1700 | if (type_node == nullptr) { |
| 674 | emit_warning(c, typedef_decl, "typedef %s - unresolved child type", buf_ptr(type_name)); | 1701 | emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name)); |
| 675 | return; | 1702 | c->decl_table.put(typedef_decl, nullptr); |
| | 1703 | return nullptr; |
| 676 | } | 1704 | } |
| 677 | add_const_type(c, type_name, child_type); | 1705 | add_global_var(c, type_name, type_node); |
| 678 | } | | |
| 679 | | 1706 | |
| 680 | static void replace_with_fwd_decl(Context *c, TypeTableEntry *struct_type, Buf *full_type_name) { | 1707 | AstNode *symbol_node = trans_create_node_symbol(c, type_name); |
| 681 | unsigned line = c->source_node ? c->source_node->line : 0; | 1708 | c->decl_table.put(typedef_decl, symbol_node); |
| 682 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugForwardDeclType(c->codegen->dbuilder, | 1709 | return symbol_node; |
| 683 | ZigLLVMTag_DW_structure_type(), buf_ptr(full_type_name), | 1710 | } |
| 684 | ZigLLVMFileToScope(c->import->di_file), c->import->di_file, line); | | |
| 685 | | 1711 | |
| 686 | ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type); | 1712 | struct AstNode *demote_enum_to_opaque(Context *c, const EnumDecl *enum_decl, |
| 687 | struct_type->di_type = replacement_di_type; | 1713 | Buf *full_type_name, Buf *bare_name) |
| 688 | struct_type->id = TypeTableEntryIdOpaque; | 1714 | { |
| | 1715 | AstNode *opaque_node = trans_create_node_opaque(c); |
| | 1716 | if (full_type_name == nullptr) { |
| | 1717 | c->decl_table.put(enum_decl->getCanonicalDecl(), opaque_node); |
| | 1718 | return opaque_node; |
| | 1719 | } |
| | 1720 | AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); |
| | 1721 | add_global_weak_alias(c, bare_name, full_type_name); |
| | 1722 | add_global_var(c, full_type_name, opaque_node); |
| | 1723 | c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node); |
| | 1724 | return symbol_node; |
| 689 | } | 1725 | } |
| 690 | | 1726 | |
| 691 | static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { | 1727 | static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 692 | auto existing_entry = c->decl_table.maybe_get((void*)enum_decl); | 1728 | auto existing_entry = c->decl_table.maybe_get((void*)enum_decl->getCanonicalDecl()); |
| 693 | if (existing_entry) { | 1729 | if (existing_entry) { |
| 694 | return existing_entry->value; | 1730 | return existing_entry->value; |
| 695 | } | 1731 | } |
| 696 | | 1732 | |
| 697 | const char *raw_name = decl_name(enum_decl); | 1733 | const char *raw_name = decl_name(enum_decl); |
| 698 | | 1734 | bool is_anonymous = (raw_name[0] == 0); |
| 699 | Buf *bare_name; | 1735 | Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name); |
| 700 | if (raw_name[0] == 0) { | 1736 | Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name)); |
| 701 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_anon_index(c)); | | |
| 702 | } else { | | |
| 703 | bare_name = buf_create_from_str(raw_name); | | |
| 704 | } | | |
| 705 | | | |
| 706 | Buf *full_type_name = buf_sprintf("enum_%s", buf_ptr(bare_name)); | | |
| 707 | | 1737 | |
| 708 | const EnumDecl *enum_def = enum_decl->getDefinition(); | 1738 | const EnumDecl *enum_def = enum_decl->getDefinition(); |
| 709 | if (!enum_def) { | 1739 | if (!enum_def) { |
| 710 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, | 1740 | return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name); |
| 711 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern); | | |
| 712 | enum_type->data.enumeration.zero_bits_known = true; | | |
| 713 | enum_type->data.enumeration.abi_alignment = 1; | | |
| 714 | c->enum_type_table.put(bare_name, enum_type); | | |
| 715 | c->decl_table.put(enum_decl, enum_type); | | |
| 716 | replace_with_fwd_decl(c, enum_type, full_type_name); | | |
| 717 | | | |
| 718 | return enum_type; | | |
| 719 | } | 1741 | } |
| 720 | | 1742 | |
| 721 | bool pure_enum = true; | 1743 | bool pure_enum = true; |
| ... | @@ -730,25 +1752,16 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) | ... | @@ -730,25 +1752,16 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 730 | } | 1752 | } |
| 731 | } | 1753 | } |
| 732 | | 1754 | |
| 733 | TypeTableEntry *tag_int_type = resolve_qual_type(c, enum_decl->getIntegerType(), enum_decl); | 1755 | AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation()); |
| | 1756 | assert(tag_int_type); |
| 734 | | 1757 | |
| 735 | if (pure_enum) { | 1758 | if (pure_enum) { |
| 736 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, | 1759 | AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl); |
| 737 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern); | 1760 | enum_node->data.container_decl.kind = ContainerKindEnum; |
| 738 | TypeTableEntry *tag_type_entry = create_enum_tag_type(c->codegen, enum_type, tag_int_type); | 1761 | enum_node->data.container_decl.layout = ContainerLayoutExtern; |
| 739 | c->enum_type_table.put(bare_name, enum_type); | 1762 | enum_node->data.container_decl.init_arg_expr = tag_int_type; |
| 740 | c->decl_table.put(enum_decl, enum_type); | | |
| 741 | | | |
| 742 | enum_type->data.enumeration.gen_field_count = 0; | | |
| 743 | enum_type->data.enumeration.complete = true; | | |
| 744 | enum_type->data.enumeration.zero_bits_known = true; | | |
| 745 | enum_type->data.enumeration.abi_alignment = 1; | | |
| 746 | enum_type->data.enumeration.tag_type = tag_type_entry; | | |
| 747 | | | |
| 748 | enum_type->data.enumeration.src_field_count = field_count; | | |
| 749 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); | | |
| 750 | ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); | | |
| 751 | | 1763 | |
| | 1764 | enum_node->data.container_decl.fields.resize(field_count); |
| 752 | uint32_t i = 0; | 1765 | uint32_t i = 0; |
| 753 | for (auto it = enum_def->enumerator_begin(), | 1766 | for (auto it = enum_def->enumerator_begin(), |
| 754 | it_end = enum_def->enumerator_end(); | 1767 | it_end = enum_def->enumerator_end(); |
| ... | @@ -758,93 +1771,82 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) | ... | @@ -758,93 +1771,82 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 758 | | 1771 | |
| 759 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); | 1772 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 760 | Buf *field_name; | 1773 | Buf *field_name; |
| 761 | if (buf_starts_with_buf(enum_val_name, bare_name)) { | 1774 | if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) { |
| 762 | field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); | 1775 | field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); |
| 763 | } else { | 1776 | } else { |
| 764 | field_name = enum_val_name; | 1777 | field_name = enum_val_name; |
| 765 | } | 1778 | } |
| 766 | | 1779 | |
| 767 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; | 1780 | AstNode *field_node = trans_create_node(c, NodeTypeStructField); |
| 768 | type_enum_field->name = field_name; | 1781 | field_node->data.struct_field.name = field_name; |
| 769 | type_enum_field->type_entry = c->codegen->builtin_types.entry_void; | 1782 | field_node->data.struct_field.type = nullptr; |
| 770 | type_enum_field->value = i; | 1783 | enum_node->data.container_decl.fields.items[i] = field_node; |
| 771 | | | |
| 772 | di_enumerators[i] = ZigLLVMCreateDebugEnumerator(c->codegen->dbuilder, buf_ptr(type_enum_field->name), i); | | |
| 773 | | | |
| 774 | | 1784 | |
| 775 | // in C each enum value is in the global namespace. so we put them there too. | 1785 | // in C each enum value is in the global namespace. so we put them there too. |
| 776 | // at this point we can rely on the enum emitting successfully | 1786 | // at this point we can rely on the enum emitting successfully |
| 777 | add_global(c, create_global_num_lit_unsigned_negative(c, enum_val_name, i, false)); | 1787 | AstNode *field_access_node = trans_create_node_field_access(c, |
| | 1788 | trans_create_node_symbol(c, full_type_name), field_name); |
| | 1789 | add_global_var(c, enum_val_name, field_access_node); |
| 778 | } | 1790 | } |
| 779 | | 1791 | |
| 780 | // create llvm type for root struct | 1792 | if (is_anonymous) { |
| 781 | enum_type->type_ref = tag_type_entry->type_ref; | 1793 | c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node); |
| 782 | | 1794 | return enum_node; |
| 783 | enum_type->data.enumeration.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref, | 1795 | } else { |
| 784 | enum_type->type_ref); | 1796 | AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); |
| 785 | | 1797 | add_global_weak_alias(c, bare_name, full_type_name); |
| 786 | // create debug type for tag | 1798 | add_global_var(c, full_type_name, enum_node); |
| 787 | unsigned line = c->source_node ? (c->source_node->line + 1) : 0; | 1799 | c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node); |
| 788 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, enum_type->type_ref); | 1800 | return enum_node; |
| 789 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, enum_type->type_ref); | 1801 | } |
| 790 | ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(c->codegen->dbuilder, | 1802 | } |
| 791 | ZigLLVMFileToScope(c->import->di_file), buf_ptr(bare_name), | | |
| 792 | c->import->di_file, line, | | |
| 793 | debug_size_in_bits, | | |
| 794 | debug_align_in_bits, | | |
| 795 | di_enumerators, field_count, tag_type_entry->di_type, ""); | | |
| 796 | | | |
| 797 | ZigLLVMReplaceTemporary(c->codegen->dbuilder, enum_type->di_type, tag_di_type); | | |
| 798 | enum_type->di_type = tag_di_type; | | |
| 799 | | | |
| 800 | return enum_type; | | |
| 801 | } else { | | |
| 802 | // TODO after issue #305 is solved, make this be an enum with tag_int_type | | |
| 803 | // as the integer type and set the custom enum values | | |
| 804 | TypeTableEntry *enum_type = tag_int_type; | | |
| 805 | c->enum_type_table.put(bare_name, enum_type); | | |
| 806 | c->decl_table.put(enum_decl, enum_type); | | |
| 807 | | 1803 | |
| 808 | // add variables for all the values with enum_type | 1804 | // TODO after issue #305 is solved, make this be an enum with tag_int_type |
| 809 | for (auto it = enum_def->enumerator_begin(), | 1805 | // as the integer type and set the custom enum values |
| 810 | it_end = enum_def->enumerator_end(); | 1806 | AstNode *enum_node = tag_int_type; |
| 811 | it != it_end; ++it) | | |
| 812 | { | | |
| 813 | const EnumConstantDecl *enum_const = *it; | | |
| 814 | | 1807 | |
| 815 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); | | |
| 816 | | 1808 | |
| 817 | Tld *tld = create_global_num_lit_ap(c, enum_decl, enum_val_name, enum_const->getInitVal()); | 1809 | // add variables for all the values with enum_node |
| 818 | if (!tld) | 1810 | for (auto it = enum_def->enumerator_begin(), |
| 819 | return c->codegen->builtin_types.entry_invalid; | 1811 | it_end = enum_def->enumerator_end(); |
| | 1812 | it != it_end; ++it) |
| | 1813 | { |
| | 1814 | const EnumConstantDecl *enum_const = *it; |
| 820 | | 1815 | |
| 821 | add_global(c, tld); | 1816 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 822 | } | 1817 | AstNode *int_node = trans_create_node_apint(c, enum_const->getInitVal()); |
| | 1818 | AstNode *var_node = add_global_var(c, enum_val_name, int_node); |
| | 1819 | var_node->data.variable_declaration.type = tag_int_type; |
| | 1820 | } |
| 823 | | 1821 | |
| 824 | return enum_type; | 1822 | if (is_anonymous) { |
| | 1823 | c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node); |
| | 1824 | return enum_node; |
| | 1825 | } else { |
| | 1826 | AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); |
| | 1827 | add_global_weak_alias(c, bare_name, full_type_name); |
| | 1828 | add_global_var(c, full_type_name, enum_node); |
| | 1829 | return symbol_node; |
| 825 | } | 1830 | } |
| 826 | } | 1831 | } |
| 827 | | 1832 | |
| 828 | static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { | 1833 | static AstNode *demote_struct_to_opaque(Context *c, const RecordDecl *record_decl, |
| 829 | TypeTableEntry *enum_type = resolve_enum_decl(c, enum_decl); | 1834 | Buf *full_type_name, Buf *bare_name) |
| 830 | | 1835 | { |
| 831 | if (enum_type->id == TypeTableEntryIdInvalid) | 1836 | AstNode *opaque_node = trans_create_node_opaque(c); |
| 832 | return; | 1837 | if (full_type_name == nullptr) { |
| 833 | | 1838 | c->decl_table.put(record_decl->getCanonicalDecl(), opaque_node); |
| 834 | // make an alias without the "enum_" prefix. this will get emitted at the | 1839 | return opaque_node; |
| 835 | // end if it doesn't conflict with anything else | 1840 | } |
| 836 | bool is_anonymous = (decl_name(enum_decl)[0] == 0); | 1841 | AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); |
| 837 | if (is_anonymous) | 1842 | add_global_weak_alias(c, bare_name, full_type_name); |
| 838 | return; | 1843 | add_global_var(c, full_type_name, opaque_node); |
| 839 | | 1844 | c->decl_table.put(record_decl->getCanonicalDecl(), symbol_node); |
| 840 | Buf *bare_name = buf_create_from_str(decl_name(enum_decl)); | 1845 | return symbol_node; |
| 841 | | | |
| 842 | Tld *tld = add_container_tld(c, enum_type); | | |
| 843 | add_global_weak_alias(c, bare_name, tld); | | |
| 844 | } | 1846 | } |
| 845 | | 1847 | |
| 846 | static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl) { | 1848 | static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) { |
| 847 | auto existing_entry = c->decl_table.maybe_get((void*)record_decl); | 1849 | auto existing_entry = c->decl_table.maybe_get((void*)record_decl->getCanonicalDecl()); |
| 848 | if (existing_entry) { | 1850 | if (existing_entry) { |
| 849 | return existing_entry->value; | 1851 | return existing_entry->value; |
| 850 | } | 1852 | } |
| ... | @@ -852,36 +1854,20 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ | ... | @@ -852,36 +1854,20 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 852 | const char *raw_name = decl_name(record_decl); | 1854 | const char *raw_name = decl_name(record_decl); |
| 853 | | 1855 | |
| 854 | if (!record_decl->isStruct()) { | 1856 | if (!record_decl->isStruct()) { |
| 855 | emit_warning(c, record_decl, "skipping record %s, not a struct", raw_name); | 1857 | emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name); |
| 856 | return c->codegen->builtin_types.entry_invalid; | 1858 | c->decl_table.put(record_decl->getCanonicalDecl(), nullptr); |
| 857 | } | 1859 | return nullptr; |
| 858 | | | |
| 859 | Buf *bare_name; | | |
| 860 | if (record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0) { | | |
| 861 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_anon_index(c)); | | |
| 862 | } else { | | |
| 863 | bare_name = buf_create_from_str(raw_name); | | |
| 864 | } | 1860 | } |
| 865 | | 1861 | |
| 866 | Buf *full_type_name = buf_sprintf("struct_%s", buf_ptr(bare_name)); | 1862 | bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0; |
| 867 | | 1863 | Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name); |
| 868 | | 1864 | Buf *full_type_name = (bare_name == nullptr) ? nullptr : buf_sprintf("struct_%s", buf_ptr(bare_name)); |
| 869 | TypeTableEntry *struct_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, | | |
| 870 | ContainerKindStruct, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern); | | |
| 871 | struct_type->data.structure.zero_bits_known = true; | | |
| 872 | struct_type->data.structure.abi_alignment = 1; | | |
| 873 | | | |
| 874 | c->struct_type_table.put(bare_name, struct_type); | | |
| 875 | c->decl_table.put(record_decl, struct_type); | | |
| 876 | | 1865 | |
| 877 | RecordDecl *record_def = record_decl->getDefinition(); | 1866 | RecordDecl *record_def = record_decl->getDefinition(); |
| 878 | unsigned line = c->source_node ? c->source_node->line : 0; | 1867 | if (record_def == nullptr) { |
| 879 | if (!record_def) { | 1868 | return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name); |
| 880 | replace_with_fwd_decl(c, struct_type, full_type_name); | | |
| 881 | return struct_type; | | |
| 882 | } | 1869 | } |
| 883 | | 1870 | |
| 884 | | | |
| 885 | // count fields and validate | 1871 | // count fields and validate |
| 886 | uint32_t field_count = 0; | 1872 | uint32_t field_count = 0; |
| 887 | for (auto it = record_def->field_begin(), | 1873 | for (auto it = record_def->field_begin(), |
| ... | @@ -891,105 +1877,56 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ | ... | @@ -891,105 +1877,56 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 891 | const FieldDecl *field_decl = *it; | 1877 | const FieldDecl *field_decl = *it; |
| 892 | | 1878 | |
| 893 | if (field_decl->isBitField()) { | 1879 | if (field_decl->isBitField()) { |
| 894 | emit_warning(c, field_decl, "struct %s demoted to opaque type - has bitfield\n", buf_ptr(bare_name)); | 1880 | emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield", |
| 895 | replace_with_fwd_decl(c, struct_type, full_type_name); | 1881 | is_anonymous ? "(anon)" : buf_ptr(bare_name)); |
| 896 | return struct_type; | 1882 | return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name); |
| 897 | } | 1883 | } |
| 898 | } | 1884 | } |
| 899 | | 1885 | |
| 900 | struct_type->data.structure.src_field_count = field_count; | 1886 | AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl); |
| 901 | struct_type->data.structure.fields = allocate<TypeStructField>(field_count); | 1887 | struct_node->data.container_decl.kind = ContainerKindStruct; |
| 902 | LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count); | 1888 | struct_node->data.container_decl.layout = ContainerLayoutExtern; |
| 903 | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count); | | |
| 904 | | 1889 | |
| 905 | // next, populate element_types as its needed for LLVMStructSetBody which is needed for LLVMOffsetOfElement | 1890 | // TODO handle attribute packed |
| 906 | uint32_t i = 0; | | |
| 907 | for (auto it = record_def->field_begin(), | | |
| 908 | it_end = record_def->field_end(); | | |
| 909 | it != it_end; ++it, i += 1) | | |
| 910 | { | | |
| 911 | const FieldDecl *field_decl = *it; | | |
| 912 | | 1891 | |
| 913 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; | 1892 | struct_node->data.container_decl.fields.resize(field_count); |
| 914 | type_struct_field->name = buf_create_from_str(decl_name(field_decl)); | | |
| 915 | type_struct_field->src_index = i; | | |
| 916 | type_struct_field->gen_index = i; | | |
| 917 | TypeTableEntry *field_type = resolve_qual_type(c, field_decl->getType(), field_decl); | | |
| 918 | type_struct_field->type_entry = field_type; | | |
| 919 | | | |
| 920 | if (type_is_invalid(field_type) || !type_is_complete(field_type)) { | | |
| 921 | emit_warning(c, field_decl, "struct %s demoted to opaque type - unresolved type\n", buf_ptr(bare_name)); | | |
| 922 | replace_with_fwd_decl(c, struct_type, full_type_name); | | |
| 923 | return struct_type; | | |
| 924 | } | | |
| 925 | | 1893 | |
| 926 | element_types[i] = field_type->type_ref; | 1894 | // must be before fields in case a circular reference happens |
| 927 | assert(element_types[i]); | 1895 | if (is_anonymous) { |
| | 1896 | c->decl_table.put(record_decl->getCanonicalDecl(), struct_node); |
| | 1897 | } else { |
| | 1898 | c->decl_table.put(record_decl->getCanonicalDecl(), trans_create_node_symbol(c, full_type_name)); |
| 928 | } | 1899 | } |
| 929 | | 1900 | |
| 930 | LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false); | 1901 | uint32_t i = 0; |
| 931 | | | |
| 932 | // finally populate debug info | | |
| 933 | i = 0; | | |
| 934 | for (auto it = record_def->field_begin(), | 1902 | for (auto it = record_def->field_begin(), |
| 935 | it_end = record_def->field_end(); | 1903 | it_end = record_def->field_end(); |
| 936 | it != it_end; ++it, i += 1) | 1904 | it != it_end; ++it, i += 1) |
| 937 | { | 1905 | { |
| 938 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; | 1906 | const FieldDecl *field_decl = *it; |
| 939 | TypeTableEntry *field_type = type_struct_field->type_entry; | | |
| 940 | | | |
| 941 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, field_type->type_ref); | | |
| 942 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, field_type->type_ref); | | |
| 943 | uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(c->codegen->target_data_ref, struct_type->type_ref, i); | | |
| 944 | di_element_types[i] = ZigLLVMCreateDebugMemberType(c->codegen->dbuilder, | | |
| 945 | ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name), | | |
| 946 | c->import->di_file, line + 1, | | |
| 947 | debug_size_in_bits, | | |
| 948 | debug_align_in_bits, | | |
| 949 | debug_offset_in_bits, | | |
| 950 | 0, field_type->di_type); | | |
| 951 | | | |
| 952 | assert(di_element_types[i]); | | |
| 953 | | 1907 | |
| 954 | } | 1908 | AstNode *field_node = trans_create_node(c, NodeTypeStructField); |
| 955 | struct_type->data.structure.embedded_in_current = false; | 1909 | field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl)); |
| 956 | | 1910 | field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), field_decl->getLocation()); |
| 957 | struct_type->data.structure.gen_field_count = field_count; | | |
| 958 | struct_type->data.structure.complete = true; | | |
| 959 | struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref, | | |
| 960 | struct_type->type_ref); | | |
| 961 | | | |
| 962 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, struct_type->type_ref); | | |
| 963 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, struct_type->type_ref); | | |
| 964 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(c->codegen->dbuilder, | | |
| 965 | ZigLLVMFileToScope(c->import->di_file), | | |
| 966 | buf_ptr(full_type_name), c->import->di_file, line + 1, | | |
| 967 | debug_size_in_bits, | | |
| 968 | debug_align_in_bits, | | |
| 969 | 0, | | |
| 970 | nullptr, di_element_types, field_count, 0, nullptr, ""); | | |
| 971 | | | |
| 972 | ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type); | | |
| 973 | struct_type->di_type = replacement_di_type; | | |
| 974 | | | |
| 975 | return struct_type; | | |
| 976 | } | | |
| 977 | | 1911 | |
| 978 | static void visit_record_decl(Context *c, const RecordDecl *record_decl) { | 1912 | if (field_node->data.struct_field.type == nullptr) { |
| 979 | TypeTableEntry *struct_type = resolve_record_decl(c, record_decl); | 1913 | emit_warning(c, field_decl->getLocation(), |
| | 1914 | "struct %s demoted to opaque type - unresolved type", |
| | 1915 | is_anonymous ? "(anon)" : buf_ptr(bare_name)); |
| 980 | | 1916 | |
| 981 | if (struct_type->id == TypeTableEntryIdInvalid) { | 1917 | return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name); |
| 982 | return; | 1918 | } |
| 983 | } | | |
| 984 | | | |
| 985 | bool is_anonymous = (record_decl->isAnonymousStructOrUnion() || decl_name(record_decl)[0] == 0); | | |
| 986 | if (is_anonymous) | | |
| 987 | return; | | |
| 988 | | 1919 | |
| 989 | Buf *bare_name = buf_create_from_str(decl_name(record_decl)); | 1920 | struct_node->data.container_decl.fields.items[i] = field_node; |
| | 1921 | } |
| 990 | | 1922 | |
| 991 | Tld *tld = add_container_tld(c, struct_type); | 1923 | if (is_anonymous) { |
| 992 | add_global_weak_alias(c, bare_name, tld); | 1924 | return struct_node; |
| | 1925 | } else { |
| | 1926 | add_global_weak_alias(c, bare_name, full_type_name); |
| | 1927 | add_global_var(c, full_type_name, struct_node); |
| | 1928 | return trans_create_node_symbol(c, full_type_name); |
| | 1929 | } |
| 993 | } | 1930 | } |
| 994 | | 1931 | |
| 995 | static void visit_var_decl(Context *c, const VarDecl *var_decl) { | 1932 | static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| ... | @@ -999,17 +1936,19 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { | ... | @@ -999,17 +1936,19 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| 999 | case VarDecl::TLS_None: | 1936 | case VarDecl::TLS_None: |
| 1000 | break; | 1937 | break; |
| 1001 | case VarDecl::TLS_Static: | 1938 | case VarDecl::TLS_Static: |
| 1002 | emit_warning(c, var_decl, "ignoring variable '%s' - static thread local storage\n", buf_ptr(name)); | 1939 | emit_warning(c, var_decl->getLocation(), |
| | 1940 | "ignoring variable '%s' - static thread local storage", buf_ptr(name)); |
| 1003 | return; | 1941 | return; |
| 1004 | case VarDecl::TLS_Dynamic: | 1942 | case VarDecl::TLS_Dynamic: |
| 1005 | emit_warning(c, var_decl, "ignoring variable '%s' - dynamic thread local storage\n", buf_ptr(name)); | 1943 | emit_warning(c, var_decl->getLocation(), |
| | 1944 | "ignoring variable '%s' - dynamic thread local storage", buf_ptr(name)); |
| 1006 | return; | 1945 | return; |
| 1007 | } | 1946 | } |
| 1008 | | 1947 | |
| 1009 | QualType qt = var_decl->getType(); | 1948 | QualType qt = var_decl->getType(); |
| 1010 | TypeTableEntry *var_type = resolve_qual_type(c, qt, var_decl); | 1949 | AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation()); |
| 1011 | if (var_type->id == TypeTableEntryIdInvalid) { | 1950 | if (var_type == nullptr) { |
| 1012 | emit_warning(c, var_decl, "ignoring variable '%s' - unresolved type\n", buf_ptr(name)); | 1951 | emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name)); |
| 1013 | return; | 1952 | return; |
| 1014 | } | 1953 | } |
| 1015 | | 1954 | |
| ... | @@ -1018,59 +1957,53 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { | ... | @@ -1018,59 +1957,53 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| 1018 | bool is_const = qt.isConstQualified(); | 1957 | bool is_const = qt.isConstQualified(); |
| 1019 | | 1958 | |
| 1020 | if (is_static && !is_extern) { | 1959 | if (is_static && !is_extern) { |
| 1021 | if (!var_decl->hasInit()) { | 1960 | AstNode *init_node; |
| 1022 | emit_warning(c, var_decl, "ignoring variable '%s' - no initializer\n", buf_ptr(name)); | 1961 | if (var_decl->hasInit()) { |
| 1023 | return; | 1962 | APValue *ap_value = var_decl->evaluateValue(); |
| 1024 | } | 1963 | if (ap_value == nullptr) { |
| 1025 | APValue *ap_value = var_decl->evaluateValue(); | 1964 | emit_warning(c, var_decl->getLocation(), |
| 1026 | if (!ap_value) { | 1965 | "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name)); |
| 1027 | emit_warning(c, var_decl, "ignoring variable '%s' - unable to evaluate initializer\n", buf_ptr(name)); | | |
| 1028 | return; | | |
| 1029 | } | | |
| 1030 | ConstExprValue *init_value = nullptr; | | |
| 1031 | switch (ap_value->getKind()) { | | |
| 1032 | case APValue::Int: | | |
| 1033 | { | | |
| 1034 | if (var_type->id != TypeTableEntryIdInt) { | | |
| 1035 | emit_warning(c, var_decl, | | |
| 1036 | "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name)); | | |
| 1037 | return; | | |
| 1038 | } | | |
| 1039 | init_value = create_const_int_ap(c, var_type, var_decl, ap_value->getInt()); | | |
| 1040 | if (!init_value) | | |
| 1041 | return; | | |
| 1042 | | | |
| 1043 | break; | | |
| 1044 | } | | |
| 1045 | case APValue::Uninitialized: | | |
| 1046 | case APValue::Float: | | |
| 1047 | case APValue::ComplexInt: | | |
| 1048 | case APValue::ComplexFloat: | | |
| 1049 | case APValue::LValue: | | |
| 1050 | case APValue::Vector: | | |
| 1051 | case APValue::Array: | | |
| 1052 | case APValue::Struct: | | |
| 1053 | case APValue::Union: | | |
| 1054 | case APValue::MemberPointer: | | |
| 1055 | case APValue::AddrLabelDiff: | | |
| 1056 | emit_warning(c, var_decl, | | |
| 1057 | "ignoring variable '%s' - unrecognized initializer value kind\n", buf_ptr(name)); | | |
| 1058 | return; | 1966 | return; |
| | 1967 | } |
| | 1968 | switch (ap_value->getKind()) { |
| | 1969 | case APValue::Int: |
| | 1970 | init_node = trans_create_node_apint(c, ap_value->getInt()); |
| | 1971 | break; |
| | 1972 | case APValue::Uninitialized: |
| | 1973 | init_node = trans_create_node_symbol_str(c, "undefined"); |
| | 1974 | break; |
| | 1975 | case APValue::Float: |
| | 1976 | case APValue::ComplexInt: |
| | 1977 | case APValue::ComplexFloat: |
| | 1978 | case APValue::LValue: |
| | 1979 | case APValue::Vector: |
| | 1980 | case APValue::Array: |
| | 1981 | case APValue::Struct: |
| | 1982 | case APValue::Union: |
| | 1983 | case APValue::MemberPointer: |
| | 1984 | case APValue::AddrLabelDiff: |
| | 1985 | emit_warning(c, var_decl->getLocation(), |
| | 1986 | "ignoring variable '%s' - unrecognized initializer value kind", buf_ptr(name)); |
| | 1987 | return; |
| | 1988 | } |
| | 1989 | } else { |
| | 1990 | init_node = trans_create_node_symbol_str(c, "undefined"); |
| 1059 | } | 1991 | } |
| 1060 | | 1992 | |
| 1061 | TldVar *tld_var = create_global_var(c, name, init_value, true); | 1993 | AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, init_node); |
| 1062 | add_global(c, &tld_var->base); | 1994 | c->root->data.root.top_level_decls.append(var_node); |
| 1063 | return; | 1995 | return; |
| 1064 | } | 1996 | } |
| 1065 | | 1997 | |
| 1066 | if (is_extern) { | 1998 | if (is_extern) { |
| 1067 | TldVar *tld_var = create_global_var(c, name, create_const_runtime(var_type), is_const); | 1999 | AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, nullptr); |
| 1068 | tld_var->var->linkage = VarLinkageExternal; | 2000 | var_node->data.variable_declaration.is_extern = true; |
| 1069 | add_global(c, &tld_var->base); | 2001 | c->root->data.root.top_level_decls.append(var_node); |
| 1070 | return; | 2002 | return; |
| 1071 | } | 2003 | } |
| 1072 | | 2004 | |
| 1073 | emit_warning(c, var_decl, "ignoring variable '%s' - non-extern, non-static variable\n", buf_ptr(name)); | 2005 | emit_warning(c, var_decl->getLocation(), |
| | 2006 | "ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name)); |
| 1074 | return; | 2007 | return; |
| 1075 | } | 2008 | } |
| 1076 | | 2009 | |
| ... | @@ -1082,44 +2015,35 @@ static bool decl_visitor(void *context, const Decl *decl) { | ... | @@ -1082,44 +2015,35 @@ static bool decl_visitor(void *context, const Decl *decl) { |
| 1082 | visit_fn_decl(c, static_cast<const FunctionDecl*>(decl)); | 2015 | visit_fn_decl(c, static_cast<const FunctionDecl*>(decl)); |
| 1083 | break; | 2016 | break; |
| 1084 | case Decl::Typedef: | 2017 | case Decl::Typedef: |
| 1085 | visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl)); | 2018 | resolve_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl)); |
| 1086 | break; | 2019 | break; |
| 1087 | case Decl::Enum: | 2020 | case Decl::Enum: |
| 1088 | visit_enum_decl(c, static_cast<const EnumDecl *>(decl)); | 2021 | resolve_enum_decl(c, static_cast<const EnumDecl *>(decl)); |
| 1089 | break; | 2022 | break; |
| 1090 | case Decl::Record: | 2023 | case Decl::Record: |
| 1091 | visit_record_decl(c, static_cast<const RecordDecl *>(decl)); | 2024 | resolve_record_decl(c, static_cast<const RecordDecl *>(decl)); |
| 1092 | break; | 2025 | break; |
| 1093 | case Decl::Var: | 2026 | case Decl::Var: |
| 1094 | visit_var_decl(c, static_cast<const VarDecl *>(decl)); | 2027 | visit_var_decl(c, static_cast<const VarDecl *>(decl)); |
| 1095 | break; | 2028 | break; |
| 1096 | default: | 2029 | default: |
| 1097 | emit_warning(c, decl, "ignoring %s decl\n", decl->getDeclKindName()); | 2030 | emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName()); |
| 1098 | } | 2031 | } |
| 1099 | | 2032 | |
| 1100 | return true; | 2033 | return true; |
| 1101 | } | 2034 | } |
| 1102 | | 2035 | |
| 1103 | static bool name_exists(Context *c, Buf *name) { | 2036 | static bool name_exists(Context *c, Buf *name) { |
| 1104 | if (c->global_type_table.maybe_get(name)) { | 2037 | return get_global(c, name) != nullptr; |
| 1105 | return true; | | |
| 1106 | } | | |
| 1107 | if (get_global(c, name)) { | | |
| 1108 | return true; | | |
| 1109 | } | | |
| 1110 | if (c->macro_table.maybe_get(name)) { | | |
| 1111 | return true; | | |
| 1112 | } | | |
| 1113 | return false; | | |
| 1114 | } | 2038 | } |
| 1115 | | 2039 | |
| 1116 | static void render_aliases(Context *c) { | 2040 | static void render_aliases(Context *c) { |
| 1117 | for (size_t i = 0; i < c->aliases.length; i += 1) { | 2041 | for (size_t i = 0; i < c->aliases.length; i += 1) { |
| 1118 | Alias *alias = &c->aliases.at(i); | 2042 | Alias *alias = &c->aliases.at(i); |
| 1119 | if (name_exists(c, alias->name)) | 2043 | if (name_exists(c, alias->new_name)) |
| 1120 | continue; | 2044 | continue; |
| 1121 | | 2045 | |
| 1122 | add_global_alias(c, alias->name, alias->tld); | 2046 | add_global_var(c, alias->new_name, trans_create_node_symbol(c, alias->canon_name)); |
| 1123 | } | 2047 | } |
| 1124 | } | 2048 | } |
| 1125 | | 2049 | |
| ... | @@ -1130,8 +2054,12 @@ static void render_macros(Context *c) { | ... | @@ -1130,8 +2054,12 @@ static void render_macros(Context *c) { |
| 1130 | if (!entry) | 2054 | if (!entry) |
| 1131 | break; | 2055 | break; |
| 1132 | | 2056 | |
| 1133 | Tld *var_tld = entry->value; | 2057 | AstNode *value_node = entry->value; |
| 1134 | add_global(c, var_tld); | 2058 | if (value_node->type == NodeTypeFnDef) { |
| | 2059 | c->root->data.root.top_level_decls.append(value_node); |
| | 2060 | } else { |
| | 2061 | add_global_var(c, entry->key, value_node); |
| | 2062 | } |
| 1135 | } | 2063 | } |
| 1136 | } | 2064 | } |
| 1137 | | 2065 | |
| ... | @@ -1150,52 +2078,52 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch | ... | @@ -1150,52 +2078,52 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch |
| 1150 | switch (tok->id) { | 2078 | switch (tok->id) { |
| 1151 | case CTokIdCharLit: | 2079 | case CTokIdCharLit: |
| 1152 | if (is_last && is_first) { | 2080 | if (is_last && is_first) { |
| 1153 | Tld *tld = create_global_num_lit_unsigned_negative(c, name, tok->data.char_lit, false); | 2081 | AstNode *node = trans_create_node_unsigned(c, tok->data.char_lit); |
| 1154 | c->macro_table.put(name, tld); | 2082 | c->macro_table.put(name, node); |
| 1155 | } | 2083 | } |
| 1156 | return; | 2084 | return; |
| 1157 | case CTokIdStrLit: | 2085 | case CTokIdStrLit: |
| 1158 | if (is_last && is_first) { | 2086 | if (is_last && is_first) { |
| 1159 | Tld *tld = create_global_str_lit_var(c, name, buf_create_from_buf(&tok->data.str_lit)); | 2087 | AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit)); |
| 1160 | c->macro_table.put(name, tld); | 2088 | c->macro_table.put(name, node); |
| 1161 | } | 2089 | } |
| 1162 | return; | 2090 | return; |
| 1163 | case CTokIdNumLitInt: | 2091 | case CTokIdNumLitInt: |
| 1164 | if (is_last) { | 2092 | if (is_last) { |
| 1165 | Tld *tld; | 2093 | AstNode *node; |
| 1166 | switch (tok->data.num_lit_int.suffix) { | 2094 | switch (tok->data.num_lit_int.suffix) { |
| 1167 | case CNumLitSuffixNone: | 2095 | case CNumLitSuffixNone: |
| 1168 | 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); |
| 1169 | break; | 2097 | break; |
| 1170 | case CNumLitSuffixL: | 2098 | case CNumLitSuffixL: |
| 1171 | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, | 2099 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 1172 | c->codegen->builtin_types.entry_c_int[CIntTypeLong]); | 2100 | "c_long"); |
| 1173 | break; | 2101 | break; |
| 1174 | case CNumLitSuffixU: | 2102 | case CNumLitSuffixU: |
| 1175 | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, | 2103 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 1176 | c->codegen->builtin_types.entry_c_int[CIntTypeUInt]); | 2104 | "c_uint"); |
| 1177 | break; | 2105 | break; |
| 1178 | case CNumLitSuffixLU: | 2106 | case CNumLitSuffixLU: |
| 1179 | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, | 2107 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 1180 | c->codegen->builtin_types.entry_c_int[CIntTypeULong]); | 2108 | "c_ulong"); |
| 1181 | break; | 2109 | break; |
| 1182 | case CNumLitSuffixLL: | 2110 | case CNumLitSuffixLL: |
| 1183 | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, | 2111 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 1184 | c->codegen->builtin_types.entry_c_int[CIntTypeLongLong]); | 2112 | "c_longlong"); |
| 1185 | break; | 2113 | break; |
| 1186 | case CNumLitSuffixLLU: | 2114 | case CNumLitSuffixLLU: |
| 1187 | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, | 2115 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 1188 | c->codegen->builtin_types.entry_c_int[CIntTypeULongLong]); | 2116 | "c_ulonglong"); |
| 1189 | break; | 2117 | break; |
| 1190 | } | 2118 | } |
| 1191 | c->macro_table.put(name, tld); | 2119 | c->macro_table.put(name, node); |
| 1192 | } | 2120 | } |
| 1193 | return; | 2121 | return; |
| 1194 | case CTokIdNumLitFloat: | 2122 | case CTokIdNumLitFloat: |
| 1195 | if (is_last) { | 2123 | if (is_last) { |
| 1196 | double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float; | 2124 | double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float; |
| 1197 | Tld *tld = create_global_num_lit_float(c, name, value); | 2125 | AstNode *node = trans_create_node_float_lit(c, value); |
| 1198 | c->macro_table.put(name, tld); | 2126 | c->macro_table.put(name, node); |
| 1199 | } | 2127 | } |
| 1200 | return; | 2128 | return; |
| 1201 | case CTokIdSymbol: | 2129 | case CTokIdSymbol: |
| ... | @@ -1224,35 +2152,37 @@ static void process_symbol_macros(Context *c) { | ... | @@ -1224,35 +2152,37 @@ static void process_symbol_macros(Context *c) { |
| 1224 | for (size_t i = 0; i < c->macro_symbols.length; i += 1) { | 2152 | for (size_t i = 0; i < c->macro_symbols.length; i += 1) { |
| 1225 | MacroSymbol ms = c->macro_symbols.at(i); | 2153 | MacroSymbol ms = c->macro_symbols.at(i); |
| 1226 | | 2154 | |
| 1227 | // If this macro aliases another top level declaration, we can make that happen by | 2155 | // Check if this macro aliases another top level declaration |
| 1228 | // putting another entry in the decl table pointing to the same top level decl. | 2156 | AstNode *existing_node = get_global(c, ms.value); |
| 1229 | Tld *existing_tld = get_global(c, ms.value); | 2157 | if (!existing_node || name_exists(c, ms.name)) |
| 1230 | if (!existing_tld) | | |
| 1231 | continue; | 2158 | continue; |
| 1232 | | 2159 | |
| 1233 | // If a macro aliases a global variable which is a function pointer, we conclude that | 2160 | // If a macro aliases a global variable which is a function pointer, we conclude that |
| 1234 | // the macro is intended to represent a function that assumes the function pointer | 2161 | // the macro is intended to represent a function that assumes the function pointer |
| 1235 | // variable is non-null and calls it. | 2162 | // variable is non-null and calls it. |
| 1236 | if (existing_tld->id == TldIdVar) { | 2163 | if (existing_node->type == NodeTypeVariableDeclaration) { |
| 1237 | TldVar *tld_var = (TldVar *)existing_tld; | 2164 | AstNode *var_type = existing_node->data.variable_declaration.type; |
| 1238 | TypeTableEntry *var_type = tld_var->var->value->type; | 2165 | if (var_type != nullptr && var_type->type == NodeTypePrefixOpExpr && |
| 1239 | if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) { | 2166 | var_type->data.prefix_op_expr.prefix_op == PrefixOpMaybe) |
| 1240 | TypeTableEntry *child_type = var_type->data.maybe.child_type; | 2167 | { |
| 1241 | if (child_type->id == TypeTableEntryIdFn) { | 2168 | AstNode *fn_proto_node = var_type->data.prefix_op_expr.primary_expr; |
| 1242 | Tld *tld = create_inline_fn_tld(c, ms.name, tld_var); | 2169 | if (fn_proto_node->type == NodeTypeFnProto) { |
| 1243 | c->macro_table.put(ms.name, tld); | 2170 | AstNode *inline_fn_node = trans_create_node_inline_fn(c, ms.name, ms.value, fn_proto_node); |
| | 2171 | c->macro_table.put(ms.name, inline_fn_node); |
| 1244 | continue; | 2172 | continue; |
| 1245 | } | 2173 | } |
| 1246 | } | 2174 | } |
| 1247 | } | 2175 | } |
| 1248 | | 2176 | |
| 1249 | add_global_alias(c, ms.name, existing_tld); | 2177 | add_global_var(c, ms.name, trans_create_node_symbol(c, ms.value)); |
| 1250 | } | 2178 | } |
| 1251 | } | 2179 | } |
| 1252 | | 2180 | |
| 1253 | static void process_preprocessor_entities(Context *c, ASTUnit &unit) { | 2181 | static void process_preprocessor_entities(Context *c, ASTUnit &unit) { |
| 1254 | CTokenize ctok = {{0}}; | 2182 | CTokenize ctok = {{0}}; |
| 1255 | | 2183 | |
| | 2184 | // TODO if we see #undef, delete it from the table |
| | 2185 | |
| 1256 | for (PreprocessedEntity *entity : unit.getLocalPreprocessingEntities()) { | 2186 | for (PreprocessedEntity *entity : unit.getLocalPreprocessingEntities()) { |
| 1257 | switch (entity->getKind()) { | 2187 | switch (entity->getKind()) { |
| 1258 | case PreprocessedEntity::InvalidKind: | 2188 | case PreprocessedEntity::InvalidKind: |
| ... | @@ -1309,9 +2239,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1309,9 +2239,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1309 | c->import = import; | 2239 | c->import = import; |
| 1310 | c->errors = errors; | 2240 | c->errors = errors; |
| 1311 | c->visib_mod = VisibModPub; | 2241 | c->visib_mod = VisibModPub; |
| 1312 | c->global_type_table.init(8); | | |
| 1313 | c->enum_type_table.init(8); | | |
| 1314 | c->struct_type_table.init(8); | | |
| 1315 | c->decl_table.init(8); | 2242 | c->decl_table.init(8); |
| 1316 | c->macro_table.init(8); | 2243 | c->macro_table.init(8); |
| 1317 | c->codegen = codegen; | 2244 | c->codegen = codegen; |
| ... | @@ -1373,7 +2300,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1373,7 +2300,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1373 | | 2300 | |
| 1374 | std::shared_ptr<PCHContainerOperations> pch_container_ops = std::make_shared<PCHContainerOperations>(); | 2301 | std::shared_ptr<PCHContainerOperations> pch_container_ops = std::make_shared<PCHContainerOperations>(); |
| 1375 | | 2302 | |
| 1376 | bool skip_function_bodies = true; | 2303 | bool skip_function_bodies = false; |
| 1377 | bool only_local_decls = true; | 2304 | bool only_local_decls = true; |
| 1378 | bool capture_diagnostics = true; | 2305 | bool capture_diagnostics = true; |
| 1379 | bool user_files_are_volatile = true; | 2306 | bool user_files_are_volatile = true; |
| ... | @@ -1390,7 +2317,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1390,7 +2317,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1390 | single_file_parse, user_files_are_volatile, for_serialization, None, &err_unit, | 2317 | single_file_parse, user_files_are_volatile, for_serialization, None, &err_unit, |
| 1391 | nullptr)); | 2318 | nullptr)); |
| 1392 | | 2319 | |
| 1393 | | | |
| 1394 | // Early failures in LoadFromCommandLine may return with ErrUnit unset. | 2320 | // Early failures in LoadFromCommandLine may return with ErrUnit unset. |
| 1395 | if (!ast_unit && !err_unit) { | 2321 | if (!ast_unit && !err_unit) { |
| 1396 | return ErrorFileSystem; | 2322 | return ErrorFileSystem; |
| ... | @@ -1416,39 +2342,48 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -1416,39 +2342,48 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1416 | break; | 2342 | break; |
| 1417 | } | 2343 | } |
| 1418 | StringRef msg_str_ref = it->getMessage(); | 2344 | StringRef msg_str_ref = it->getMessage(); |
| 1419 | FullSourceLoc fsl = it->getLocation(); | | |
| 1420 | FileID file_id = fsl.getFileID(); | | |
| 1421 | StringRef filename = fsl.getManager().getFilename(fsl); | | |
| 1422 | unsigned line = fsl.getSpellingLineNumber() - 1; | | |
| 1423 | unsigned column = fsl.getSpellingColumnNumber() - 1; | | |
| 1424 | unsigned offset = fsl.getManager().getFileOffset(fsl); | | |
| 1425 | const char *source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin(); | | |
| 1426 | Buf *msg = buf_create_from_str((const char *)msg_str_ref.bytes_begin()); | 2345 | Buf *msg = buf_create_from_str((const char *)msg_str_ref.bytes_begin()); |
| 1427 | Buf *path; | 2346 | FullSourceLoc fsl = it->getLocation(); |
| 1428 | if (filename.empty()) { | 2347 | if (fsl.hasManager()) { |
| 1429 | path = buf_alloc(); | 2348 | FileID file_id = fsl.getFileID(); |
| 1430 | } else { | 2349 | StringRef filename = fsl.getManager().getFilename(fsl); |
| 1431 | path = buf_create_from_mem((const char *)filename.bytes_begin(), filename.size()); | 2350 | unsigned line = fsl.getSpellingLineNumber() - 1; |
| 1432 | } | 2351 | unsigned column = fsl.getSpellingColumnNumber() - 1; |
| | 2352 | unsigned offset = fsl.getManager().getFileOffset(fsl); |
| | 2353 | const char *source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin(); |
| | 2354 | Buf *path; |
| | 2355 | if (filename.empty()) { |
| | 2356 | path = buf_alloc(); |
| | 2357 | } else { |
| | 2358 | path = buf_create_from_mem((const char *)filename.bytes_begin(), filename.size()); |
| | 2359 | } |
| 1433 | | 2360 | |
| 1434 | ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg); | 2361 | ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg); |
| 1435 | | 2362 | |
| 1436 | c->errors->append(err_msg); | 2363 | c->errors->append(err_msg); |
| | 2364 | } else { |
| | 2365 | // NOTE the only known way this gets triggered right now is if you have a lot of errors |
| | 2366 | // clang emits "too many errors emitted, stopping now" |
| | 2367 | fprintf(stderr, "unexpected error from clang: %s\n", buf_ptr(msg)); |
| | 2368 | } |
| 1437 | } | 2369 | } |
| 1438 | | 2370 | |
| 1439 | return 0; | 2371 | return 0; |
| 1440 | } | 2372 | } |
| 1441 | | 2373 | |
| | 2374 | c->ctx = &ast_unit->getASTContext(); |
| 1442 | c->source_manager = &ast_unit->getSourceManager(); | 2375 | c->source_manager = &ast_unit->getSourceManager(); |
| | 2376 | c->root = trans_create_node(c, NodeTypeRoot); |
| 1443 | | 2377 | |
| 1444 | ast_unit->visitLocalTopLevelDecls(c, decl_visitor); | 2378 | ast_unit->visitLocalTopLevelDecls(c, decl_visitor); |
| 1445 | | 2379 | |
| 1446 | process_preprocessor_entities(c, *ast_unit); | 2380 | process_preprocessor_entities(c, *ast_unit); |
| 1447 | | 2381 | |
| 1448 | process_symbol_macros(c); | 2382 | process_symbol_macros(c); |
| 1449 | | | |
| 1450 | render_macros(c); | 2383 | render_macros(c); |
| 1451 | render_aliases(c); | 2384 | render_aliases(c); |
| 1452 | | 2385 | |
| | 2386 | import->root = c->root; |
| | 2387 | |
| 1453 | return 0; | 2388 | return 0; |
| 1454 | } | 2389 | } |