| ... | ... | @@ -15,8 +15,10 @@ |
| 15 | 15 | #include "parseh.hpp" |
| 16 | 16 | #include "parser.hpp" |
| 17 | 17 | |
| 18 | |
| 18 | 19 | #include <clang/Frontend/ASTUnit.h> |
| 19 | 20 | #include <clang/Frontend/CompilerInstance.h> |
| 21 | #include <clang/AST/Expr.h> |
| 20 | 22 | |
| 21 | 23 | #include <string.h> |
| 22 | 24 | |
| ... | ... | @@ -27,14 +29,9 @@ struct MacroSymbol { |
| 27 | 29 | Buf *value; |
| 28 | 30 | }; |
| 29 | 31 | |
| 30 | | struct GlobalValue { |
| 31 | | TypeTableEntry *type; |
| 32 | | bool is_const; |
| 33 | | }; |
| 34 | | |
| 35 | 32 | struct Alias { |
| 36 | | Buf *name; |
| 37 | | Tld *tld; |
| 33 | Buf *new_name; |
| 34 | Buf *canon_name; |
| 38 | 35 | }; |
| 39 | 36 | |
| 40 | 37 | struct Context { |
| ... | ... | @@ -42,30 +39,27 @@ struct Context { |
| 42 | 39 | ZigList<ErrorMsg *> *errors; |
| 43 | 40 | bool warnings_on; |
| 44 | 41 | VisibMod visib_mod; |
| 45 | | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> global_type_table; |
| 46 | | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table; |
| 47 | | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table; |
| 48 | | HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table; |
| 49 | | HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> macro_table; |
| 42 | AstNode *root; |
| 43 | HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table; |
| 44 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; |
| 50 | 45 | SourceManager *source_manager; |
| 51 | 46 | ZigList<Alias> aliases; |
| 52 | 47 | ZigList<MacroSymbol> macro_symbols; |
| 53 | 48 | AstNode *source_node; |
| 54 | | uint32_t next_anon_index; |
| 55 | 49 | |
| 56 | 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, |
| 60 | | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table); |
| 61 | | |
| 62 | | static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl); |
| 63 | | static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl); |
| 64 | | static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); |
| 54 | static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl); |
| 55 | static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); |
| 56 | static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl); |
| 57 | static AstNode *trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc); |
| 58 | static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc); |
| 65 | 59 | |
| 66 | 60 | |
| 67 | 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 | 63 | if (!c->warnings_on) { |
| 70 | 64 | return; |
| 71 | 65 | } |
| ... | ... | @@ -75,8 +69,6 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...) |
| 75 | 69 | Buf *msg = buf_vprintf(format, ap); |
| 76 | 70 | va_end(ap); |
| 77 | 71 | |
| 78 | | SourceLocation sl = decl->getLocation(); |
| 79 | | |
| 80 | 72 | StringRef filename = c->source_manager->getFilename(sl); |
| 81 | 73 | const char *filename_bytes = (const char *)filename.bytes_begin(); |
| 82 | 74 | Buf *path; |
| ... | ... | @@ -90,141 +82,214 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...) |
| 90 | 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) { |
| 94 | | uint32_t result = c->next_anon_index; |
| 95 | | c->next_anon_index += 1; |
| 96 | | return result; |
| 85 | static void add_global_weak_alias(Context *c, Buf *new_name, Buf *canon_name) { |
| 86 | Alias *alias = c->aliases.add_one(); |
| 87 | alias->new_name = new_name; |
| 88 | alias->canon_name = canon_name; |
| 97 | 89 | } |
| 98 | 90 | |
| 99 | | static void add_global_alias(Context *c, Buf *name, Tld *tld) { |
| 100 | | c->import->decls_scope->decl_table.put(name, tld); |
| 91 | static AstNode * trans_create_node(Context *c, NodeType id) { |
| 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) { |
| 104 | | Alias *alias = c->aliases.add_one(); |
| 105 | | alias->name = name; |
| 106 | | alias->tld = tld; |
| 99 | static AstNode *trans_create_node_float_lit(Context *c, double value) { |
| 100 | AstNode *node = trans_create_node(c, NodeTypeFloatLiteral); |
| 101 | node->data.float_literal.bigfloat = allocate<BigFloat>(1); |
| 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) { |
| 110 | | return add_global_alias(c, tld->name, tld); |
| 106 | static AstNode *trans_create_node_symbol(Context *c, Buf *name) { |
| 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) { |
| 114 | | { |
| 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; |
| 112 | static AstNode *trans_create_node_symbol_str(Context *c, const char *name) { |
| 113 | return trans_create_node_symbol(c, buf_create_from_str(name)); |
| 125 | 114 | } |
| 126 | 115 | |
| 127 | | static const char *decl_name(const Decl *decl) { |
| 128 | | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); |
| 129 | | return (const char *)named_decl->getName().bytes_begin(); |
| 116 | static AstNode *trans_create_node_builtin_fn_call(Context *c, Buf *name) { |
| 117 | AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); |
| 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) { |
| 133 | | init_tld(tld, id, name, c->visib_mod, c->source_node, &c->import->decls_scope->base); |
| 134 | | tld->resolution = TldResolutionOk; |
| 135 | | tld->import = c->import; |
| 123 | static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *name) { |
| 124 | return trans_create_node_builtin_fn_call(c, buf_create_from_str(name)); |
| 136 | 125 | } |
| 137 | 126 | |
| 138 | | static Tld *create_inline_fn_tld(Context *c, Buf *fn_name, TldVar *tld_var) { |
| 139 | | TldFn *tld_fn = allocate<TldFn>(1); |
| 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; |
| 127 | static AstNode *trans_create_node_opaque(Context *c) { |
| 128 | return trans_create_node_builtin_fn_call_str(c, "OpaqueType"); |
| 143 | 129 | } |
| 144 | 130 | |
| 145 | | static TldVar *create_global_var(Context *c, Buf *name, ConstExprValue *var_value, bool is_const) { |
| 146 | | auto entry = c->import->decls_scope->decl_table.maybe_get(name); |
| 147 | | if (entry) { |
| 148 | | Tld *existing_tld = entry->value; |
| 149 | | assert(existing_tld->id == TldIdVar); |
| 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; |
| 131 | static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) { |
| 132 | AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr); |
| 133 | node->data.field_access_expr.struct_expr = container; |
| 134 | node->data.field_access_expr.field_name = field_name; |
| 135 | return node; |
| 158 | 136 | } |
| 159 | 137 | |
| 160 | | static Tld *create_global_str_lit_var(Context *c, Buf *name, Buf *value) { |
| 161 | | TldVar *tld_var = create_global_var(c, name, create_const_c_str_lit(c->codegen, value), true); |
| 162 | | return &tld_var->base; |
| 138 | static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) { |
| 139 | AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr); |
| 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) { |
| 166 | | ConstExprValue *var_val = create_const_unsigned_negative(type_entry, x, negative); |
| 167 | | TldVar *tld_var = create_global_var(c, name, var_val, true); |
| 168 | | return &tld_var->base; |
| 145 | static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) { |
| 146 | AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr); |
| 147 | node->data.addr_of_expr.is_const = is_const; |
| 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) { |
| 172 | | return create_global_num_lit_unsigned_negative_type(c, name, x, negative, c->codegen->builtin_types.entry_num_lit_int); |
| 153 | static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) { |
| 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) { |
| 176 | | ConstExprValue *var_val = create_const_float(c->codegen->builtin_types.entry_num_lit_float, value); |
| 177 | | TldVar *tld_var = create_global_var(c, name, var_val, true); |
| 178 | | return &tld_var->base; |
| 160 | static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) { |
| 161 | AstNode *node = trans_create_node(c, NodeTypeIntLiteral); |
| 162 | node->data.int_literal.bigint = allocate<BigInt>(1); |
| 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, |
| 182 | | const llvm::APSInt &aps_int) |
| 167 | static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) { |
| 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()) { |
| 185 | | if (aps_int > INT64_MAX || aps_int < INT64_MIN) { |
| 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 | | } |
| 182 | AstNode *lit_node = trans_create_node_unsigned_negative(c, x, is_negative); |
| 183 | return trans_create_node_cast(c, trans_create_node_symbol_str(c, type_name), lit_node); |
| 199 | 184 | } |
| 200 | 185 | |
| 201 | | static Tld *create_global_num_lit_ap(Context *c, const Decl *source_decl, Buf *name, |
| 202 | | const llvm::APSInt &aps_int) |
| 186 | static AstNode *trans_create_node_array_type(Context *c, AstNode *size_node, AstNode *child_type_node) { |
| 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, |
| 205 | | source_decl, aps_int); |
| 206 | | if (!const_value) |
| 207 | | return nullptr; |
| 208 | | TldVar *tld_var = create_global_var(c, name, const_value, true); |
| 209 | | return &tld_var->base; |
| 196 | AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration); |
| 197 | node->data.variable_declaration.visib_mod = c->visib_mod; |
| 198 | node->data.variable_declaration.symbol = var_name; |
| 199 | node->data.variable_declaration.is_const = is_const; |
| 200 | node->data.variable_declaration.type = type_node; |
| 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) { |
| 214 | | ConstExprValue *var_value = create_const_type(c->codegen, type_entry); |
| 215 | | TldVar *tld_var = create_global_var(c, name, var_value, true); |
| 216 | | add_global(c, &tld_var->base); |
| 206 | static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_name, AstNode *src_proto_node) { |
| 207 | AstNode *fn_def = trans_create_node(c, NodeTypeFnDef); |
| 208 | AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto); |
| 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); |
| 219 | | return &tld_var->base; |
| 278 | static const char *decl_name(const Decl *decl) { |
| 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) { |
| 223 | | return add_const_type(c, &type_entry->name, type_entry); |
| 283 | static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) { |
| 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) { |
| 227 | | return (type_entry == c->codegen->builtin_types.entry_c_void); |
| 291 | static bool is_c_void_type(AstNode *node) { |
| 292 | return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void")); |
| 228 | 293 | } |
| 229 | 294 | |
| 230 | 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 | 305 | return false; |
| 241 | 306 | } |
| 242 | 307 | |
| 243 | | static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl, |
| 244 | | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table) |
| 245 | | { |
| 308 | static bool c_is_signed_integer(Context *c, QualType qt) { |
| 309 | const Type *c_type = qt.getTypePtr(); |
| 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 | 373 | switch (ty->getTypeClass()) { |
| 247 | 374 | case Type::Builtin: |
| 248 | 375 | { |
| 249 | 376 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); |
| 250 | 377 | switch (builtin_ty->getKind()) { |
| 251 | 378 | case BuiltinType::Void: |
| 252 | | return c->codegen->builtin_types.entry_c_void; |
| 379 | return trans_create_node_symbol_str(c, "c_void"); |
| 253 | 380 | case BuiltinType::Bool: |
| 254 | | return c->codegen->builtin_types.entry_bool; |
| 381 | return trans_create_node_symbol_str(c, "bool"); |
| 255 | 382 | case BuiltinType::Char_U: |
| 256 | 383 | case BuiltinType::UChar: |
| 257 | 384 | case BuiltinType::Char_S: |
| 258 | | return c->codegen->builtin_types.entry_u8; |
| 385 | return trans_create_node_symbol_str(c, "u8"); |
| 259 | 386 | case BuiltinType::SChar: |
| 260 | | return c->codegen->builtin_types.entry_i8; |
| 387 | return trans_create_node_symbol_str(c, "i8"); |
| 261 | 388 | case BuiltinType::UShort: |
| 262 | | return get_c_int_type(c->codegen, CIntTypeUShort); |
| 389 | return trans_create_node_symbol_str(c, "c_ushort"); |
| 263 | 390 | case BuiltinType::UInt: |
| 264 | | return get_c_int_type(c->codegen, CIntTypeUInt); |
| 391 | return trans_create_node_symbol_str(c, "c_uint"); |
| 265 | 392 | case BuiltinType::ULong: |
| 266 | | return get_c_int_type(c->codegen, CIntTypeULong); |
| 393 | return trans_create_node_symbol_str(c, "c_ulong"); |
| 267 | 394 | case BuiltinType::ULongLong: |
| 268 | | return get_c_int_type(c->codegen, CIntTypeULongLong); |
| 395 | return trans_create_node_symbol_str(c, "c_ulonglong"); |
| 269 | 396 | case BuiltinType::Short: |
| 270 | | return get_c_int_type(c->codegen, CIntTypeShort); |
| 397 | return trans_create_node_symbol_str(c, "c_short"); |
| 271 | 398 | case BuiltinType::Int: |
| 272 | | return get_c_int_type(c->codegen, CIntTypeInt); |
| 399 | return trans_create_node_symbol_str(c, "c_int"); |
| 273 | 400 | case BuiltinType::Long: |
| 274 | | return get_c_int_type(c->codegen, CIntTypeLong); |
| 401 | return trans_create_node_symbol_str(c, "c_long"); |
| 275 | 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 | 408 | case BuiltinType::Float: |
| 278 | | return c->codegen->builtin_types.entry_f32; |
| 409 | return trans_create_node_symbol_str(c, "f32"); |
| 279 | 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 | 414 | case BuiltinType::LongDouble: |
| 282 | | return c->codegen->builtin_types.entry_c_longdouble; |
| 415 | return trans_create_node_symbol_str(c, "c_longdouble"); |
| 283 | 416 | case BuiltinType::WChar_U: |
| 284 | 417 | case BuiltinType::Char16: |
| 285 | 418 | case BuiltinType::Char32: |
| 286 | | case BuiltinType::UInt128: |
| 287 | 419 | case BuiltinType::WChar_S: |
| 288 | | case BuiltinType::Int128: |
| 289 | 420 | case BuiltinType::Half: |
| 290 | 421 | case BuiltinType::NullPtr: |
| 291 | 422 | case BuiltinType::ObjCId: |
| ... | ... | @@ -336,14 +467,13 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 336 | 467 | case BuiltinType::OCLImage2dMSAADepthRW: |
| 337 | 468 | case BuiltinType::OCLImage2dArrayMSAADepthRW: |
| 338 | 469 | case BuiltinType::OCLImage3dRW: |
| 339 | | case BuiltinType::Float128: |
| 340 | 470 | case BuiltinType::OCLSampler: |
| 341 | 471 | case BuiltinType::OCLEvent: |
| 342 | 472 | case BuiltinType::OCLClkEvent: |
| 343 | 473 | case BuiltinType::OCLQueue: |
| 344 | 474 | case BuiltinType::OCLReserveID: |
| 345 | | emit_warning(c, decl, "missed a builtin type"); |
| 346 | | return c->codegen->builtin_types.entry_invalid; |
| 475 | emit_warning(c, source_loc, "unsupported builtin type"); |
| 476 | return nullptr; |
| 347 | 477 | } |
| 348 | 478 | break; |
| 349 | 479 | } |
| ... | ... | @@ -351,170 +481,150 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 351 | 481 | { |
| 352 | 482 | const PointerType *pointer_ty = static_cast<const PointerType*>(ty); |
| 353 | 483 | QualType child_qt = pointer_ty->getPointeeType(); |
| 354 | | TypeTableEntry *child_type = resolve_qual_type(c, child_qt, decl); |
| 355 | | if (type_is_invalid(child_type)) { |
| 356 | | emit_warning(c, decl, "pointer to unresolved type"); |
| 357 | | return c->codegen->builtin_types.entry_invalid; |
| 484 | AstNode *child_node = trans_qual_type(c, child_qt, source_loc); |
| 485 | if (child_node == nullptr) { |
| 486 | emit_warning(c, source_loc, "pointer to unsupported type"); |
| 487 | return nullptr; |
| 358 | 488 | } |
| 359 | 489 | |
| 360 | 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); |
| 366 | | return get_maybe_type(c->codegen, non_null_pointer_type); |
| 494 | AstNode *pointer_node = trans_create_node_addr_of(c, child_qt.isConstQualified(), |
| 495 | child_qt.isVolatileQualified(), child_node); |
| 496 | return trans_create_node_prefix_op(c, PrefixOpMaybe, pointer_node); |
| 367 | 497 | } |
| 368 | 498 | case Type::Typedef: |
| 369 | 499 | { |
| 370 | 500 | const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty); |
| 371 | 501 | const TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); |
| 372 | | Buf *type_name = buf_create_from_str(decl_name(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 | | } |
| 502 | return resolve_typedef_decl(c, typedef_decl); |
| 405 | 503 | } |
| 406 | 504 | case Type::Elaborated: |
| 407 | 505 | { |
| 408 | 506 | const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty); |
| 409 | 507 | switch (elaborated_ty->getKeyword()) { |
| 410 | 508 | case ETK_Struct: |
| 411 | | return resolve_qual_type_with_table(c, elaborated_ty->getNamedType(), |
| 412 | | decl, &c->struct_type_table); |
| 509 | return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), source_loc); |
| 413 | 510 | case ETK_Enum: |
| 414 | | return resolve_qual_type_with_table(c, elaborated_ty->getNamedType(), |
| 415 | | decl, &c->enum_type_table); |
| 511 | return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), source_loc); |
| 416 | 512 | case ETK_Interface: |
| 417 | 513 | case ETK_Union: |
| 418 | 514 | case ETK_Class: |
| 419 | 515 | case ETK_Typename: |
| 420 | 516 | case ETK_None: |
| 421 | | emit_warning(c, decl, "unsupported elaborated type"); |
| 422 | | return c->codegen->builtin_types.entry_invalid; |
| 517 | emit_warning(c, source_loc, "unsupported elaborated type"); |
| 518 | return nullptr; |
| 423 | 519 | } |
| 424 | 520 | } |
| 425 | 521 | case Type::FunctionProto: |
| 426 | 522 | { |
| 427 | 523 | const FunctionProtoType *fn_proto_ty = static_cast<const FunctionProtoType*>(ty); |
| 428 | 524 | |
| 525 | AstNode *proto_node = trans_create_node(c, NodeTypeFnProto); |
| 429 | 526 | switch (fn_proto_ty->getCallConv()) { |
| 430 | 527 | case CC_C: // __attribute__((cdecl)) |
| 528 | proto_node->data.fn_proto.cc = CallingConventionC; |
| 529 | proto_node->data.fn_proto.is_extern = true; |
| 431 | 530 | break; |
| 432 | 531 | case CC_X86StdCall: // __attribute__((stdcall)) |
| 433 | | emit_warning(c, decl, "function type has x86 stdcall calling convention"); |
| 434 | | return c->codegen->builtin_types.entry_invalid; |
| 532 | proto_node->data.fn_proto.cc = CallingConventionStdcall; |
| 533 | break; |
| 435 | 534 | case CC_X86FastCall: // __attribute__((fastcall)) |
| 436 | | emit_warning(c, decl, "function type has x86 fastcall calling convention"); |
| 437 | | return c->codegen->builtin_types.entry_invalid; |
| 535 | emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall"); |
| 536 | return nullptr; |
| 438 | 537 | case CC_X86ThisCall: // __attribute__((thiscall)) |
| 439 | | emit_warning(c, decl, "function type has x86 thiscall calling convention"); |
| 440 | | return c->codegen->builtin_types.entry_invalid; |
| 538 | emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall"); |
| 539 | return nullptr; |
| 441 | 540 | case CC_X86VectorCall: // __attribute__((vectorcall)) |
| 442 | | emit_warning(c, decl, "function type has x86 vectorcall calling convention"); |
| 443 | | return c->codegen->builtin_types.entry_invalid; |
| 541 | emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall"); |
| 542 | return nullptr; |
| 444 | 543 | case CC_X86Pascal: // __attribute__((pascal)) |
| 445 | | emit_warning(c, decl, "function type has x86 pascal calling convention"); |
| 446 | | return c->codegen->builtin_types.entry_invalid; |
| 544 | emit_warning(c, source_loc, "unsupported calling convention: x86 pascal"); |
| 545 | return nullptr; |
| 447 | 546 | case CC_Win64: // __attribute__((ms_abi)) |
| 448 | | emit_warning(c, decl, "function type has win64 calling convention"); |
| 449 | | return c->codegen->builtin_types.entry_invalid; |
| 547 | emit_warning(c, source_loc, "unsupported calling convention: win64"); |
| 548 | return nullptr; |
| 450 | 549 | case CC_X86_64SysV: // __attribute__((sysv_abi)) |
| 451 | | emit_warning(c, decl, "function type has x86 64sysv calling convention"); |
| 452 | | return c->codegen->builtin_types.entry_invalid; |
| 550 | emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv"); |
| 551 | return nullptr; |
| 453 | 552 | case CC_X86RegCall: |
| 454 | | emit_warning(c, decl, "function type has x86 reg calling convention"); |
| 455 | | return c->codegen->builtin_types.entry_invalid; |
| 553 | emit_warning(c, source_loc, "unsupported calling convention: x86 reg"); |
| 554 | return nullptr; |
| 456 | 555 | case CC_AAPCS: // __attribute__((pcs("aapcs"))) |
| 457 | | emit_warning(c, decl, "function type has aapcs calling convention"); |
| 458 | | return c->codegen->builtin_types.entry_invalid; |
| 556 | emit_warning(c, source_loc, "unsupported calling convention: aapcs"); |
| 557 | return nullptr; |
| 459 | 558 | case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp"))) |
| 460 | | emit_warning(c, decl, "function type has aapcs-vfp calling convention"); |
| 461 | | return c->codegen->builtin_types.entry_invalid; |
| 559 | emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp"); |
| 560 | return nullptr; |
| 462 | 561 | case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc)) |
| 463 | | emit_warning(c, decl, "function type has intel_ocl_bicc calling convention"); |
| 464 | | return c->codegen->builtin_types.entry_invalid; |
| 562 | emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc"); |
| 563 | return nullptr; |
| 465 | 564 | case CC_SpirFunction: // default for OpenCL functions on SPIR target |
| 466 | | emit_warning(c, decl, "function type has SPIR function calling convention"); |
| 467 | | return c->codegen->builtin_types.entry_invalid; |
| 565 | emit_warning(c, source_loc, "unsupported calling convention: SPIR function"); |
| 566 | return nullptr; |
| 468 | 567 | case CC_OpenCLKernel: |
| 469 | | emit_warning(c, decl, "function type has OpenCLKernel calling convention"); |
| 470 | | return c->codegen->builtin_types.entry_invalid; |
| 568 | emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel"); |
| 569 | return nullptr; |
| 471 | 570 | case CC_Swift: |
| 472 | | emit_warning(c, decl, "function type has Swift calling convention"); |
| 473 | | return c->codegen->builtin_types.entry_invalid; |
| 571 | emit_warning(c, source_loc, "unsupported calling convention: Swift"); |
| 572 | return nullptr; |
| 474 | 573 | case CC_PreserveMost: |
| 475 | | emit_warning(c, decl, "function type has PreserveMost calling convention"); |
| 476 | | return c->codegen->builtin_types.entry_invalid; |
| 574 | emit_warning(c, source_loc, "unsupported calling convention: PreserveMost"); |
| 575 | return nullptr; |
| 477 | 576 | case CC_PreserveAll: |
| 478 | | emit_warning(c, decl, "function type has PreserveAll calling convention"); |
| 479 | | return c->codegen->builtin_types.entry_invalid; |
| 577 | emit_warning(c, source_loc, "unsupported calling convention: PreserveAll"); |
| 578 | return nullptr; |
| 480 | 579 | } |
| 481 | 580 | |
| 482 | | FnTypeId fn_type_id = {0}; |
| 483 | | fn_type_id.cc = CallingConventionC; |
| 484 | | fn_type_id.is_var_args = fn_proto_ty->isVariadic(); |
| 485 | | fn_type_id.param_count = fn_proto_ty->getNumParams(); |
| 486 | | |
| 581 | proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic(); |
| 582 | size_t param_count = fn_proto_ty->getNumParams(); |
| 487 | 583 | |
| 488 | 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 | 586 | } else { |
| 491 | | fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl); |
| 492 | | if (type_is_invalid(fn_type_id.return_type)) { |
| 493 | | emit_warning(c, decl, "unresolved function proto return type"); |
| 494 | | return c->codegen->builtin_types.entry_invalid; |
| 587 | proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_proto_ty->getReturnType(), |
| 588 | source_loc); |
| 589 | if (proto_node->data.fn_proto.return_type == nullptr) { |
| 590 | emit_warning(c, source_loc, "unsupported function proto return type"); |
| 591 | return nullptr; |
| 495 | 592 | } |
| 496 | 593 | // convert c_void to actual void (only for return type) |
| 497 | | if (is_c_void_type(c, fn_type_id.return_type)) { |
| 498 | | fn_type_id.return_type = c->codegen->builtin_types.entry_void; |
| 594 | if (is_c_void_type(proto_node->data.fn_proto.return_type)) { |
| 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); |
| 503 | | for (size_t i = 0; i < fn_type_id.param_count; i += 1) { |
| 599 | //emit_warning(c, source_loc, "TODO figure out fn prototype fn name"); |
| 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 | 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)) { |
| 508 | | emit_warning(c, decl, "unresolved function proto parameter type"); |
| 509 | | return c->codegen->builtin_types.entry_invalid; |
| 609 | if (param_type_node == nullptr) { |
| 610 | emit_warning(c, source_loc, "unresolved function proto parameter type"); |
| 611 | return nullptr; |
| 510 | 612 | } |
| 511 | 613 | |
| 512 | | FnTypeParamInfo *param_info = &fn_type_id.param_info[i]; |
| 513 | | param_info->type = param_type; |
| 514 | | param_info->is_noalias = qt.isRestrictQualified(); |
| 614 | AstNode *param_node = trans_create_node(c, NodeTypeParamDecl); |
| 615 | //emit_warning(c, source_loc, "TODO figure out fn prototype param name"); |
| 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 | 629 | case Type::Record: |
| 520 | 630 | { |
| ... | ... | @@ -529,28 +639,29 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 529 | 639 | case Type::ConstantArray: |
| 530 | 640 | { |
| 531 | 641 | const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty); |
| 532 | | TypeTableEntry *child_type = resolve_qual_type(c, const_arr_ty->getElementType(), decl); |
| 533 | | if (child_type->id == TypeTableEntryIdInvalid) { |
| 534 | | emit_warning(c, decl, "unresolved array element type"); |
| 535 | | return child_type; |
| 642 | AstNode *child_type_node = trans_qual_type(c, const_arr_ty->getElementType(), source_loc); |
| 643 | if (child_type_node == nullptr) { |
| 644 | emit_warning(c, source_loc, "unresolved array element type"); |
| 645 | return nullptr; |
| 536 | 646 | } |
| 537 | 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 | 651 | case Type::Paren: |
| 541 | 652 | { |
| 542 | 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 | 656 | case Type::Decayed: |
| 546 | 657 | { |
| 547 | 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 | 661 | case Type::Attributed: |
| 551 | 662 | { |
| 552 | 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 | 666 | case Type::BlockPointer: |
| 556 | 667 | case Type::LValueReference: |
| ... | ... | @@ -586,20 +697,897 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const |
| 586 | 697 | case Type::Pipe: |
| 587 | 698 | case Type::ObjCTypeParam: |
| 588 | 699 | case Type::DeducedTemplateSpecialization: |
| 589 | | emit_warning(c, decl, "missed a '%s' type", ty->getTypeClassName()); |
| 590 | | return c->codegen->builtin_types.entry_invalid; |
| 700 | emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName()); |
| 701 | return nullptr; |
| 591 | 702 | } |
| 592 | 703 | zig_unreachable(); |
| 593 | 704 | } |
| 594 | 705 | |
| 595 | | static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl, |
| 596 | | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table) |
| 597 | | { |
| 598 | | return resolve_type_with_table(c, qt.getTypePtr(), decl, type_table); |
| 706 | static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc) { |
| 707 | return trans_type_with_table(c, qt.getTypePtr(), source_loc); |
| 708 | } |
| 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) { |
| 602 | | return resolve_qual_type_with_table(c, qt, decl, &c->global_type_table); |
| 714 | static AstNode * trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) { |
| 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 | 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 | 1598 | return; |
| 611 | 1599 | } |
| 612 | 1600 | |
| 613 | | TypeTableEntry *fn_type = resolve_qual_type(c, fn_decl->getType(), fn_decl); |
| 614 | | |
| 615 | | if (fn_type->id == TypeTableEntryIdInvalid) { |
| 616 | | emit_warning(c, fn_decl, "ignoring function '%s' - unable to resolve type", buf_ptr(fn_name)); |
| 1601 | AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), fn_decl->getLocation()); |
| 1602 | if (proto_node == nullptr) { |
| 1603 | emit_warning(c, fn_decl->getLocation(), "unable to resolve prototype of function '%s'", buf_ptr(fn_name)); |
| 617 | 1604 | return; |
| 618 | 1605 | } |
| 619 | | assert(fn_type->id == TypeTableEntryIdFn); |
| 620 | 1606 | |
| 621 | | FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong); |
| 622 | | buf_init_from_buf(&fn_entry->symbol_name, fn_name); |
| 623 | | fn_entry->type_entry = fn_type; |
| 1607 | proto_node->data.fn_proto.name = fn_name; |
| 1608 | proto_node->data.fn_proto.is_extern = !fn_decl->hasBody(); |
| 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; |
| 628 | | fn_entry->param_names = allocate<Buf *>(arg_count); |
| 629 | | Buf *name_buf; |
| 630 | | for (size_t i = 0; i < arg_count; i += 1) { |
| 1623 | for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) { |
| 1624 | AstNode *param_node = proto_node->data.fn_proto.params.at(i); |
| 631 | 1625 | const ParmVarDecl *param = fn_decl->getParamDecl(i); |
| 632 | 1626 | const char *name = decl_name(param); |
| 633 | 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 | 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); |
| 642 | | parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name); |
| 643 | | tld_fn->fn_entry = fn_entry; |
| 644 | | add_global(c, &tld_fn->base); |
| 1639 | if (fn_decl->hasBody()) { |
| 1640 | Stmt *body = fn_decl->getBody(); |
| 1641 | |
| 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 | 1666 | QualType child_qt = typedef_decl->getUnderlyingType(); |
| 651 | 1667 | Buf *type_name = buf_create_from_str(decl_name(typedef_decl)); |
| 652 | 1668 | |
| 653 | | if (buf_eql_str(type_name, "uint8_t") || |
| 654 | | buf_eql_str(type_name, "int8_t") || |
| 655 | | buf_eql_str(type_name, "uint16_t") || |
| 656 | | buf_eql_str(type_name, "int16_t") || |
| 657 | | buf_eql_str(type_name, "uint32_t") || |
| 658 | | buf_eql_str(type_name, "int32_t") || |
| 659 | | buf_eql_str(type_name, "uint64_t") || |
| 660 | | buf_eql_str(type_name, "int64_t") || |
| 661 | | buf_eql_str(type_name, "intptr_t") || |
| 662 | | buf_eql_str(type_name, "uintptr_t")) |
| 663 | | { |
| 664 | | // special case we can just use the builtin types |
| 665 | | return; |
| 1669 | if (buf_eql_str(type_name, "uint8_t")) { |
| 1670 | return resolve_typdef_as_builtin(c, typedef_decl, "u8"); |
| 1671 | } else if (buf_eql_str(type_name, "int8_t")) { |
| 1672 | return resolve_typdef_as_builtin(c, typedef_decl, "i8"); |
| 1673 | } else if (buf_eql_str(type_name, "uint16_t")) { |
| 1674 | return resolve_typdef_as_builtin(c, typedef_decl, "u16"); |
| 1675 | } else if (buf_eql_str(type_name, "int16_t")) { |
| 1676 | return resolve_typdef_as_builtin(c, typedef_decl, "i16"); |
| 1677 | } else if (buf_eql_str(type_name, "uint32_t")) { |
| 1678 | return resolve_typdef_as_builtin(c, typedef_decl, "u32"); |
| 1679 | } else if (buf_eql_str(type_name, "int32_t")) { |
| 1680 | return resolve_typdef_as_builtin(c, typedef_decl, "i32"); |
| 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 | 1695 | // if the underlying type is anonymous, we can special case it to just |
| 669 | 1696 | // use the name of this typedef |
| 670 | 1697 | // TODO |
| 671 | 1698 | |
| 672 | | TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl); |
| 673 | | if (child_type->id == TypeTableEntryIdInvalid) { |
| 674 | | emit_warning(c, typedef_decl, "typedef %s - unresolved child type", buf_ptr(type_name)); |
| 675 | | return; |
| 1699 | AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation()); |
| 1700 | if (type_node == nullptr) { |
| 1701 | emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name)); |
| 1702 | c->decl_table.put(typedef_decl, nullptr); |
| 1703 | return nullptr; |
| 676 | 1704 | } |
| 677 | | add_const_type(c, type_name, child_type); |
| 678 | | } |
| 1705 | add_global_var(c, type_name, type_node); |
| 679 | 1706 | |
| 680 | | static void replace_with_fwd_decl(Context *c, TypeTableEntry *struct_type, Buf *full_type_name) { |
| 681 | | unsigned line = c->source_node ? c->source_node->line : 0; |
| 682 | | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugForwardDeclType(c->codegen->dbuilder, |
| 683 | | ZigLLVMTag_DW_structure_type(), buf_ptr(full_type_name), |
| 684 | | ZigLLVMFileToScope(c->import->di_file), c->import->di_file, line); |
| 1707 | AstNode *symbol_node = trans_create_node_symbol(c, type_name); |
| 1708 | c->decl_table.put(typedef_decl, symbol_node); |
| 1709 | return symbol_node; |
| 1710 | } |
| 685 | 1711 | |
| 686 | | ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type); |
| 687 | | struct_type->di_type = replacement_di_type; |
| 688 | | struct_type->id = TypeTableEntryIdOpaque; |
| 1712 | struct AstNode *demote_enum_to_opaque(Context *c, const EnumDecl *enum_decl, |
| 1713 | Buf *full_type_name, Buf *bare_name) |
| 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) { |
| 692 | | auto existing_entry = c->decl_table.maybe_get((void*)enum_decl); |
| 1727 | static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 1728 | auto existing_entry = c->decl_table.maybe_get((void*)enum_decl->getCanonicalDecl()); |
| 693 | 1729 | if (existing_entry) { |
| 694 | 1730 | return existing_entry->value; |
| 695 | 1731 | } |
| 696 | 1732 | |
| 697 | 1733 | const char *raw_name = decl_name(enum_decl); |
| 698 | | |
| 699 | | Buf *bare_name; |
| 700 | | if (raw_name[0] == 0) { |
| 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)); |
| 1734 | bool is_anonymous = (raw_name[0] == 0); |
| 1735 | Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name); |
| 1736 | Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name)); |
| 707 | 1737 | |
| 708 | 1738 | const EnumDecl *enum_def = enum_decl->getDefinition(); |
| 709 | 1739 | if (!enum_def) { |
| 710 | | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, |
| 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; |
| 1740 | return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name); |
| 719 | 1741 | } |
| 720 | 1742 | |
| 721 | 1743 | bool pure_enum = true; |
| ... | ... | @@ -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 | 1758 | if (pure_enum) { |
| 736 | | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, |
| 737 | | ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern); |
| 738 | | TypeTableEntry *tag_type_entry = create_enum_tag_type(c->codegen, enum_type, tag_int_type); |
| 739 | | c->enum_type_table.put(bare_name, enum_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); |
| 1759 | AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl); |
| 1760 | enum_node->data.container_decl.kind = ContainerKindEnum; |
| 1761 | enum_node->data.container_decl.layout = ContainerLayoutExtern; |
| 1762 | enum_node->data.container_decl.init_arg_expr = tag_int_type; |
| 751 | 1763 | |
| 1764 | enum_node->data.container_decl.fields.resize(field_count); |
| 752 | 1765 | uint32_t i = 0; |
| 753 | 1766 | for (auto it = enum_def->enumerator_begin(), |
| 754 | 1767 | it_end = enum_def->enumerator_end(); |
| ... | ... | @@ -758,93 +1771,82 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 758 | 1771 | |
| 759 | 1772 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 760 | 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 | 1775 | field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); |
| 763 | 1776 | } else { |
| 764 | 1777 | field_name = enum_val_name; |
| 765 | 1778 | } |
| 766 | 1779 | |
| 767 | | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; |
| 768 | | type_enum_field->name = field_name; |
| 769 | | type_enum_field->type_entry = c->codegen->builtin_types.entry_void; |
| 770 | | type_enum_field->value = i; |
| 771 | | |
| 772 | | di_enumerators[i] = ZigLLVMCreateDebugEnumerator(c->codegen->dbuilder, buf_ptr(type_enum_field->name), i); |
| 773 | | |
| 1780 | AstNode *field_node = trans_create_node(c, NodeTypeStructField); |
| 1781 | field_node->data.struct_field.name = field_name; |
| 1782 | field_node->data.struct_field.type = nullptr; |
| 1783 | enum_node->data.container_decl.fields.items[i] = field_node; |
| 774 | 1784 | |
| 775 | 1785 | // in C each enum value is in the global namespace. so we put them there too. |
| 776 | 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 |
| 781 | | enum_type->type_ref = tag_type_entry->type_ref; |
| 782 | | |
| 783 | | enum_type->data.enumeration.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref, |
| 784 | | enum_type->type_ref); |
| 785 | | |
| 786 | | // create debug type for tag |
| 787 | | unsigned line = c->source_node ? (c->source_node->line + 1) : 0; |
| 788 | | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, enum_type->type_ref); |
| 789 | | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, enum_type->type_ref); |
| 790 | | ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(c->codegen->dbuilder, |
| 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); |
| 1792 | if (is_anonymous) { |
| 1793 | c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node); |
| 1794 | return enum_node; |
| 1795 | } else { |
| 1796 | AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); |
| 1797 | add_global_weak_alias(c, bare_name, full_type_name); |
| 1798 | add_global_var(c, full_type_name, enum_node); |
| 1799 | c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node); |
| 1800 | return enum_node; |
| 1801 | } |
| 1802 | } |
| 807 | 1803 | |
| 808 | | // add variables for all the values with enum_type |
| 809 | | for (auto it = enum_def->enumerator_begin(), |
| 810 | | it_end = enum_def->enumerator_end(); |
| 811 | | it != it_end; ++it) |
| 812 | | { |
| 813 | | const EnumConstantDecl *enum_const = *it; |
| 1804 | // TODO after issue #305 is solved, make this be an enum with tag_int_type |
| 1805 | // as the integer type and set the custom enum values |
| 1806 | AstNode *enum_node = tag_int_type; |
| 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()); |
| 818 | | if (!tld) |
| 819 | | return c->codegen->builtin_types.entry_invalid; |
| 1809 | // add variables for all the values with enum_node |
| 1810 | for (auto it = enum_def->enumerator_begin(), |
| 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); |
| 822 | | } |
| 1816 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 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) { |
| 829 | | TypeTableEntry *enum_type = resolve_enum_decl(c, enum_decl); |
| 830 | | |
| 831 | | if (enum_type->id == TypeTableEntryIdInvalid) |
| 832 | | return; |
| 833 | | |
| 834 | | // make an alias without the "enum_" prefix. this will get emitted at the |
| 835 | | // end if it doesn't conflict with anything else |
| 836 | | bool is_anonymous = (decl_name(enum_decl)[0] == 0); |
| 837 | | if (is_anonymous) |
| 838 | | return; |
| 839 | | |
| 840 | | Buf *bare_name = buf_create_from_str(decl_name(enum_decl)); |
| 841 | | |
| 842 | | Tld *tld = add_container_tld(c, enum_type); |
| 843 | | add_global_weak_alias(c, bare_name, tld); |
| 1833 | static AstNode *demote_struct_to_opaque(Context *c, const RecordDecl *record_decl, |
| 1834 | Buf *full_type_name, Buf *bare_name) |
| 1835 | { |
| 1836 | AstNode *opaque_node = trans_create_node_opaque(c); |
| 1837 | if (full_type_name == nullptr) { |
| 1838 | c->decl_table.put(record_decl->getCanonicalDecl(), opaque_node); |
| 1839 | return opaque_node; |
| 1840 | } |
| 1841 | AstNode *symbol_node = trans_create_node_symbol(c, full_type_name); |
| 1842 | add_global_weak_alias(c, bare_name, full_type_name); |
| 1843 | add_global_var(c, full_type_name, opaque_node); |
| 1844 | c->decl_table.put(record_decl->getCanonicalDecl(), symbol_node); |
| 1845 | return symbol_node; |
| 844 | 1846 | } |
| 845 | 1847 | |
| 846 | | static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl) { |
| 847 | | auto existing_entry = c->decl_table.maybe_get((void*)record_decl); |
| 1848 | static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) { |
| 1849 | auto existing_entry = c->decl_table.maybe_get((void*)record_decl->getCanonicalDecl()); |
| 848 | 1850 | if (existing_entry) { |
| 849 | 1851 | return existing_entry->value; |
| 850 | 1852 | } |
| ... | ... | @@ -852,36 +1854,20 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 852 | 1854 | const char *raw_name = decl_name(record_decl); |
| 853 | 1855 | |
| 854 | 1856 | if (!record_decl->isStruct()) { |
| 855 | | emit_warning(c, record_decl, "skipping record %s, not a struct", raw_name); |
| 856 | | return c->codegen->builtin_types.entry_invalid; |
| 857 | | } |
| 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); |
| 1857 | emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name); |
| 1858 | c->decl_table.put(record_decl->getCanonicalDecl(), nullptr); |
| 1859 | return nullptr; |
| 864 | 1860 | } |
| 865 | 1861 | |
| 866 | | Buf *full_type_name = buf_sprintf("struct_%s", buf_ptr(bare_name)); |
| 867 | | |
| 868 | | |
| 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); |
| 1862 | bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0; |
| 1863 | Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name); |
| 1864 | Buf *full_type_name = (bare_name == nullptr) ? nullptr : buf_sprintf("struct_%s", buf_ptr(bare_name)); |
| 876 | 1865 | |
| 877 | 1866 | RecordDecl *record_def = record_decl->getDefinition(); |
| 878 | | unsigned line = c->source_node ? c->source_node->line : 0; |
| 879 | | if (!record_def) { |
| 880 | | replace_with_fwd_decl(c, struct_type, full_type_name); |
| 881 | | return struct_type; |
| 1867 | if (record_def == nullptr) { |
| 1868 | return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name); |
| 882 | 1869 | } |
| 883 | 1870 | |
| 884 | | |
| 885 | 1871 | // count fields and validate |
| 886 | 1872 | uint32_t field_count = 0; |
| 887 | 1873 | for (auto it = record_def->field_begin(), |
| ... | ... | @@ -891,105 +1877,56 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 891 | 1877 | const FieldDecl *field_decl = *it; |
| 892 | 1878 | |
| 893 | 1879 | if (field_decl->isBitField()) { |
| 894 | | emit_warning(c, field_decl, "struct %s demoted to opaque type - has bitfield\n", buf_ptr(bare_name)); |
| 895 | | replace_with_fwd_decl(c, struct_type, full_type_name); |
| 896 | | return struct_type; |
| 1880 | emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield", |
| 1881 | is_anonymous ? "(anon)" : buf_ptr(bare_name)); |
| 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; |
| 901 | | struct_type->data.structure.fields = allocate<TypeStructField>(field_count); |
| 902 | | LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count); |
| 903 | | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count); |
| 1886 | AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl); |
| 1887 | struct_node->data.container_decl.kind = ContainerKindStruct; |
| 1888 | struct_node->data.container_decl.layout = ContainerLayoutExtern; |
| 904 | 1889 | |
| 905 | | // next, populate element_types as its needed for LLVMStructSetBody which is needed for LLVMOffsetOfElement |
| 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; |
| 1890 | // TODO handle attribute packed |
| 912 | 1891 | |
| 913 | | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 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 | | } |
| 1892 | struct_node->data.container_decl.fields.resize(field_count); |
| 925 | 1893 | |
| 926 | | element_types[i] = field_type->type_ref; |
| 927 | | assert(element_types[i]); |
| 1894 | // must be before fields in case a circular reference happens |
| 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); |
| 931 | | |
| 932 | | // finally populate debug info |
| 933 | | i = 0; |
| 1901 | uint32_t i = 0; |
| 934 | 1902 | for (auto it = record_def->field_begin(), |
| 935 | 1903 | it_end = record_def->field_end(); |
| 936 | 1904 | it != it_end; ++it, i += 1) |
| 937 | 1905 | { |
| 938 | | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; |
| 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]); |
| 1906 | const FieldDecl *field_decl = *it; |
| 953 | 1907 | |
| 954 | | } |
| 955 | | struct_type->data.structure.embedded_in_current = false; |
| 956 | | |
| 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 | | } |
| 1908 | AstNode *field_node = trans_create_node(c, NodeTypeStructField); |
| 1909 | field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl)); |
| 1910 | field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), field_decl->getLocation()); |
| 977 | 1911 | |
| 978 | | static void visit_record_decl(Context *c, const RecordDecl *record_decl) { |
| 979 | | TypeTableEntry *struct_type = resolve_record_decl(c, record_decl); |
| 1912 | if (field_node->data.struct_field.type == nullptr) { |
| 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) { |
| 982 | | return; |
| 983 | | } |
| 984 | | |
| 985 | | bool is_anonymous = (record_decl->isAnonymousStructOrUnion() || decl_name(record_decl)[0] == 0); |
| 986 | | if (is_anonymous) |
| 987 | | return; |
| 1917 | return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name); |
| 1918 | } |
| 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); |
| 992 | | add_global_weak_alias(c, bare_name, tld); |
| 1923 | if (is_anonymous) { |
| 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 | 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 | 1936 | case VarDecl::TLS_None: |
| 1000 | 1937 | break; |
| 1001 | 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 | 1941 | return; |
| 1004 | 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 | 1945 | return; |
| 1007 | 1946 | } |
| 1008 | 1947 | |
| 1009 | 1948 | QualType qt = var_decl->getType(); |
| 1010 | | TypeTableEntry *var_type = resolve_qual_type(c, qt, var_decl); |
| 1011 | | if (var_type->id == TypeTableEntryIdInvalid) { |
| 1012 | | emit_warning(c, var_decl, "ignoring variable '%s' - unresolved type\n", buf_ptr(name)); |
| 1949 | AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation()); |
| 1950 | if (var_type == nullptr) { |
| 1951 | emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name)); |
| 1013 | 1952 | return; |
| 1014 | 1953 | } |
| 1015 | 1954 | |
| ... | ... | @@ -1018,59 +1957,53 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| 1018 | 1957 | bool is_const = qt.isConstQualified(); |
| 1019 | 1958 | |
| 1020 | 1959 | if (is_static && !is_extern) { |
| 1021 | | if (!var_decl->hasInit()) { |
| 1022 | | emit_warning(c, var_decl, "ignoring variable '%s' - no initializer\n", buf_ptr(name)); |
| 1023 | | return; |
| 1024 | | } |
| 1025 | | APValue *ap_value = var_decl->evaluateValue(); |
| 1026 | | if (!ap_value) { |
| 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)); |
| 1960 | AstNode *init_node; |
| 1961 | if (var_decl->hasInit()) { |
| 1962 | APValue *ap_value = var_decl->evaluateValue(); |
| 1963 | if (ap_value == nullptr) { |
| 1964 | emit_warning(c, var_decl->getLocation(), |
| 1965 | "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name)); |
| 1058 | 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); |
| 1062 | | add_global(c, &tld_var->base); |
| 1993 | AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, init_node); |
| 1994 | c->root->data.root.top_level_decls.append(var_node); |
| 1063 | 1995 | return; |
| 1064 | 1996 | } |
| 1065 | 1997 | |
| 1066 | 1998 | if (is_extern) { |
| 1067 | | TldVar *tld_var = create_global_var(c, name, create_const_runtime(var_type), is_const); |
| 1068 | | tld_var->var->linkage = VarLinkageExternal; |
| 1069 | | add_global(c, &tld_var->base); |
| 1999 | AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, nullptr); |
| 2000 | var_node->data.variable_declaration.is_extern = true; |
| 2001 | c->root->data.root.top_level_decls.append(var_node); |
| 1070 | 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 | 2007 | return; |
| 1075 | 2008 | } |
| 1076 | 2009 | |
| ... | ... | @@ -1082,44 +2015,35 @@ static bool decl_visitor(void *context, const Decl *decl) { |
| 1082 | 2015 | visit_fn_decl(c, static_cast<const FunctionDecl*>(decl)); |
| 1083 | 2016 | break; |
| 1084 | 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 | 2019 | break; |
| 1087 | 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 | 2022 | break; |
| 1090 | 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 | 2025 | break; |
| 1093 | 2026 | case Decl::Var: |
| 1094 | 2027 | visit_var_decl(c, static_cast<const VarDecl *>(decl)); |
| 1095 | 2028 | break; |
| 1096 | 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 | 2033 | return true; |
| 1101 | 2034 | } |
| 1102 | 2035 | |
| 1103 | 2036 | static bool name_exists(Context *c, Buf *name) { |
| 1104 | | if (c->global_type_table.maybe_get(name)) { |
| 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; |
| 2037 | return get_global(c, name) != nullptr; |
| 1114 | 2038 | } |
| 1115 | 2039 | |
| 1116 | 2040 | static void render_aliases(Context *c) { |
| 1117 | 2041 | for (size_t i = 0; i < c->aliases.length; i += 1) { |
| 1118 | 2042 | Alias *alias = &c->aliases.at(i); |
| 1119 | | if (name_exists(c, alias->name)) |
| 2043 | if (name_exists(c, alias->new_name)) |
| 1120 | 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 | 2054 | if (!entry) |
| 1131 | 2055 | break; |
| 1132 | 2056 | |
| 1133 | | Tld *var_tld = entry->value; |
| 1134 | | add_global(c, var_tld); |
| 2057 | AstNode *value_node = entry->value; |
| 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 | 2078 | switch (tok->id) { |
| 1151 | 2079 | case CTokIdCharLit: |
| 1152 | 2080 | if (is_last && is_first) { |
| 1153 | | Tld *tld = create_global_num_lit_unsigned_negative(c, name, tok->data.char_lit, false); |
| 1154 | | c->macro_table.put(name, tld); |
| 2081 | AstNode *node = trans_create_node_unsigned(c, tok->data.char_lit); |
| 2082 | c->macro_table.put(name, node); |
| 1155 | 2083 | } |
| 1156 | 2084 | return; |
| 1157 | 2085 | case CTokIdStrLit: |
| 1158 | 2086 | if (is_last && is_first) { |
| 1159 | | Tld *tld = create_global_str_lit_var(c, name, buf_create_from_buf(&tok->data.str_lit)); |
| 1160 | | c->macro_table.put(name, tld); |
| 2087 | AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit)); |
| 2088 | c->macro_table.put(name, node); |
| 1161 | 2089 | } |
| 1162 | 2090 | return; |
| 1163 | 2091 | case CTokIdNumLitInt: |
| 1164 | 2092 | if (is_last) { |
| 1165 | | Tld *tld; |
| 2093 | AstNode *node; |
| 1166 | 2094 | switch (tok->data.num_lit_int.suffix) { |
| 1167 | 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 | 2097 | break; |
| 1170 | 2098 | case CNumLitSuffixL: |
| 1171 | | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, |
| 1172 | | c->codegen->builtin_types.entry_c_int[CIntTypeLong]); |
| 2099 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 2100 | "c_long"); |
| 1173 | 2101 | break; |
| 1174 | 2102 | case CNumLitSuffixU: |
| 1175 | | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, |
| 1176 | | c->codegen->builtin_types.entry_c_int[CIntTypeUInt]); |
| 2103 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 2104 | "c_uint"); |
| 1177 | 2105 | break; |
| 1178 | 2106 | case CNumLitSuffixLU: |
| 1179 | | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, |
| 1180 | | c->codegen->builtin_types.entry_c_int[CIntTypeULong]); |
| 2107 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 2108 | "c_ulong"); |
| 1181 | 2109 | break; |
| 1182 | 2110 | case CNumLitSuffixLL: |
| 1183 | | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, |
| 1184 | | c->codegen->builtin_types.entry_c_int[CIntTypeLongLong]); |
| 2111 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 2112 | "c_longlong"); |
| 1185 | 2113 | break; |
| 1186 | 2114 | case CNumLitSuffixLLU: |
| 1187 | | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, |
| 1188 | | c->codegen->builtin_types.entry_c_int[CIntTypeULongLong]); |
| 2115 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 2116 | "c_ulonglong"); |
| 1189 | 2117 | break; |
| 1190 | 2118 | } |
| 1191 | | c->macro_table.put(name, tld); |
| 2119 | c->macro_table.put(name, node); |
| 1192 | 2120 | } |
| 1193 | 2121 | return; |
| 1194 | 2122 | case CTokIdNumLitFloat: |
| 1195 | 2123 | if (is_last) { |
| 1196 | 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); |
| 1198 | | c->macro_table.put(name, tld); |
| 2125 | AstNode *node = trans_create_node_float_lit(c, value); |
| 2126 | c->macro_table.put(name, node); |
| 1199 | 2127 | } |
| 1200 | 2128 | return; |
| 1201 | 2129 | case CTokIdSymbol: |
| ... | ... | @@ -1224,35 +2152,37 @@ static void process_symbol_macros(Context *c) { |
| 1224 | 2152 | for (size_t i = 0; i < c->macro_symbols.length; i += 1) { |
| 1225 | 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 |
| 1228 | | // putting another entry in the decl table pointing to the same top level decl. |
| 1229 | | Tld *existing_tld = get_global(c, ms.value); |
| 1230 | | if (!existing_tld) |
| 2155 | // Check if this macro aliases another top level declaration |
| 2156 | AstNode *existing_node = get_global(c, ms.value); |
| 2157 | if (!existing_node || name_exists(c, ms.name)) |
| 1231 | 2158 | continue; |
| 1232 | 2159 | |
| 1233 | 2160 | // If a macro aliases a global variable which is a function pointer, we conclude that |
| 1234 | 2161 | // the macro is intended to represent a function that assumes the function pointer |
| 1235 | 2162 | // variable is non-null and calls it. |
| 1236 | | if (existing_tld->id == TldIdVar) { |
| 1237 | | TldVar *tld_var = (TldVar *)existing_tld; |
| 1238 | | TypeTableEntry *var_type = tld_var->var->value->type; |
| 1239 | | if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) { |
| 1240 | | TypeTableEntry *child_type = var_type->data.maybe.child_type; |
| 1241 | | if (child_type->id == TypeTableEntryIdFn) { |
| 1242 | | Tld *tld = create_inline_fn_tld(c, ms.name, tld_var); |
| 1243 | | c->macro_table.put(ms.name, tld); |
| 2163 | if (existing_node->type == NodeTypeVariableDeclaration) { |
| 2164 | AstNode *var_type = existing_node->data.variable_declaration.type; |
| 2165 | if (var_type != nullptr && var_type->type == NodeTypePrefixOpExpr && |
| 2166 | var_type->data.prefix_op_expr.prefix_op == PrefixOpMaybe) |
| 2167 | { |
| 2168 | AstNode *fn_proto_node = var_type->data.prefix_op_expr.primary_expr; |
| 2169 | if (fn_proto_node->type == NodeTypeFnProto) { |
| 2170 | AstNode *inline_fn_node = trans_create_node_inline_fn(c, ms.name, ms.value, fn_proto_node); |
| 2171 | c->macro_table.put(ms.name, inline_fn_node); |
| 1244 | 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 | 2181 | static void process_preprocessor_entities(Context *c, ASTUnit &unit) { |
| 1254 | 2182 | CTokenize ctok = {{0}}; |
| 1255 | 2183 | |
| 2184 | // TODO if we see #undef, delete it from the table |
| 2185 | |
| 1256 | 2186 | for (PreprocessedEntity *entity : unit.getLocalPreprocessingEntities()) { |
| 1257 | 2187 | switch (entity->getKind()) { |
| 1258 | 2188 | case PreprocessedEntity::InvalidKind: |
| ... | ... | @@ -1309,9 +2239,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1309 | 2239 | c->import = import; |
| 1310 | 2240 | c->errors = errors; |
| 1311 | 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 | 2242 | c->decl_table.init(8); |
| 1316 | 2243 | c->macro_table.init(8); |
| 1317 | 2244 | c->codegen = codegen; |
| ... | ... | @@ -1373,7 +2300,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1373 | 2300 | |
| 1374 | 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 | 2304 | bool only_local_decls = true; |
| 1378 | 2305 | bool capture_diagnostics = true; |
| 1379 | 2306 | bool user_files_are_volatile = true; |
| ... | ... | @@ -1390,7 +2317,6 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1390 | 2317 | single_file_parse, user_files_are_volatile, for_serialization, None, &err_unit, |
| 1391 | 2318 | nullptr)); |
| 1392 | 2319 | |
| 1393 | | |
| 1394 | 2320 | // Early failures in LoadFromCommandLine may return with ErrUnit unset. |
| 1395 | 2321 | if (!ast_unit && !err_unit) { |
| 1396 | 2322 | return ErrorFileSystem; |
| ... | ... | @@ -1416,39 +2342,48 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 1416 | 2342 | break; |
| 1417 | 2343 | } |
| 1418 | 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 | 2345 | Buf *msg = buf_create_from_str((const char *)msg_str_ref.bytes_begin()); |
| 1427 | | Buf *path; |
| 1428 | | if (filename.empty()) { |
| 1429 | | path = buf_alloc(); |
| 1430 | | } else { |
| 1431 | | path = buf_create_from_mem((const char *)filename.bytes_begin(), filename.size()); |
| 1432 | | } |
| 2346 | FullSourceLoc fsl = it->getLocation(); |
| 2347 | if (fsl.hasManager()) { |
| 2348 | FileID file_id = fsl.getFileID(); |
| 2349 | StringRef filename = fsl.getManager().getFilename(fsl); |
| 2350 | unsigned line = fsl.getSpellingLineNumber() - 1; |
| 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 | 2371 | return 0; |
| 1440 | 2372 | } |
| 1441 | 2373 | |
| 2374 | c->ctx = &ast_unit->getASTContext(); |
| 1442 | 2375 | c->source_manager = &ast_unit->getSourceManager(); |
| 2376 | c->root = trans_create_node(c, NodeTypeRoot); |
| 1443 | 2377 | |
| 1444 | 2378 | ast_unit->visitLocalTopLevelDecls(c, decl_visitor); |
| 1445 | 2379 | |
| 1446 | 2380 | process_preprocessor_entities(c, *ast_unit); |
| 1447 | 2381 | |
| 1448 | 2382 | process_symbol_macros(c); |
| 1449 | | |
| 1450 | 2383 | render_macros(c); |
| 1451 | 2384 | render_aliases(c); |
| 1452 | 2385 | |
| 2386 | import->root = c->root; |
| 2387 | |
| 1453 | 2388 | return 0; |
| 1454 | 2389 | } |