| ... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
| 15 | #include "parseh.hpp" | 15 | #include "parseh.hpp" |
| 16 | #include "parser.hpp" | 16 | #include "parser.hpp" |
| 17 | | 17 | |
| | 18 | |
| 18 | #include <clang/Frontend/ASTUnit.h> | 19 | #include <clang/Frontend/ASTUnit.h> |
| 19 | #include <clang/Frontend/CompilerInstance.h> | 20 | #include <clang/Frontend/CompilerInstance.h> |
| 20 | #include <clang/AST/Expr.h> | 21 | #include <clang/AST/Expr.h> |
| ... | @@ -28,14 +29,9 @@ struct MacroSymbol { | ... | @@ -28,14 +29,9 @@ struct MacroSymbol { |
| 28 | Buf *value; | 29 | Buf *value; |
| 29 | }; | 30 | }; |
| 30 | | 31 | |
| 31 | struct GlobalValue { | | |
| 32 | TypeTableEntry *type; | | |
| 33 | bool is_const; | | |
| 34 | }; | | |
| 35 | | | |
| 36 | struct Alias { | 32 | struct Alias { |
| 37 | Buf *name; | 33 | Buf *name; |
| 38 | Tld *tld; | 34 | AstNode *node; |
| 39 | }; | 35 | }; |
| 40 | | 36 | |
| 41 | struct Context { | 37 | struct Context { |
| ... | @@ -43,30 +39,26 @@ struct Context { | ... | @@ -43,30 +39,26 @@ struct Context { |
| 43 | ZigList<ErrorMsg *> *errors; | 39 | ZigList<ErrorMsg *> *errors; |
| 44 | bool warnings_on; | 40 | bool warnings_on; |
| 45 | VisibMod visib_mod; | 41 | VisibMod visib_mod; |
| 46 | | 42 | AstNode *root; |
| 47 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> global_type_table; | 43 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_type_table; |
| 48 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_type_table2; | 44 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> struct_type_table; |
| 49 | | 45 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> enum_type_table; |
| 50 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> struct_type_table; | 46 | HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table; |
| 51 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> enum_type_table; | 47 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table; |
| 52 | HashMap<const void *, TypeTableEntry *, ptr_hash, ptr_eq> decl_table; | | |
| 53 | HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> macro_table; | | |
| 54 | SourceManager *source_manager; | 48 | SourceManager *source_manager; |
| 55 | ZigList<Alias> aliases; | 49 | ZigList<Alias> aliases; |
| 56 | ZigList<MacroSymbol> macro_symbols; | 50 | ZigList<MacroSymbol> macro_symbols; |
| 57 | AstNode *source_node; | 51 | AstNode *source_node; |
| 58 | uint32_t next_anon_index; | | |
| 59 | | 52 | |
| 60 | CodeGen *codegen; | 53 | CodeGen *codegen; |
| 61 | ASTContext *ctx; | 54 | ASTContext *ctx; |
| 62 | }; | 55 | }; |
| 63 | | 56 | |
| 64 | static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl, | 57 | static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl); |
| 65 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table); | 58 | static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); |
| 66 | | 59 | static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const SourceLocation &source_loc, |
| 67 | static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl); | 60 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> *type_table); |
| 68 | static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl); | 61 | static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc); |
| 69 | static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl); | | |
| 70 | | 62 | |
| 71 | | 63 | |
| 72 | __attribute__ ((format (printf, 3, 4))) | 64 | __attribute__ ((format (printf, 3, 4))) |
| ... | @@ -93,522 +85,226 @@ static void emit_warning(Context *c, const SourceLocation &sl, const char *forma | ... | @@ -93,522 +85,226 @@ static void emit_warning(Context *c, const SourceLocation &sl, const char *forma |
| 93 | fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg)); | 85 | fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg)); |
| 94 | } | 86 | } |
| 95 | | 87 | |
| 96 | static uint32_t get_next_anon_index(Context *c) { | 88 | static void add_global_weak_alias(Context *c, Buf *name, AstNode *node) { |
| 97 | uint32_t result = c->next_anon_index; | | |
| 98 | c->next_anon_index += 1; | | |
| 99 | return result; | | |
| 100 | } | | |
| 101 | | | |
| 102 | static void add_global_alias(Context *c, Buf *name, Tld *tld) { | | |
| 103 | c->import->decls_scope->decl_table.put(name, tld); | | |
| 104 | } | | |
| 105 | | | |
| 106 | static void add_global_weak_alias(Context *c, Buf *name, Tld *tld) { | | |
| 107 | Alias *alias = c->aliases.add_one(); | 89 | Alias *alias = c->aliases.add_one(); |
| 108 | alias->name = name; | 90 | alias->name = name; |
| 109 | alias->tld = tld; | 91 | alias->node = node; |
| 110 | } | 92 | } |
| 111 | | 93 | |
| 112 | static void add_global(Context *c, Tld *tld) { | 94 | static AstNode * trans_create_node(Context *c, NodeType id) { |
| 113 | return add_global_alias(c, tld->name, tld); | 95 | AstNode *node = allocate<AstNode>(1); |
| | 96 | node->type = id; |
| | 97 | node->owner = c->import; |
| | 98 | // TODO line/column. mapping to C file?? |
| | 99 | return node; |
| 114 | } | 100 | } |
| 115 | | 101 | |
| 116 | static Tld *get_global(Context *c, Buf *name) { | 102 | static AstNode *trans_create_node_float_lit(Context *c, double value) { |
| 117 | { | 103 | AstNode *node = trans_create_node(c, NodeTypeFloatLiteral); |
| 118 | auto entry = c->import->decls_scope->decl_table.maybe_get(name); | 104 | node->data.float_literal.bigfloat = allocate<BigFloat>(1); |
| 119 | if (entry) | 105 | bigfloat_init_64(node->data.float_literal.bigfloat, value); |
| 120 | return entry->value; | 106 | return node; |
| 121 | } | | |
| 122 | { | | |
| 123 | auto entry = c->macro_table.maybe_get(name); | | |
| 124 | if (entry) | | |
| 125 | return entry->value; | | |
| 126 | } | | |
| 127 | return nullptr; | | |
| 128 | } | 107 | } |
| 129 | | 108 | |
| 130 | static const char *decl_name(const Decl *decl) { | 109 | static AstNode *trans_create_node_symbol(Context *c, Buf *name) { |
| 131 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); | 110 | AstNode *node = trans_create_node(c, NodeTypeSymbol); |
| 132 | return (const char *)named_decl->getName().bytes_begin(); | 111 | node->data.symbol_expr.symbol = name; |
| | 112 | return node; |
| 133 | } | 113 | } |
| 134 | | 114 | |
| 135 | static void parseh_init_tld(Context *c, Tld *tld, TldId id, Buf *name) { | 115 | static AstNode *trans_create_node_symbol_str(Context *c, const char *name) { |
| 136 | init_tld(tld, id, name, c->visib_mod, c->source_node, &c->import->decls_scope->base); | 116 | return trans_create_node_symbol(c, buf_create_from_str(name)); |
| 137 | tld->resolution = TldResolutionOk; | | |
| 138 | tld->import = c->import; | | |
| 139 | } | 117 | } |
| 140 | | 118 | |
| 141 | static Tld *create_inline_fn_tld(Context *c, Buf *fn_name, TldVar *tld_var) { | 119 | static AstNode *trans_create_node_builtin_fn_call(Context *c, Buf *name) { |
| 142 | TldFn *tld_fn = allocate<TldFn>(1); | 120 | AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); |
| 143 | parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name); | 121 | node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, name); |
| 144 | tld_fn->fn_entry = ir_create_inline_fn(c->codegen, fn_name, tld_var->var, &c->import->decls_scope->base); | 122 | node->data.fn_call_expr.is_builtin = true; |
| 145 | return &tld_fn->base; | 123 | return node; |
| 146 | } | 124 | } |
| 147 | | 125 | |
| 148 | static TldVar *create_global_var(Context *c, Buf *name, ConstExprValue *var_value, bool is_const) { | 126 | static AstNode *trans_create_node_builtin_fn_call_str(Context *c, const char *name) { |
| 149 | auto entry = c->import->decls_scope->decl_table.maybe_get(name); | 127 | return trans_create_node_builtin_fn_call(c, buf_create_from_str(name)); |
| 150 | if (entry) { | | |
| 151 | Tld *existing_tld = entry->value; | | |
| 152 | assert(existing_tld->id == TldIdVar); | | |
| 153 | return (TldVar *)existing_tld; | | |
| 154 | } | | |
| 155 | TldVar *tld_var = allocate<TldVar>(1); | | |
| 156 | parseh_init_tld(c, &tld_var->base, TldIdVar, name); | | |
| 157 | tld_var->var = add_variable(c->codegen, c->source_node, &c->import->decls_scope->base, | | |
| 158 | name, is_const, var_value, &tld_var->base); | | |
| 159 | c->codegen->global_vars.append(tld_var); | | |
| 160 | return tld_var; | | |
| 161 | } | 128 | } |
| 162 | | 129 | |
| 163 | static Tld *create_global_str_lit_var(Context *c, Buf *name, Buf *value) { | 130 | static AstNode *trans_create_node_opaque(Context *c) { |
| 164 | TldVar *tld_var = create_global_var(c, name, create_const_c_str_lit(c->codegen, value), true); | 131 | return trans_create_node_builtin_fn_call_str(c, "opaque"); |
| 165 | return &tld_var->base; | | |
| 166 | } | 132 | } |
| 167 | | 133 | |
| 168 | static Tld *create_global_num_lit_unsigned_negative_type(Context *c, Buf *name, uint64_t x, bool negative, TypeTableEntry *type_entry) { | 134 | static AstNode *trans_create_node_field_access(Context *c, AstNode *container, Buf *field_name) { |
| 169 | ConstExprValue *var_val = create_const_unsigned_negative(type_entry, x, negative); | 135 | AstNode *node = trans_create_node(c, NodeTypeFieldAccessExpr); |
| 170 | TldVar *tld_var = create_global_var(c, name, var_val, true); | 136 | node->data.field_access_expr.struct_expr = container; |
| 171 | return &tld_var->base; | 137 | node->data.field_access_expr.field_name = field_name; |
| | 138 | return node; |
| 172 | } | 139 | } |
| 173 | | 140 | |
| 174 | static Tld *create_global_num_lit_unsigned_negative(Context *c, Buf *name, uint64_t x, bool negative) { | 141 | static AstNode *trans_create_node_prefix_op(Context *c, PrefixOp op, AstNode *child_node) { |
| 175 | return create_global_num_lit_unsigned_negative_type(c, name, x, negative, c->codegen->builtin_types.entry_num_lit_int); | 142 | AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr); |
| | 143 | node->data.prefix_op_expr.prefix_op = op; |
| | 144 | node->data.prefix_op_expr.primary_expr = child_node; |
| | 145 | return node; |
| 176 | } | 146 | } |
| 177 | | 147 | |
| 178 | static Tld *create_global_num_lit_float(Context *c, Buf *name, double value) { | 148 | static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_volatile, AstNode *child_node) { |
| 179 | ConstExprValue *var_val = create_const_float(c->codegen->builtin_types.entry_num_lit_float, value); | 149 | AstNode *node = trans_create_node(c, NodeTypeAddrOfExpr); |
| 180 | TldVar *tld_var = create_global_var(c, name, var_val, true); | 150 | node->data.addr_of_expr.is_const = is_const; |
| 181 | return &tld_var->base; | 151 | node->data.addr_of_expr.is_volatile = is_volatile; |
| | 152 | node->data.addr_of_expr.op_expr = child_node; |
| | 153 | return node; |
| 182 | } | 154 | } |
| 183 | | 155 | |
| 184 | static ConstExprValue *create_const_int_ap(Context *c, TypeTableEntry *type, const Decl *source_decl, | 156 | static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) { |
| 185 | const llvm::APSInt &aps_int) | 157 | AstNode *node = trans_create_node(c, NodeTypeStringLiteral); |
| 186 | { | 158 | node->data.string_literal.buf = buf; |
| 187 | if (aps_int.isSigned()) { | 159 | node->data.string_literal.c = true; |
| 188 | if (aps_int > INT64_MAX || aps_int < INT64_MIN) { | 160 | return node; |
| 189 | emit_warning(c, source_decl->getLocation(), "integer overflow\n"); | | |
| 190 | return nullptr; | | |
| 191 | } else { | | |
| 192 | return create_const_signed(type, aps_int.getExtValue()); | | |
| 193 | } | | |
| 194 | } else { | | |
| 195 | if (aps_int > INT64_MAX) { | | |
| 196 | emit_warning(c, source_decl->getLocation(), "integer overflow\n"); | | |
| 197 | return nullptr; | | |
| 198 | } else { | | |
| 199 | return create_const_unsigned_negative(type, aps_int.getExtValue(), false); | | |
| 200 | } | | |
| 201 | } | | |
| 202 | } | 161 | } |
| 203 | | 162 | |
| 204 | static Tld *create_global_num_lit_ap(Context *c, const Decl *source_decl, Buf *name, | 163 | static AstNode *trans_create_node_unsigned_negative(Context *c, uint64_t x, bool is_negative) { |
| 205 | const llvm::APSInt &aps_int) | 164 | AstNode *node = trans_create_node(c, NodeTypeIntLiteral); |
| 206 | { | 165 | node->data.int_literal.bigint = allocate<BigInt>(1); |
| 207 | ConstExprValue *const_value = create_const_int_ap(c, c->codegen->builtin_types.entry_num_lit_int, | 166 | bigint_init_data(node->data.int_literal.bigint, &x, 1, is_negative); |
| 208 | source_decl, aps_int); | 167 | return node; |
| 209 | if (!const_value) | | |
| 210 | return nullptr; | | |
| 211 | TldVar *tld_var = create_global_var(c, name, const_value, true); | | |
| 212 | return &tld_var->base; | | |
| 213 | } | 168 | } |
| 214 | | 169 | |
| 215 | | 170 | static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) { |
| 216 | static Tld *add_const_type(Context *c, Buf *name, TypeTableEntry *type_entry) { | 171 | return trans_create_node_unsigned_negative(c, x, false); |
| 217 | ConstExprValue *var_value = create_const_type(c->codegen, type_entry); | | |
| 218 | TldVar *tld_var = create_global_var(c, name, var_value, true); | | |
| 219 | add_global(c, &tld_var->base); | | |
| 220 | | | |
| 221 | c->global_type_table.put(name, type_entry); | | |
| 222 | return &tld_var->base; | | |
| 223 | } | 172 | } |
| 224 | | 173 | |
| 225 | static Tld *add_container_tld(Context *c, TypeTableEntry *type_entry) { | 174 | static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) { |
| 226 | return add_const_type(c, &type_entry->name, type_entry); | 175 | AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); |
| | 176 | node->data.fn_call_expr.fn_ref_expr = dest; |
| | 177 | node->data.fn_call_expr.params.resize(1); |
| | 178 | node->data.fn_call_expr.params.items[0] = src; |
| | 179 | return node; |
| 227 | } | 180 | } |
| 228 | | 181 | |
| 229 | static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) { | 182 | static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative, |
| 230 | return (type_entry == c->codegen->builtin_types.entry_c_void); | 183 | const char *type_name) |
| | 184 | { |
| | 185 | AstNode *lit_node = trans_create_node_unsigned_negative(c, x, is_negative); |
| | 186 | return trans_create_node_cast(c, trans_create_node_symbol_str(c, type_name), lit_node); |
| 231 | } | 187 | } |
| 232 | | 188 | |
| 233 | static bool qual_type_child_is_fn_proto(const QualType &qt) { | 189 | static AstNode *trans_create_node_array_type(Context *c, AstNode *size_node, AstNode *child_type_node) { |
| 234 | if (qt.getTypePtr()->getTypeClass() == Type::Paren) { | 190 | AstNode *node = trans_create_node(c, NodeTypeArrayType); |
| 235 | const ParenType *paren_type = static_cast<const ParenType *>(qt.getTypePtr()); | 191 | node->data.array_type.size = size_node; |
| 236 | if (paren_type->getInnerType()->getTypeClass() == Type::FunctionProto) { | 192 | node->data.array_type.child_type = child_type_node; |
| 237 | return true; | 193 | return node; |
| 238 | } | | |
| 239 | } else if (qt.getTypePtr()->getTypeClass() == Type::Attributed) { | | |
| 240 | const AttributedType *attr_type = static_cast<const AttributedType *>(qt.getTypePtr()); | | |
| 241 | return qual_type_child_is_fn_proto(attr_type->getEquivalentType()); | | |
| 242 | } | | |
| 243 | return false; | | |
| 244 | } | 194 | } |
| 245 | | 195 | |
| 246 | static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl, | 196 | static AstNode *trans_create_node_var_decl(Context *c, bool is_const, Buf *var_name, AstNode *type_node, |
| 247 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table) | 197 | AstNode *init_node) |
| 248 | { | 198 | { |
| 249 | switch (ty->getTypeClass()) { | 199 | AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration); |
| 250 | case Type::Builtin: | 200 | node->data.variable_declaration.visib_mod = c->visib_mod; |
| 251 | { | 201 | node->data.variable_declaration.symbol = var_name; |
| 252 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); | 202 | node->data.variable_declaration.is_const = is_const; |
| 253 | switch (builtin_ty->getKind()) { | 203 | node->data.variable_declaration.type = type_node; |
| 254 | case BuiltinType::Void: | 204 | node->data.variable_declaration.expr = init_node; |
| 255 | return c->codegen->builtin_types.entry_c_void; | 205 | return node; |
| 256 | case BuiltinType::Bool: | 206 | } |
| 257 | return c->codegen->builtin_types.entry_bool; | | |
| 258 | case BuiltinType::Char_U: | | |
| 259 | case BuiltinType::UChar: | | |
| 260 | case BuiltinType::Char_S: | | |
| 261 | return c->codegen->builtin_types.entry_u8; | | |
| 262 | case BuiltinType::SChar: | | |
| 263 | return c->codegen->builtin_types.entry_i8; | | |
| 264 | case BuiltinType::UShort: | | |
| 265 | return get_c_int_type(c->codegen, CIntTypeUShort); | | |
| 266 | case BuiltinType::UInt: | | |
| 267 | return get_c_int_type(c->codegen, CIntTypeUInt); | | |
| 268 | case BuiltinType::ULong: | | |
| 269 | return get_c_int_type(c->codegen, CIntTypeULong); | | |
| 270 | case BuiltinType::ULongLong: | | |
| 271 | return get_c_int_type(c->codegen, CIntTypeULongLong); | | |
| 272 | case BuiltinType::Short: | | |
| 273 | return get_c_int_type(c->codegen, CIntTypeShort); | | |
| 274 | case BuiltinType::Int: | | |
| 275 | return get_c_int_type(c->codegen, CIntTypeInt); | | |
| 276 | case BuiltinType::Long: | | |
| 277 | return get_c_int_type(c->codegen, CIntTypeLong); | | |
| 278 | case BuiltinType::LongLong: | | |
| 279 | return get_c_int_type(c->codegen, CIntTypeLongLong); | | |
| 280 | case BuiltinType::UInt128: | | |
| 281 | return c->codegen->builtin_types.entry_u128; | | |
| 282 | case BuiltinType::Int128: | | |
| 283 | return c->codegen->builtin_types.entry_i128; | | |
| 284 | case BuiltinType::Float: | | |
| 285 | return c->codegen->builtin_types.entry_f32; | | |
| 286 | case BuiltinType::Double: | | |
| 287 | return c->codegen->builtin_types.entry_f64; | | |
| 288 | case BuiltinType::Float128: | | |
| 289 | return c->codegen->builtin_types.entry_f128; | | |
| 290 | case BuiltinType::LongDouble: | | |
| 291 | return c->codegen->builtin_types.entry_c_longdouble; | | |
| 292 | case BuiltinType::WChar_U: | | |
| 293 | case BuiltinType::Char16: | | |
| 294 | case BuiltinType::Char32: | | |
| 295 | case BuiltinType::WChar_S: | | |
| 296 | case BuiltinType::Half: | | |
| 297 | case BuiltinType::NullPtr: | | |
| 298 | case BuiltinType::ObjCId: | | |
| 299 | case BuiltinType::ObjCClass: | | |
| 300 | case BuiltinType::ObjCSel: | | |
| 301 | case BuiltinType::OMPArraySection: | | |
| 302 | case BuiltinType::Dependent: | | |
| 303 | case BuiltinType::Overload: | | |
| 304 | case BuiltinType::BoundMember: | | |
| 305 | case BuiltinType::PseudoObject: | | |
| 306 | case BuiltinType::UnknownAny: | | |
| 307 | case BuiltinType::BuiltinFn: | | |
| 308 | case BuiltinType::ARCUnbridgedCast: | | |
| 309 | | 207 | |
| 310 | case BuiltinType::OCLImage1dRO: | | |
| 311 | case BuiltinType::OCLImage1dArrayRO: | | |
| 312 | case BuiltinType::OCLImage1dBufferRO: | | |
| 313 | case BuiltinType::OCLImage2dRO: | | |
| 314 | case BuiltinType::OCLImage2dArrayRO: | | |
| 315 | case BuiltinType::OCLImage2dDepthRO: | | |
| 316 | case BuiltinType::OCLImage2dArrayDepthRO: | | |
| 317 | case BuiltinType::OCLImage2dMSAARO: | | |
| 318 | case BuiltinType::OCLImage2dArrayMSAARO: | | |
| 319 | case BuiltinType::OCLImage2dMSAADepthRO: | | |
| 320 | case BuiltinType::OCLImage2dArrayMSAADepthRO: | | |
| 321 | case BuiltinType::OCLImage3dRO: | | |
| 322 | case BuiltinType::OCLImage1dWO: | | |
| 323 | case BuiltinType::OCLImage1dArrayWO: | | |
| 324 | case BuiltinType::OCLImage1dBufferWO: | | |
| 325 | case BuiltinType::OCLImage2dWO: | | |
| 326 | case BuiltinType::OCLImage2dArrayWO: | | |
| 327 | case BuiltinType::OCLImage2dDepthWO: | | |
| 328 | case BuiltinType::OCLImage2dArrayDepthWO: | | |
| 329 | case BuiltinType::OCLImage2dMSAAWO: | | |
| 330 | case BuiltinType::OCLImage2dArrayMSAAWO: | | |
| 331 | case BuiltinType::OCLImage2dMSAADepthWO: | | |
| 332 | case BuiltinType::OCLImage2dArrayMSAADepthWO: | | |
| 333 | case BuiltinType::OCLImage3dWO: | | |
| 334 | case BuiltinType::OCLImage1dRW: | | |
| 335 | case BuiltinType::OCLImage1dArrayRW: | | |
| 336 | case BuiltinType::OCLImage1dBufferRW: | | |
| 337 | case BuiltinType::OCLImage2dRW: | | |
| 338 | case BuiltinType::OCLImage2dArrayRW: | | |
| 339 | case BuiltinType::OCLImage2dDepthRW: | | |
| 340 | case BuiltinType::OCLImage2dArrayDepthRW: | | |
| 341 | case BuiltinType::OCLImage2dMSAARW: | | |
| 342 | case BuiltinType::OCLImage2dArrayMSAARW: | | |
| 343 | case BuiltinType::OCLImage2dMSAADepthRW: | | |
| 344 | case BuiltinType::OCLImage2dArrayMSAADepthRW: | | |
| 345 | case BuiltinType::OCLImage3dRW: | | |
| 346 | case BuiltinType::OCLSampler: | | |
| 347 | case BuiltinType::OCLEvent: | | |
| 348 | case BuiltinType::OCLClkEvent: | | |
| 349 | case BuiltinType::OCLQueue: | | |
| 350 | case BuiltinType::OCLReserveID: | | |
| 351 | emit_warning(c, decl->getLocation(), "missed a builtin type"); | | |
| 352 | return c->codegen->builtin_types.entry_invalid; | | |
| 353 | } | | |
| 354 | break; | | |
| 355 | } | | |
| 356 | case Type::Pointer: | | |
| 357 | { | | |
| 358 | const PointerType *pointer_ty = static_cast<const PointerType*>(ty); | | |
| 359 | QualType child_qt = pointer_ty->getPointeeType(); | | |
| 360 | TypeTableEntry *child_type = resolve_qual_type(c, child_qt, decl); | | |
| 361 | if (type_is_invalid(child_type)) { | | |
| 362 | emit_warning(c, decl->getLocation(), "pointer to unresolved type"); | | |
| 363 | return c->codegen->builtin_types.entry_invalid; | | |
| 364 | } | | |
| 365 | | 208 | |
| 366 | if (qual_type_child_is_fn_proto(child_qt)) { | 209 | static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_name, AstNode *src_proto_node) { |
| 367 | return get_maybe_type(c->codegen, child_type); | 210 | AstNode *fn_def = trans_create_node(c, NodeTypeFnDef); |
| 368 | } | 211 | AstNode *fn_proto = trans_create_node(c, NodeTypeFnProto); |
| 369 | bool is_const = child_qt.isConstQualified(); | 212 | fn_proto->data.fn_proto.visib_mod = c->visib_mod;; |
| | 213 | fn_proto->data.fn_proto.name = fn_name; |
| | 214 | fn_proto->data.fn_proto.is_inline = true; |
| | 215 | fn_proto->data.fn_proto.return_type = src_proto_node->data.fn_proto.return_type; // TODO ok for these to alias? |
| 370 | | 216 | |
| 371 | TypeTableEntry *non_null_pointer_type = get_pointer_to_type(c->codegen, child_type, is_const); | 217 | fn_def->data.fn_def.fn_proto = fn_proto; |
| 372 | return get_maybe_type(c->codegen, non_null_pointer_type); | 218 | fn_proto->data.fn_proto.fn_def_node = fn_def; |
| 373 | } | | |
| 374 | case Type::Typedef: | | |
| 375 | { | | |
| 376 | const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty); | | |
| 377 | const TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); | | |
| 378 | Buf *type_name = buf_create_from_str(decl_name(typedef_decl)); | | |
| 379 | if (buf_eql_str(type_name, "uint8_t")) { | | |
| 380 | return c->codegen->builtin_types.entry_u8; | | |
| 381 | } else if (buf_eql_str(type_name, "int8_t")) { | | |
| 382 | return c->codegen->builtin_types.entry_i8; | | |
| 383 | } else if (buf_eql_str(type_name, "uint16_t")) { | | |
| 384 | return c->codegen->builtin_types.entry_u16; | | |
| 385 | } else if (buf_eql_str(type_name, "int16_t")) { | | |
| 386 | return c->codegen->builtin_types.entry_i16; | | |
| 387 | } else if (buf_eql_str(type_name, "uint32_t")) { | | |
| 388 | return c->codegen->builtin_types.entry_u32; | | |
| 389 | } else if (buf_eql_str(type_name, "int32_t")) { | | |
| 390 | return c->codegen->builtin_types.entry_i32; | | |
| 391 | } else if (buf_eql_str(type_name, "uint64_t")) { | | |
| 392 | return c->codegen->builtin_types.entry_u64; | | |
| 393 | } else if (buf_eql_str(type_name, "int64_t")) { | | |
| 394 | return c->codegen->builtin_types.entry_i64; | | |
| 395 | } else if (buf_eql_str(type_name, "intptr_t")) { | | |
| 396 | return c->codegen->builtin_types.entry_isize; | | |
| 397 | } else if (buf_eql_str(type_name, "uintptr_t")) { | | |
| 398 | return c->codegen->builtin_types.entry_usize; | | |
| 399 | } else { | | |
| 400 | auto entry = type_table->maybe_get(type_name); | | |
| 401 | if (entry) { | | |
| 402 | if (type_is_invalid(entry->value)) { | | |
| 403 | return c->codegen->builtin_types.entry_invalid; | | |
| 404 | } else { | | |
| 405 | return entry->value; | | |
| 406 | } | | |
| 407 | } else { | | |
| 408 | return c->codegen->builtin_types.entry_invalid; | | |
| 409 | } | | |
| 410 | } | | |
| 411 | } | | |
| 412 | case Type::Elaborated: | | |
| 413 | { | | |
| 414 | const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty); | | |
| 415 | switch (elaborated_ty->getKeyword()) { | | |
| 416 | case ETK_Struct: | | |
| 417 | return resolve_qual_type_with_table(c, elaborated_ty->getNamedType(), | | |
| 418 | decl, &c->struct_type_table); | | |
| 419 | case ETK_Enum: | | |
| 420 | return resolve_qual_type_with_table(c, elaborated_ty->getNamedType(), | | |
| 421 | decl, &c->enum_type_table); | | |
| 422 | case ETK_Interface: | | |
| 423 | case ETK_Union: | | |
| 424 | case ETK_Class: | | |
| 425 | case ETK_Typename: | | |
| 426 | case ETK_None: | | |
| 427 | emit_warning(c, decl->getLocation(), "unsupported elaborated type"); | | |
| 428 | return c->codegen->builtin_types.entry_invalid; | | |
| 429 | } | | |
| 430 | } | | |
| 431 | case Type::FunctionProto: | | |
| 432 | { | | |
| 433 | const FunctionProtoType *fn_proto_ty = static_cast<const FunctionProtoType*>(ty); | | |
| 434 | | 219 | |
| 435 | switch (fn_proto_ty->getCallConv()) { | 220 | AstNode *unwrap_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, trans_create_node_symbol(c, var_name)); |
| 436 | case CC_C: // __attribute__((cdecl)) | 221 | AstNode *fn_call_node = trans_create_node(c, NodeTypeFnCallExpr); |
| 437 | break; | 222 | fn_call_node->data.fn_call_expr.fn_ref_expr = unwrap_node; |
| 438 | case CC_X86StdCall: // __attribute__((stdcall)) | | |
| 439 | emit_warning(c, decl->getLocation(), "function type has x86 stdcall calling convention"); | | |
| 440 | return c->codegen->builtin_types.entry_invalid; | | |
| 441 | case CC_X86FastCall: // __attribute__((fastcall)) | | |
| 442 | emit_warning(c, decl->getLocation(), "function type has x86 fastcall calling convention"); | | |
| 443 | return c->codegen->builtin_types.entry_invalid; | | |
| 444 | case CC_X86ThisCall: // __attribute__((thiscall)) | | |
| 445 | emit_warning(c, decl->getLocation(), "function type has x86 thiscall calling convention"); | | |
| 446 | return c->codegen->builtin_types.entry_invalid; | | |
| 447 | case CC_X86VectorCall: // __attribute__((vectorcall)) | | |
| 448 | emit_warning(c, decl->getLocation(), "function type has x86 vectorcall calling convention"); | | |
| 449 | return c->codegen->builtin_types.entry_invalid; | | |
| 450 | case CC_X86Pascal: // __attribute__((pascal)) | | |
| 451 | emit_warning(c, decl->getLocation(), "function type has x86 pascal calling convention"); | | |
| 452 | return c->codegen->builtin_types.entry_invalid; | | |
| 453 | case CC_Win64: // __attribute__((ms_abi)) | | |
| 454 | emit_warning(c, decl->getLocation(), "function type has win64 calling convention"); | | |
| 455 | return c->codegen->builtin_types.entry_invalid; | | |
| 456 | case CC_X86_64SysV: // __attribute__((sysv_abi)) | | |
| 457 | emit_warning(c, decl->getLocation(), "function type has x86 64sysv calling convention"); | | |
| 458 | return c->codegen->builtin_types.entry_invalid; | | |
| 459 | case CC_X86RegCall: | | |
| 460 | emit_warning(c, decl->getLocation(), "function type has x86 reg calling convention"); | | |
| 461 | return c->codegen->builtin_types.entry_invalid; | | |
| 462 | case CC_AAPCS: // __attribute__((pcs("aapcs"))) | | |
| 463 | emit_warning(c, decl->getLocation(), "function type has aapcs calling convention"); | | |
| 464 | return c->codegen->builtin_types.entry_invalid; | | |
| 465 | case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp"))) | | |
| 466 | emit_warning(c, decl->getLocation(), "function type has aapcs-vfp calling convention"); | | |
| 467 | return c->codegen->builtin_types.entry_invalid; | | |
| 468 | case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc)) | | |
| 469 | emit_warning(c, decl->getLocation(), "function type has intel_ocl_bicc calling convention"); | | |
| 470 | return c->codegen->builtin_types.entry_invalid; | | |
| 471 | case CC_SpirFunction: // default for OpenCL functions on SPIR target | | |
| 472 | emit_warning(c, decl->getLocation(), "function type has SPIR function calling convention"); | | |
| 473 | return c->codegen->builtin_types.entry_invalid; | | |
| 474 | case CC_OpenCLKernel: | | |
| 475 | emit_warning(c, decl->getLocation(), "function type has OpenCLKernel calling convention"); | | |
| 476 | return c->codegen->builtin_types.entry_invalid; | | |
| 477 | case CC_Swift: | | |
| 478 | emit_warning(c, decl->getLocation(), "function type has Swift calling convention"); | | |
| 479 | return c->codegen->builtin_types.entry_invalid; | | |
| 480 | case CC_PreserveMost: | | |
| 481 | emit_warning(c, decl->getLocation(), "function type has PreserveMost calling convention"); | | |
| 482 | return c->codegen->builtin_types.entry_invalid; | | |
| 483 | case CC_PreserveAll: | | |
| 484 | emit_warning(c, decl->getLocation(), "function type has PreserveAll calling convention"); | | |
| 485 | return c->codegen->builtin_types.entry_invalid; | | |
| 486 | } | | |
| 487 | | 223 | |
| 488 | FnTypeId fn_type_id = {0}; | 224 | for (size_t i = 0; i < src_proto_node->data.fn_proto.params.length; i += 1) { |
| 489 | fn_type_id.cc = CallingConventionC; | 225 | AstNode *src_param_node = src_proto_node->data.fn_proto.params.at(i); |
| 490 | fn_type_id.is_var_args = fn_proto_ty->isVariadic(); | 226 | Buf *param_name = src_param_node->data.param_decl.name; |
| 491 | fn_type_id.param_count = fn_proto_ty->getNumParams(); | | |
| 492 | | 227 | |
| | 228 | AstNode *dest_param_node = trans_create_node(c, NodeTypeParamDecl); |
| | 229 | dest_param_node->data.param_decl.name = param_name; |
| | 230 | dest_param_node->data.param_decl.type = src_param_node->data.param_decl.type; |
| | 231 | dest_param_node->data.param_decl.is_noalias = src_param_node->data.param_decl.is_noalias; |
| | 232 | fn_proto->data.fn_proto.params.append(dest_param_node); |
| 493 | | 233 | |
| 494 | if (fn_proto_ty->getNoReturnAttr()) { | 234 | fn_call_node->data.fn_call_expr.params.append(trans_create_node_symbol(c, param_name)); |
| 495 | fn_type_id.return_type = c->codegen->builtin_types.entry_unreachable; | | |
| 496 | } else { | | |
| 497 | fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl); | | |
| 498 | if (type_is_invalid(fn_type_id.return_type)) { | | |
| 499 | emit_warning(c, decl->getLocation(), "unresolved function proto return type"); | | |
| 500 | return c->codegen->builtin_types.entry_invalid; | | |
| 501 | } | | |
| 502 | // convert c_void to actual void (only for return type) | | |
| 503 | if (is_c_void_type(c, fn_type_id.return_type)) { | | |
| 504 | fn_type_id.return_type = c->codegen->builtin_types.entry_void; | | |
| 505 | } | | |
| 506 | } | | |
| 507 | | 235 | |
| 508 | fn_type_id.param_info = allocate_nonzero<FnTypeParamInfo>(fn_type_id.param_count); | 236 | } |
| 509 | for (size_t i = 0; i < fn_type_id.param_count; i += 1) { | | |
| 510 | QualType qt = fn_proto_ty->getParamType(i); | | |
| 511 | TypeTableEntry *param_type = resolve_qual_type(c, qt, decl); | | |
| 512 | | 237 | |
| 513 | if (type_is_invalid(param_type)) { | 238 | AstNode *block = trans_create_node(c, NodeTypeBlock); |
| 514 | emit_warning(c, decl->getLocation(), "unresolved function proto parameter type"); | 239 | block->data.block.statements.resize(1); |
| 515 | return c->codegen->builtin_types.entry_invalid; | 240 | block->data.block.statements.items[0] = fn_call_node; |
| 516 | } | | |
| 517 | | 241 | |
| 518 | FnTypeParamInfo *param_info = &fn_type_id.param_info[i]; | 242 | fn_def->data.fn_def.body = block; |
| 519 | param_info->type = param_type; | 243 | return fn_def; |
| 520 | param_info->is_noalias = qt.isRestrictQualified(); | 244 | } |
| 521 | } | | |
| 522 | | 245 | |
| 523 | return get_fn_type(c->codegen, &fn_type_id); | 246 | static AstNode *get_global(Context *c, Buf *name) { |
| 524 | } | 247 | for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) { |
| 525 | case Type::Record: | 248 | AstNode *decl_node = c->root->data.root.top_level_decls.items[i]; |
| 526 | { | 249 | if (decl_node->type == NodeTypeVariableDeclaration) { |
| 527 | const RecordType *record_ty = static_cast<const RecordType*>(ty); | 250 | if (buf_eql_buf(decl_node->data.variable_declaration.symbol, name)) { |
| 528 | return resolve_record_decl(c, record_ty->getDecl()); | 251 | return decl_node; |
| 529 | } | | |
| 530 | case Type::Enum: | | |
| 531 | { | | |
| 532 | const EnumType *enum_ty = static_cast<const EnumType*>(ty); | | |
| 533 | return resolve_enum_decl(c, enum_ty->getDecl()); | | |
| 534 | } | 252 | } |
| 535 | case Type::ConstantArray: | 253 | } else if (decl_node->type == NodeTypeFnDef) { |
| 536 | { | 254 | if (buf_eql_buf(decl_node->data.fn_def.fn_proto->data.fn_proto.name, name)) { |
| 537 | const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty); | 255 | return decl_node; |
| 538 | TypeTableEntry *child_type = resolve_qual_type(c, const_arr_ty->getElementType(), decl); | | |
| 539 | if (child_type->id == TypeTableEntryIdInvalid) { | | |
| 540 | emit_warning(c, decl->getLocation(), "unresolved array element type"); | | |
| 541 | return child_type; | | |
| 542 | } | | |
| 543 | uint64_t size = const_arr_ty->getSize().getLimitedValue(); | | |
| 544 | return get_array_type(c->codegen, child_type, size); | | |
| 545 | } | 256 | } |
| 546 | case Type::Paren: | 257 | } else if (decl_node->type == NodeTypeFnProto) { |
| 547 | { | 258 | if (buf_eql_buf(decl_node->data.fn_proto.name, name)) { |
| 548 | const ParenType *paren_ty = static_cast<const ParenType *>(ty); | 259 | return decl_node; |
| 549 | return resolve_qual_type(c, paren_ty->getInnerType(), decl); | | |
| 550 | } | 260 | } |
| 551 | case Type::Decayed: | 261 | } |
| 552 | { | | |
| 553 | const DecayedType *decayed_ty = static_cast<const DecayedType *>(ty); | | |
| 554 | return resolve_qual_type(c, decayed_ty->getDecayedType(), decl); | | |
| 555 | } | | |
| 556 | case Type::Attributed: | | |
| 557 | { | | |
| 558 | const AttributedType *attributed_ty = static_cast<const AttributedType *>(ty); | | |
| 559 | return resolve_qual_type(c, attributed_ty->getEquivalentType(), decl); | | |
| 560 | } | | |
| 561 | case Type::BlockPointer: | | |
| 562 | case Type::LValueReference: | | |
| 563 | case Type::RValueReference: | | |
| 564 | case Type::MemberPointer: | | |
| 565 | case Type::IncompleteArray: | | |
| 566 | case Type::VariableArray: | | |
| 567 | case Type::DependentSizedArray: | | |
| 568 | case Type::DependentSizedExtVector: | | |
| 569 | case Type::Vector: | | |
| 570 | case Type::ExtVector: | | |
| 571 | case Type::FunctionNoProto: | | |
| 572 | case Type::UnresolvedUsing: | | |
| 573 | case Type::Adjusted: | | |
| 574 | case Type::TypeOfExpr: | | |
| 575 | case Type::TypeOf: | | |
| 576 | case Type::Decltype: | | |
| 577 | case Type::UnaryTransform: | | |
| 578 | case Type::TemplateTypeParm: | | |
| 579 | case Type::SubstTemplateTypeParm: | | |
| 580 | case Type::SubstTemplateTypeParmPack: | | |
| 581 | case Type::TemplateSpecialization: | | |
| 582 | case Type::Auto: | | |
| 583 | case Type::InjectedClassName: | | |
| 584 | case Type::DependentName: | | |
| 585 | case Type::DependentTemplateSpecialization: | | |
| 586 | case Type::PackExpansion: | | |
| 587 | case Type::ObjCObject: | | |
| 588 | case Type::ObjCInterface: | | |
| 589 | case Type::Complex: | | |
| 590 | case Type::ObjCObjectPointer: | | |
| 591 | case Type::Atomic: | | |
| 592 | case Type::Pipe: | | |
| 593 | case Type::ObjCTypeParam: | | |
| 594 | case Type::DeducedTemplateSpecialization: | | |
| 595 | emit_warning(c, decl->getLocation(), "missed a '%s' type", ty->getTypeClassName()); | | |
| 596 | return c->codegen->builtin_types.entry_invalid; | | |
| 597 | } | 262 | } |
| 598 | zig_unreachable(); | 263 | { |
| | 264 | auto entry = c->macro_table.maybe_get(name); |
| | 265 | if (entry) |
| | 266 | return entry->value; |
| | 267 | } |
| | 268 | return nullptr; |
| | 269 | } |
| | 270 | |
| | 271 | static AstNode *add_global_var(Context *c, Buf *var_name, AstNode *value_node) { |
| | 272 | bool is_const = true; |
| | 273 | AstNode *type_node = nullptr; |
| | 274 | AstNode *node = trans_create_node_var_decl(c, is_const, var_name, type_node, value_node); |
| | 275 | c->root->data.root.top_level_decls.append(node); |
| | 276 | return node; |
| | 277 | } |
| | 278 | |
| | 279 | static const char *decl_name(const Decl *decl) { |
| | 280 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); |
| | 281 | return (const char *)named_decl->getName().bytes_begin(); |
| 599 | } | 282 | } |
| 600 | | 283 | |
| 601 | static TypeTableEntry *resolve_qual_type_with_table(Context *c, QualType qt, const Decl *decl, | 284 | static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) { |
| 602 | HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table) | 285 | AstNode *node = trans_create_node(c, NodeTypeIntLiteral); |
| 603 | { | 286 | node->data.int_literal.bigint = allocate<BigInt>(1); |
| 604 | return resolve_type_with_table(c, qt.getTypePtr(), decl, type_table); | 287 | bigint_init_data(node->data.int_literal.bigint, aps_int.getRawData(), aps_int.getNumWords(), aps_int.isNegative()); |
| | 288 | return node; |
| | 289 | |
| 605 | } | 290 | } |
| 606 | | 291 | |
| 607 | static TypeTableEntry *resolve_qual_type(Context *c, QualType qt, const Decl *decl) { | 292 | static bool is_c_void_type(AstNode *node) { |
| 608 | return resolve_qual_type_with_table(c, qt, decl, &c->global_type_table); | 293 | return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void")); |
| 609 | } | 294 | } |
| 610 | | 295 | |
| 611 | #include "ast_render.hpp" | 296 | static bool qual_type_child_is_fn_proto(const QualType &qt) { |
| | 297 | if (qt.getTypePtr()->getTypeClass() == Type::Paren) { |
| | 298 | const ParenType *paren_type = static_cast<const ParenType *>(qt.getTypePtr()); |
| | 299 | if (paren_type->getInnerType()->getTypeClass() == Type::FunctionProto) { |
| | 300 | return true; |
| | 301 | } |
| | 302 | } else if (qt.getTypePtr()->getTypeClass() == Type::Attributed) { |
| | 303 | const AttributedType *attr_type = static_cast<const AttributedType *>(qt.getTypePtr()); |
| | 304 | return qual_type_child_is_fn_proto(attr_type->getEquivalentType()); |
| | 305 | } |
| | 306 | return false; |
| | 307 | } |
| 612 | | 308 | |
| 613 | static bool c_is_signed_integer(Context *c, QualType qt) { | 309 | static bool c_is_signed_integer(Context *c, QualType qt) { |
| 614 | const Type *c_type = qt.getTypePtr(); | 310 | const Type *c_type = qt.getTypePtr(); |
| ... | @@ -668,19 +364,12 @@ static bool c_is_float(Context *c, QualType qt) { | ... | @@ -668,19 +364,12 @@ static bool c_is_float(Context *c, QualType qt) { |
| 668 | } | 364 | } |
| 669 | | 365 | |
| 670 | static AstNode * trans_stmt(Context *c, AstNode *block, Stmt *stmt); | 366 | static AstNode * trans_stmt(Context *c, AstNode *block, Stmt *stmt); |
| 671 | static AstNode * trans_create_node(Context *c, NodeType id); | | |
| 672 | static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc); | 367 | static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc); |
| 673 | | 368 | |
| 674 | static AstNode * trans_expr(Context *c, AstNode *block, Expr *expr) { | 369 | static AstNode * trans_expr(Context *c, AstNode *block, Expr *expr) { |
| 675 | return trans_stmt(c, block, expr); | 370 | return trans_stmt(c, block, expr); |
| 676 | } | 371 | } |
| 677 | | 372 | |
| 678 | static AstNode *trans_create_symbol_node(Context *c, const char * name) { | | |
| 679 | AstNode *node = trans_create_node(c, NodeTypeSymbol); | | |
| 680 | node->data.symbol_expr.symbol = buf_create_from_str(name); | | |
| 681 | return node; | | |
| 682 | } | | |
| 683 | | | |
| 684 | static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLocation &source_loc, | 373 | static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLocation &source_loc, |
| 685 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> *type_table) | 374 | HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> *type_table) |
| 686 | { | 375 | { |
| ... | @@ -690,43 +379,43 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo | ... | @@ -690,43 +379,43 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo |
| 690 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); | 379 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); |
| 691 | switch (builtin_ty->getKind()) { | 380 | switch (builtin_ty->getKind()) { |
| 692 | case BuiltinType::Void: | 381 | case BuiltinType::Void: |
| 693 | return trans_create_symbol_node(c, "c_void"); | 382 | return trans_create_node_symbol_str(c, "c_void"); |
| 694 | case BuiltinType::Bool: | 383 | case BuiltinType::Bool: |
| 695 | return trans_create_symbol_node(c, "bool"); | 384 | return trans_create_node_symbol_str(c, "bool"); |
| 696 | case BuiltinType::Char_U: | 385 | case BuiltinType::Char_U: |
| 697 | case BuiltinType::UChar: | 386 | case BuiltinType::UChar: |
| 698 | case BuiltinType::Char_S: | 387 | case BuiltinType::Char_S: |
| 699 | return trans_create_symbol_node(c, "u8"); | 388 | return trans_create_node_symbol_str(c, "u8"); |
| 700 | case BuiltinType::SChar: | 389 | case BuiltinType::SChar: |
| 701 | return trans_create_symbol_node(c, "i8"); | 390 | return trans_create_node_symbol_str(c, "i8"); |
| 702 | case BuiltinType::UShort: | 391 | case BuiltinType::UShort: |
| 703 | return trans_create_symbol_node(c, "c_ushort"); | 392 | return trans_create_node_symbol_str(c, "c_ushort"); |
| 704 | case BuiltinType::UInt: | 393 | case BuiltinType::UInt: |
| 705 | return trans_create_symbol_node(c, "c_uint"); | 394 | return trans_create_node_symbol_str(c, "c_uint"); |
| 706 | case BuiltinType::ULong: | 395 | case BuiltinType::ULong: |
| 707 | return trans_create_symbol_node(c, "c_ulong"); | 396 | return trans_create_node_symbol_str(c, "c_ulong"); |
| 708 | case BuiltinType::ULongLong: | 397 | case BuiltinType::ULongLong: |
| 709 | return trans_create_symbol_node(c, "c_ulonglong"); | 398 | return trans_create_node_symbol_str(c, "c_ulonglong"); |
| 710 | case BuiltinType::Short: | 399 | case BuiltinType::Short: |
| 711 | return trans_create_symbol_node(c, "c_short"); | 400 | return trans_create_node_symbol_str(c, "c_short"); |
| 712 | case BuiltinType::Int: | 401 | case BuiltinType::Int: |
| 713 | return trans_create_symbol_node(c, "c_int"); | 402 | return trans_create_node_symbol_str(c, "c_int"); |
| 714 | case BuiltinType::Long: | 403 | case BuiltinType::Long: |
| 715 | return trans_create_symbol_node(c, "c_long"); | 404 | return trans_create_node_symbol_str(c, "c_long"); |
| 716 | case BuiltinType::LongLong: | 405 | case BuiltinType::LongLong: |
| 717 | return trans_create_symbol_node(c, "c_longlong"); | 406 | return trans_create_node_symbol_str(c, "c_longlong"); |
| 718 | case BuiltinType::UInt128: | 407 | case BuiltinType::UInt128: |
| 719 | return trans_create_symbol_node(c, "u128"); | 408 | return trans_create_node_symbol_str(c, "u128"); |
| 720 | case BuiltinType::Int128: | 409 | case BuiltinType::Int128: |
| 721 | return trans_create_symbol_node(c, "i128"); | 410 | return trans_create_node_symbol_str(c, "i128"); |
| 722 | case BuiltinType::Float: | 411 | case BuiltinType::Float: |
| 723 | return trans_create_symbol_node(c, "f32"); | 412 | return trans_create_node_symbol_str(c, "f32"); |
| 724 | case BuiltinType::Double: | 413 | case BuiltinType::Double: |
| 725 | return trans_create_symbol_node(c, "f64"); | 414 | return trans_create_node_symbol_str(c, "f64"); |
| 726 | case BuiltinType::Float128: | 415 | case BuiltinType::Float128: |
| 727 | return trans_create_symbol_node(c, "f128"); | 416 | return trans_create_node_symbol_str(c, "f128"); |
| 728 | case BuiltinType::LongDouble: | 417 | case BuiltinType::LongDouble: |
| 729 | return trans_create_symbol_node(c, "c_longdouble"); | 418 | return trans_create_node_symbol_str(c, "c_longdouble"); |
| 730 | case BuiltinType::WChar_U: | 419 | case BuiltinType::WChar_U: |
| 731 | case BuiltinType::Char16: | 420 | case BuiltinType::Char16: |
| 732 | case BuiltinType::Char32: | 421 | case BuiltinType::Char32: |
| ... | @@ -786,7 +475,8 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo | ... | @@ -786,7 +475,8 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo |
| 786 | case BuiltinType::OCLClkEvent: | 475 | case BuiltinType::OCLClkEvent: |
| 787 | case BuiltinType::OCLQueue: | 476 | case BuiltinType::OCLQueue: |
| 788 | case BuiltinType::OCLReserveID: | 477 | case BuiltinType::OCLReserveID: |
| 789 | zig_panic("TODO more c type"); | 478 | emit_warning(c, source_loc, "unsupported builtin type"); |
| | 479 | return nullptr; |
| 790 | } | 480 | } |
| 791 | break; | 481 | break; |
| 792 | } | 482 | } |
| ... | @@ -795,40 +485,218 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo | ... | @@ -795,40 +485,218 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo |
| 795 | const PointerType *pointer_ty = static_cast<const PointerType*>(ty); | 485 | const PointerType *pointer_ty = static_cast<const PointerType*>(ty); |
| 796 | QualType child_qt = pointer_ty->getPointeeType(); | 486 | QualType child_qt = pointer_ty->getPointeeType(); |
| 797 | AstNode *child_node = trans_qual_type(c, child_qt, source_loc); | 487 | AstNode *child_node = trans_qual_type(c, child_qt, source_loc); |
| 798 | if (child_node == nullptr) return nullptr; | 488 | if (child_node == nullptr) { |
| | 489 | emit_warning(c, source_loc, "pointer to unsupported type"); |
| | 490 | return nullptr; |
| | 491 | } |
| 799 | | 492 | |
| 800 | if (qual_type_child_is_fn_proto(child_qt)) { | 493 | if (qual_type_child_is_fn_proto(child_qt)) { |
| 801 | zig_panic("TODO pointer to function proto"); | 494 | return trans_create_node_prefix_op(c, PrefixOpMaybe, child_node); |
| 802 | } | 495 | } |
| 803 | | 496 | |
| 804 | AstNode *pointer_node = trans_create_node(c, NodeTypeAddrOfExpr); | 497 | AstNode *pointer_node = trans_create_node_addr_of(c, child_qt.isConstQualified(), |
| 805 | pointer_node->data.addr_of_expr.is_const = child_qt.isConstQualified(); | 498 | child_qt.isVolatileQualified(), child_node); |
| 806 | pointer_node->data.addr_of_expr.is_volatile = child_qt.isVolatileQualified(); | 499 | return trans_create_node_prefix_op(c, PrefixOpMaybe, pointer_node); |
| 807 | pointer_node->data.addr_of_expr.op_expr = child_node; | | |
| 808 | | | |
| 809 | AstNode *maybe_node = trans_create_node(c, NodeTypePrefixOpExpr); | | |
| 810 | maybe_node->data.prefix_op_expr.prefix_op = PrefixOpMaybe; | | |
| 811 | maybe_node->data.prefix_op_expr.primary_expr = pointer_node; | | |
| 812 | return maybe_node; | | |
| 813 | } | 500 | } |
| 814 | case Type::Typedef: | 501 | case Type::Typedef: |
| 815 | zig_panic("TODO typedef"); | 502 | { |
| | 503 | const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty); |
| | 504 | const TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); |
| | 505 | Buf *type_name = buf_create_from_str(decl_name(typedef_decl)); |
| | 506 | if (buf_eql_str(type_name, "uint8_t")) { |
| | 507 | return trans_create_node_symbol_str(c, "u8"); |
| | 508 | } else if (buf_eql_str(type_name, "int8_t")) { |
| | 509 | return trans_create_node_symbol_str(c, "i8"); |
| | 510 | } else if (buf_eql_str(type_name, "uint16_t")) { |
| | 511 | return trans_create_node_symbol_str(c, "u16"); |
| | 512 | } else if (buf_eql_str(type_name, "int16_t")) { |
| | 513 | return trans_create_node_symbol_str(c, "i16"); |
| | 514 | } else if (buf_eql_str(type_name, "uint32_t")) { |
| | 515 | return trans_create_node_symbol_str(c, "u32"); |
| | 516 | } else if (buf_eql_str(type_name, "int32_t")) { |
| | 517 | return trans_create_node_symbol_str(c, "i32"); |
| | 518 | } else if (buf_eql_str(type_name, "uint64_t")) { |
| | 519 | return trans_create_node_symbol_str(c, "u64"); |
| | 520 | } else if (buf_eql_str(type_name, "int64_t")) { |
| | 521 | return trans_create_node_symbol_str(c, "i64"); |
| | 522 | } else if (buf_eql_str(type_name, "intptr_t")) { |
| | 523 | return trans_create_node_symbol_str(c, "isize"); |
| | 524 | } else if (buf_eql_str(type_name, "uintptr_t")) { |
| | 525 | return trans_create_node_symbol_str(c, "usize"); |
| | 526 | } else { |
| | 527 | auto entry = type_table->maybe_get(type_name); |
| | 528 | if (entry == nullptr || entry->value == nullptr) { |
| | 529 | return nullptr; |
| | 530 | } else { |
| | 531 | return entry->value; |
| | 532 | } |
| | 533 | } |
| | 534 | } |
| 816 | case Type::Elaborated: | 535 | case Type::Elaborated: |
| 817 | zig_panic("TODO elaborated"); | 536 | { |
| | 537 | const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty); |
| | 538 | switch (elaborated_ty->getKeyword()) { |
| | 539 | case ETK_Struct: |
| | 540 | return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), |
| | 541 | source_loc, &c->struct_type_table); |
| | 542 | case ETK_Enum: |
| | 543 | return trans_qual_type_with_table(c, elaborated_ty->getNamedType(), |
| | 544 | source_loc, &c->enum_type_table); |
| | 545 | case ETK_Interface: |
| | 546 | case ETK_Union: |
| | 547 | case ETK_Class: |
| | 548 | case ETK_Typename: |
| | 549 | case ETK_None: |
| | 550 | emit_warning(c, source_loc, "unsupported elaborated type"); |
| | 551 | return nullptr; |
| | 552 | } |
| | 553 | } |
| 818 | case Type::FunctionProto: | 554 | case Type::FunctionProto: |
| 819 | zig_panic("TODO FunctionProto"); | 555 | { |
| | 556 | const FunctionProtoType *fn_proto_ty = static_cast<const FunctionProtoType*>(ty); |
| | 557 | |
| | 558 | AstNode *proto_node = trans_create_node(c, NodeTypeFnProto); |
| | 559 | switch (fn_proto_ty->getCallConv()) { |
| | 560 | case CC_C: // __attribute__((cdecl)) |
| | 561 | proto_node->data.fn_proto.cc = CallingConventionC; |
| | 562 | break; |
| | 563 | case CC_X86StdCall: // __attribute__((stdcall)) |
| | 564 | proto_node->data.fn_proto.cc = CallingConventionStdcall; |
| | 565 | break; |
| | 566 | case CC_X86FastCall: // __attribute__((fastcall)) |
| | 567 | emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall"); |
| | 568 | return nullptr; |
| | 569 | case CC_X86ThisCall: // __attribute__((thiscall)) |
| | 570 | emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall"); |
| | 571 | return nullptr; |
| | 572 | case CC_X86VectorCall: // __attribute__((vectorcall)) |
| | 573 | emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall"); |
| | 574 | return nullptr; |
| | 575 | case CC_X86Pascal: // __attribute__((pascal)) |
| | 576 | emit_warning(c, source_loc, "unsupported calling convention: x86 pascal"); |
| | 577 | return nullptr; |
| | 578 | case CC_Win64: // __attribute__((ms_abi)) |
| | 579 | emit_warning(c, source_loc, "unsupported calling convention: win64"); |
| | 580 | return nullptr; |
| | 581 | case CC_X86_64SysV: // __attribute__((sysv_abi)) |
| | 582 | emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv"); |
| | 583 | return nullptr; |
| | 584 | case CC_X86RegCall: |
| | 585 | emit_warning(c, source_loc, "unsupported calling convention: x86 reg"); |
| | 586 | return nullptr; |
| | 587 | case CC_AAPCS: // __attribute__((pcs("aapcs"))) |
| | 588 | emit_warning(c, source_loc, "unsupported calling convention: aapcs"); |
| | 589 | return nullptr; |
| | 590 | case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp"))) |
| | 591 | emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp"); |
| | 592 | return nullptr; |
| | 593 | case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc)) |
| | 594 | emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc"); |
| | 595 | return nullptr; |
| | 596 | case CC_SpirFunction: // default for OpenCL functions on SPIR target |
| | 597 | emit_warning(c, source_loc, "unsupported calling convention: SPIR function"); |
| | 598 | return nullptr; |
| | 599 | case CC_OpenCLKernel: |
| | 600 | emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel"); |
| | 601 | return nullptr; |
| | 602 | case CC_Swift: |
| | 603 | emit_warning(c, source_loc, "unsupported calling convention: Swift"); |
| | 604 | return nullptr; |
| | 605 | case CC_PreserveMost: |
| | 606 | emit_warning(c, source_loc, "unsupported calling convention: PreserveMost"); |
| | 607 | return nullptr; |
| | 608 | case CC_PreserveAll: |
| | 609 | emit_warning(c, source_loc, "unsupported calling convention: PreserveAll"); |
| | 610 | return nullptr; |
| | 611 | } |
| | 612 | |
| | 613 | proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic(); |
| | 614 | size_t param_count = fn_proto_ty->getNumParams(); |
| | 615 | |
| | 616 | if (fn_proto_ty->getNoReturnAttr()) { |
| | 617 | proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn"); |
| | 618 | } else { |
| | 619 | proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_proto_ty->getReturnType(), |
| | 620 | source_loc); |
| | 621 | if (proto_node->data.fn_proto.return_type == nullptr) { |
| | 622 | emit_warning(c, source_loc, "unsupported function proto return type"); |
| | 623 | return nullptr; |
| | 624 | } |
| | 625 | // convert c_void to actual void (only for return type) |
| | 626 | if (is_c_void_type(proto_node->data.fn_proto.return_type)) { |
| | 627 | proto_node->data.fn_proto.return_type = nullptr; |
| | 628 | } |
| | 629 | } |
| | 630 | |
| | 631 | //emit_warning(c, source_loc, "TODO figure out fn prototype fn name"); |
| | 632 | const char *fn_name = nullptr; |
| | 633 | if (fn_name != nullptr) { |
| | 634 | proto_node->data.fn_proto.name = buf_create_from_str(fn_name); |
| | 635 | } |
| | 636 | |
| | 637 | for (size_t i = 0; i < param_count; i += 1) { |
| | 638 | QualType qt = fn_proto_ty->getParamType(i); |
| | 639 | AstNode *param_type_node = trans_qual_type(c, qt, source_loc); |
| | 640 | |
| | 641 | if (param_type_node == nullptr) { |
| | 642 | emit_warning(c, source_loc, "unresolved function proto parameter type"); |
| | 643 | return nullptr; |
| | 644 | } |
| | 645 | |
| | 646 | AstNode *param_node = trans_create_node(c, NodeTypeParamDecl); |
| | 647 | //emit_warning(c, source_loc, "TODO figure out fn prototype param name"); |
| | 648 | const char *param_name = nullptr; |
| | 649 | if (param_name == nullptr) { |
| | 650 | param_node->data.param_decl.name = buf_sprintf("arg%" ZIG_PRI_usize "", i); |
| | 651 | } else { |
| | 652 | param_node->data.param_decl.name = buf_create_from_str(param_name); |
| | 653 | } |
| | 654 | param_node->data.param_decl.is_noalias = qt.isRestrictQualified(); |
| | 655 | param_node->data.param_decl.type = param_type_node; |
| | 656 | proto_node->data.fn_proto.params.append(param_node); |
| | 657 | } |
| | 658 | // TODO check for always_inline attribute |
| | 659 | // TODO check for align attribute |
| | 660 | |
| | 661 | return proto_node; |
| | 662 | } |
| 820 | case Type::Record: | 663 | case Type::Record: |
| 821 | zig_panic("TODO Record"); | 664 | { |
| | 665 | const RecordType *record_ty = static_cast<const RecordType*>(ty); |
| | 666 | return resolve_record_decl(c, record_ty->getDecl()); |
| | 667 | } |
| 822 | case Type::Enum: | 668 | case Type::Enum: |
| 823 | zig_panic("TODO Enum"); | 669 | { |
| | 670 | const EnumType *enum_ty = static_cast<const EnumType*>(ty); |
| | 671 | return resolve_enum_decl(c, enum_ty->getDecl()); |
| | 672 | } |
| 824 | case Type::ConstantArray: | 673 | case Type::ConstantArray: |
| 825 | zig_panic("TODO ConstantArray"); | 674 | { |
| | 675 | const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty); |
| | 676 | AstNode *child_type_node = trans_qual_type(c, const_arr_ty->getElementType(), source_loc); |
| | 677 | if (child_type_node == nullptr) { |
| | 678 | emit_warning(c, source_loc, "unresolved array element type"); |
| | 679 | return nullptr; |
| | 680 | } |
| | 681 | uint64_t size = const_arr_ty->getSize().getLimitedValue(); |
| | 682 | AstNode *size_node = trans_create_node_unsigned(c, size); |
| | 683 | return trans_create_node_array_type(c, size_node, child_type_node); |
| | 684 | } |
| 826 | case Type::Paren: | 685 | case Type::Paren: |
| 827 | zig_panic("TODO Paren"); | 686 | { |
| | 687 | const ParenType *paren_ty = static_cast<const ParenType *>(ty); |
| | 688 | return trans_qual_type(c, paren_ty->getInnerType(), source_loc); |
| | 689 | } |
| 828 | case Type::Decayed: | 690 | case Type::Decayed: |
| 829 | zig_panic("TODO Decayed"); | 691 | { |
| | 692 | const DecayedType *decayed_ty = static_cast<const DecayedType *>(ty); |
| | 693 | return trans_qual_type(c, decayed_ty->getDecayedType(), source_loc); |
| | 694 | } |
| 830 | case Type::Attributed: | 695 | case Type::Attributed: |
| 831 | zig_panic("TODO Attributed"); | 696 | { |
| | 697 | const AttributedType *attributed_ty = static_cast<const AttributedType *>(ty); |
| | 698 | return trans_qual_type(c, attributed_ty->getEquivalentType(), source_loc); |
| | 699 | } |
| 832 | case Type::BlockPointer: | 700 | case Type::BlockPointer: |
| 833 | case Type::LValueReference: | 701 | case Type::LValueReference: |
| 834 | case Type::RValueReference: | 702 | case Type::RValueReference: |
| ... | @@ -863,7 +731,8 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo | ... | @@ -863,7 +731,8 @@ static AstNode *trans_type_with_table(Context *c, const Type *ty, const SourceLo |
| 863 | case Type::Pipe: | 731 | case Type::Pipe: |
| 864 | case Type::ObjCTypeParam: | 732 | case Type::ObjCTypeParam: |
| 865 | case Type::DeducedTemplateSpecialization: | 733 | case Type::DeducedTemplateSpecialization: |
| 866 | zig_panic("TODO more c type aoeu"); | 734 | emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName()); |
| | 735 | return nullptr; |
| 867 | } | 736 | } |
| 868 | zig_unreachable(); | 737 | zig_unreachable(); |
| 869 | } | 738 | } |
| ... | @@ -875,15 +744,7 @@ static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const Sourc | ... | @@ -875,15 +744,7 @@ static AstNode * trans_qual_type_with_table(Context *c, QualType qt, const Sourc |
| 875 | } | 744 | } |
| 876 | | 745 | |
| 877 | static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc) { | 746 | static AstNode * trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc) { |
| 878 | return trans_qual_type_with_table(c, qt, source_loc, &c->global_type_table2); | 747 | return trans_qual_type_with_table(c, qt, source_loc, &c->global_type_table); |
| 879 | } | | |
| 880 | | | |
| 881 | static AstNode * trans_create_node(Context *c, NodeType id) { | | |
| 882 | AstNode *node = allocate<AstNode>(1); | | |
| 883 | node->type = id; | | |
| 884 | node->owner = c->import; | | |
| 885 | // TODO line/column. mapping to C file?? | | |
| 886 | return node; | | |
| 887 | } | 748 | } |
| 888 | | 749 | |
| 889 | static AstNode * trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) { | 750 | static AstNode * trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) { |
| ... | @@ -907,35 +768,15 @@ static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt) | ... | @@ -907,35 +768,15 @@ static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt) |
| 907 | } | 768 | } |
| 908 | } | 769 | } |
| 909 | | 770 | |
| 910 | static void aps_int_to_bigint(Context *c, const llvm::APSInt &aps_int, BigInt *bigint) { | 771 | static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) { |
| 911 | // TODO respect actually big integers | | |
| 912 | if (aps_int.isSigned()) { | | |
| 913 | if (aps_int > INT64_MAX || aps_int < INT64_MIN) { | | |
| 914 | zig_panic("TODO actually bigint in C"); | | |
| 915 | } else { | | |
| 916 | bigint_init_signed(bigint, aps_int.getExtValue()); | | |
| 917 | } | | |
| 918 | } else { | | |
| 919 | if (aps_int > INT64_MAX) { | | |
| 920 | zig_panic("TODO actually bigint in C"); | | |
| 921 | } else { | | |
| 922 | bigint_init_unsigned(bigint, aps_int.getExtValue()); | | |
| 923 | } | | |
| 924 | } | | |
| 925 | } | | |
| 926 | | | |
| 927 | static AstNode * trans_integer_literal(Context *c, IntegerLiteral *stmt) { | | |
| 928 | AstNode *node = trans_create_node(c, NodeTypeIntLiteral); | | |
| 929 | llvm::APSInt result; | 772 | llvm::APSInt result; |
| 930 | if (!stmt->EvaluateAsInt(result, *c->ctx)) { | 773 | if (!stmt->EvaluateAsInt(result, *c->ctx)) { |
| 931 | fprintf(stderr, "TODO unable to convert integer literal to zig\n"); | 774 | zig_panic("TODO handle libclang unable to evaluate C integer literal"); |
| 932 | } | 775 | } |
| 933 | node->data.int_literal.bigint = allocate<BigInt>(1); | 776 | return trans_create_node_apint(c, result); |
| 934 | aps_int_to_bigint(c, result, node->data.int_literal.bigint); | | |
| 935 | return node; | | |
| 936 | } | 777 | } |
| 937 | | 778 | |
| 938 | static AstNode * trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) { | 779 | static AstNode *trans_conditional_operator(Context *c, AstNode *block, ConditionalOperator *stmt) { |
| 939 | AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr); | 780 | AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr); |
| 940 | | 781 | |
| 941 | Expr *cond_expr = stmt->getCond(); | 782 | Expr *cond_expr = stmt->getCond(); |
| ... | @@ -1034,9 +875,7 @@ static AstNode * trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCa | ... | @@ -1034,9 +875,7 @@ static AstNode * trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCa |
| 1034 | return trans_expr(c, block, stmt->getSubExpr()); | 875 | return trans_expr(c, block, stmt->getSubExpr()); |
| 1035 | case CK_IntegralCast: | 876 | case CK_IntegralCast: |
| 1036 | { | 877 | { |
| 1037 | AstNode *node = trans_create_node(c, NodeTypeFnCallExpr); | 878 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "bitCast"); |
| 1038 | node->data.fn_call_expr.fn_ref_expr = trans_create_symbol_node(c, "bitCast"); | | |
| 1039 | node->data.fn_call_expr.is_builtin = true; | | |
| 1040 | node->data.fn_call_expr.params.append(trans_qual_type(c, stmt->getType(), stmt->getExprLoc())); | 879 | node->data.fn_call_expr.params.append(trans_qual_type(c, stmt->getType(), stmt->getExprLoc())); |
| 1041 | node->data.fn_call_expr.params.append(trans_expr(c, block, stmt->getSubExpr())); | 880 | node->data.fn_call_expr.params.append(trans_expr(c, block, stmt->getSubExpr())); |
| 1042 | return node; | 881 | return node; |
| ... | @@ -1166,13 +1005,6 @@ static AstNode * trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) { | ... | @@ -1166,13 +1005,6 @@ static AstNode * trans_decl_ref_expr(Context *c, DeclRefExpr *stmt) { |
| 1166 | return node; | 1005 | return node; |
| 1167 | } | 1006 | } |
| 1168 | | 1007 | |
| 1169 | static AstNode * trans_create_num_lit_node_unsigned(Context *c, Stmt *stmt, uint64_t x) { | | |
| 1170 | AstNode *node = trans_create_node(c, NodeTypeIntLiteral); | | |
| 1171 | node->data.int_literal.bigint = allocate<BigInt>(1); | | |
| 1172 | bigint_init_unsigned(node->data.int_literal.bigint, x); | | |
| 1173 | return node; | | |
| 1174 | } | | |
| 1175 | | | |
| 1176 | static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) { | 1008 | static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) { |
| 1177 | switch (stmt->getOpcode()) { | 1009 | switch (stmt->getOpcode()) { |
| 1178 | case UO_PostInc: | 1010 | case UO_PostInc: |
| ... | @@ -1200,7 +1032,7 @@ static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator | ... | @@ -1200,7 +1032,7 @@ static AstNode * trans_unary_operator(Context *c, AstNode *block, UnaryOperator |
| 1200 | } else if (c_is_unsigned_integer(c, op_expr->getType())) { | 1032 | } else if (c_is_unsigned_integer(c, op_expr->getType())) { |
| 1201 | // we gotta emit 0 -% x | 1033 | // we gotta emit 0 -% x |
| 1202 | AstNode *node = trans_create_node(c, NodeTypeBinOpExpr); | 1034 | AstNode *node = trans_create_node(c, NodeTypeBinOpExpr); |
| 1203 | node->data.bin_op_expr.op1 = trans_create_num_lit_node_unsigned(c, stmt, 0); | 1035 | node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0); |
| 1204 | node->data.bin_op_expr.op2 = trans_expr(c, block, op_expr); | 1036 | node->data.bin_op_expr.op2 = trans_expr(c, block, op_expr); |
| 1205 | node->data.bin_op_expr.bin_op = BinOpTypeSubWrap; | 1037 | node->data.bin_op_expr.bin_op = BinOpTypeSubWrap; |
| 1206 | return node; | 1038 | return node; |
| ... | @@ -1230,19 +1062,14 @@ static AstNode * trans_local_declaration(Context *c, AstNode *block, DeclStmt *s | ... | @@ -1230,19 +1062,14 @@ static AstNode * trans_local_declaration(Context *c, AstNode *block, DeclStmt *s |
| 1230 | switch (decl->getKind()) { | 1062 | switch (decl->getKind()) { |
| 1231 | case Decl::Var: { | 1063 | case Decl::Var: { |
| 1232 | VarDecl *var_decl = (VarDecl *)decl; | 1064 | VarDecl *var_decl = (VarDecl *)decl; |
| 1233 | AstNode *node = trans_create_node(c, NodeTypeVariableDeclaration); | | |
| 1234 | node->data.variable_declaration.symbol = buf_create_from_str(decl_name(var_decl)); | | |
| 1235 | QualType qual_type = var_decl->getTypeSourceInfo()->getType(); | 1065 | QualType qual_type = var_decl->getTypeSourceInfo()->getType(); |
| 1236 | node->data.variable_declaration.is_const = qual_type.isConstQualified(); | 1066 | AstNode *init_node = var_decl->hasInit() ? trans_expr(c, block, var_decl->getInit()) : nullptr; |
| 1237 | node->data.variable_declaration.type = trans_qual_type(c, qual_type, stmt->getStartLoc()); | 1067 | AstNode *type_node = trans_qual_type(c, qual_type, stmt->getStartLoc()); |
| 1238 | if (var_decl->hasInit()) { | 1068 | AstNode *node = trans_create_node_var_decl(c, qual_type.isConstQualified(), |
| 1239 | node->data.variable_declaration.expr = trans_expr(c, block, var_decl->getInit()); | 1069 | buf_create_from_str(decl_name(var_decl)), type_node, init_node); |
| 1240 | } | | |
| 1241 | | | |
| 1242 | block->data.block.statements.append(node); | 1070 | block->data.block.statements.append(node); |
| 1243 | continue; | 1071 | continue; |
| 1244 | } | 1072 | } |
| 1245 | | | |
| 1246 | case Decl::AccessSpec: | 1073 | case Decl::AccessSpec: |
| 1247 | zig_panic("TODO handle decl kind AccessSpec"); | 1074 | zig_panic("TODO handle decl kind AccessSpec"); |
| 1248 | case Decl::Block: | 1075 | case Decl::Block: |
| ... | @@ -1802,53 +1629,57 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) { | ... | @@ -1802,53 +1629,57 @@ static AstNode *trans_stmt(Context *c, AstNode *block, Stmt *stmt) { |
| 1802 | static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { | 1629 | static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 1803 | Buf *fn_name = buf_create_from_str(decl_name(fn_decl)); | 1630 | Buf *fn_name = buf_create_from_str(decl_name(fn_decl)); |
| 1804 | | 1631 | |
| 1805 | if (fn_decl->hasBody()) { | | |
| 1806 | fprintf(stderr, "fn %s\n", buf_ptr(fn_name)); | | |
| 1807 | Stmt *body = fn_decl->getBody(); | | |
| 1808 | AstNode *body_node = trans_stmt(c, nullptr, body); | | |
| 1809 | ast_render(c->codegen, stderr, body_node, 4); | | |
| 1810 | fprintf(stderr, "\n"); | | |
| 1811 | } | | |
| 1812 | | | |
| 1813 | if (get_global(c, fn_name)) { | 1632 | if (get_global(c, fn_name)) { |
| 1814 | // we already saw this function | 1633 | // we already saw this function |
| 1815 | return; | 1634 | return; |
| 1816 | } | 1635 | } |
| 1817 | | 1636 | |
| 1818 | TypeTableEntry *fn_type = resolve_qual_type(c, fn_decl->getType(), fn_decl); | 1637 | AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), fn_decl->getLocation()); |
| 1819 | | 1638 | if (proto_node == nullptr) { |
| 1820 | if (fn_type->id == TypeTableEntryIdInvalid) { | 1639 | emit_warning(c, fn_decl->getLocation(), "unable to resolve prototype of function '%s'", buf_ptr(fn_name)); |
| 1821 | emit_warning(c, fn_decl->getLocation(), "ignoring function '%s' - unable to resolve type", buf_ptr(fn_name)); | | |
| 1822 | return; | 1640 | return; |
| 1823 | } | 1641 | } |
| 1824 | assert(fn_type->id == TypeTableEntryIdFn); | | |
| 1825 | | 1642 | |
| 1826 | FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong); | 1643 | proto_node->data.fn_proto.name = fn_name; |
| 1827 | buf_init_from_buf(&fn_entry->symbol_name, fn_name); | 1644 | proto_node->data.fn_proto.is_extern = !fn_decl->hasBody(); |
| 1828 | fn_entry->type_entry = fn_type; | | |
| 1829 | | 1645 | |
| 1830 | assert(fn_type->data.fn.fn_type_id.cc != CallingConventionNaked); | 1646 | StorageClass sc = fn_decl->getStorageClass(); |
| | 1647 | if (sc == SC_None) { |
| | 1648 | proto_node->data.fn_proto.visib_mod = fn_decl->hasBody() ? VisibModExport : c->visib_mod; |
| | 1649 | } else if (sc == SC_Extern || sc == SC_Static) { |
| | 1650 | proto_node->data.fn_proto.visib_mod = c->visib_mod; |
| | 1651 | } else if (sc == SC_PrivateExtern) { |
| | 1652 | emit_warning(c, fn_decl->getLocation(), "unsupported storage class: private extern"); |
| | 1653 | return; |
| | 1654 | } else { |
| | 1655 | emit_warning(c, fn_decl->getLocation(), "unsupported storage class: unknown"); |
| | 1656 | return; |
| | 1657 | } |
| 1831 | | 1658 | |
| 1832 | size_t arg_count = fn_type->data.fn.fn_type_id.param_count; | 1659 | const FunctionProtoType *fn_proto_ty = (const FunctionProtoType *) fn_decl->getType().getTypePtr(); |
| 1833 | fn_entry->param_names = allocate<Buf *>(arg_count); | 1660 | size_t arg_count = fn_proto_ty->getNumParams(); |
| 1834 | Buf *name_buf; | | |
| 1835 | for (size_t i = 0; i < arg_count; i += 1) { | 1661 | for (size_t i = 0; i < arg_count; i += 1) { |
| | 1662 | AstNode *param_node = proto_node->data.fn_proto.params.at(i); |
| 1836 | const ParmVarDecl *param = fn_decl->getParamDecl(i); | 1663 | const ParmVarDecl *param = fn_decl->getParamDecl(i); |
| 1837 | const char *name = decl_name(param); | 1664 | const char *name = decl_name(param); |
| 1838 | if (strlen(name) == 0) { | 1665 | if (strlen(name) != 0) { |
| 1839 | name_buf = buf_sprintf("arg%" ZIG_PRI_usize "", i); | 1666 | param_node->data.param_decl.name = buf_create_from_str(name); |
| 1840 | } else { | | |
| 1841 | name_buf = buf_create_from_str(name); | | |
| 1842 | } | 1667 | } |
| 1843 | fn_entry->param_names[i] = name_buf; | | |
| 1844 | } | 1668 | } |
| 1845 | | 1669 | |
| 1846 | TldFn *tld_fn = allocate<TldFn>(1); | 1670 | if (fn_decl->hasBody()) { |
| 1847 | parseh_init_tld(c, &tld_fn->base, TldIdFn, fn_name); | 1671 | Stmt *body = fn_decl->getBody(); |
| 1848 | tld_fn->fn_entry = fn_entry; | 1672 | |
| 1849 | add_global(c, &tld_fn->base); | 1673 | AstNode *fn_def_node = trans_create_node(c, NodeTypeFnDef); |
| | 1674 | fn_def_node->data.fn_def.fn_proto = proto_node; |
| | 1675 | fn_def_node->data.fn_def.body = trans_stmt(c, nullptr, body); |
| 1850 | | 1676 | |
| 1851 | c->codegen->fn_protos.append(fn_entry); | 1677 | proto_node->data.fn_proto.fn_def_node = fn_def_node; |
| | 1678 | c->root->data.root.top_level_decls.append(fn_def_node); |
| | 1679 | return; |
| | 1680 | } |
| | 1681 | |
| | 1682 | c->root->data.root.top_level_decls.append(proto_node); |
| 1852 | } | 1683 | } |
| 1853 | | 1684 | |
| 1854 | static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) { | 1685 | static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) { |
| ... | @@ -1874,53 +1705,36 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) | ... | @@ -1874,53 +1705,36 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) |
| 1874 | // use the name of this typedef | 1705 | // use the name of this typedef |
| 1875 | // TODO | 1706 | // TODO |
| 1876 | | 1707 | |
| 1877 | TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl); | 1708 | AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation()); |
| 1878 | if (child_type->id == TypeTableEntryIdInvalid) { | 1709 | if (type_node == nullptr) { |
| 1879 | emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name)); | 1710 | emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name)); |
| 1880 | return; | 1711 | return; |
| 1881 | } | 1712 | } |
| 1882 | add_const_type(c, type_name, child_type); | 1713 | add_global_var(c, type_name, type_node); |
| 1883 | } | 1714 | c->global_type_table.put(type_name, type_node); |
| 1884 | | | |
| 1885 | static void replace_with_fwd_decl(Context *c, TypeTableEntry *struct_type, Buf *full_type_name) { | | |
| 1886 | unsigned line = c->source_node ? c->source_node->line : 0; | | |
| 1887 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugForwardDeclType(c->codegen->dbuilder, | | |
| 1888 | ZigLLVMTag_DW_structure_type(), buf_ptr(full_type_name), | | |
| 1889 | ZigLLVMFileToScope(c->import->di_file), c->import->di_file, line); | | |
| 1890 | | | |
| 1891 | ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type); | | |
| 1892 | struct_type->di_type = replacement_di_type; | | |
| 1893 | struct_type->id = TypeTableEntryIdOpaque; | | |
| 1894 | } | 1715 | } |
| 1895 | | 1716 | |
| 1896 | static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { | 1717 | static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| 1897 | auto existing_entry = c->decl_table.maybe_get((void*)enum_decl); | 1718 | auto existing_entry = c->decl_table.maybe_get((void*)enum_decl); |
| 1898 | if (existing_entry) { | 1719 | if (existing_entry) { |
| 1899 | return existing_entry->value; | 1720 | return existing_entry->value; |
| 1900 | } | 1721 | } |
| 1901 | | 1722 | |
| 1902 | const char *raw_name = decl_name(enum_decl); | 1723 | const char *raw_name = decl_name(enum_decl); |
| 1903 | | 1724 | bool is_anonymous = (raw_name[0] == 0); |
| 1904 | Buf *bare_name; | 1725 | Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name); |
| 1905 | if (raw_name[0] == 0) { | 1726 | Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name)); |
| 1906 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_anon_index(c)); | | |
| 1907 | } else { | | |
| 1908 | bare_name = buf_create_from_str(raw_name); | | |
| 1909 | } | | |
| 1910 | | | |
| 1911 | Buf *full_type_name = buf_sprintf("enum_%s", buf_ptr(bare_name)); | | |
| 1912 | | 1727 | |
| 1913 | const EnumDecl *enum_def = enum_decl->getDefinition(); | 1728 | const EnumDecl *enum_def = enum_decl->getDefinition(); |
| 1914 | if (!enum_def) { | 1729 | if (!enum_def) { |
| 1915 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, | 1730 | AstNode *opaque_node = trans_create_node_opaque(c); |
| 1916 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern); | 1731 | if (!is_anonymous) { |
| 1917 | enum_type->data.enumeration.zero_bits_known = true; | 1732 | c->enum_type_table.put(bare_name, opaque_node); |
| 1918 | enum_type->data.enumeration.abi_alignment = 1; | 1733 | add_global_weak_alias(c, bare_name, opaque_node); |
| 1919 | c->enum_type_table.put(bare_name, enum_type); | 1734 | add_global_var(c, full_type_name, opaque_node); |
| 1920 | c->decl_table.put(enum_decl, enum_type); | 1735 | } |
| 1921 | replace_with_fwd_decl(c, enum_type, full_type_name); | 1736 | c->decl_table.put(enum_decl, opaque_node); |
| 1922 | | 1737 | return opaque_node; |
| 1923 | return enum_type; | | |
| 1924 | } | 1738 | } |
| 1925 | | 1739 | |
| 1926 | bool pure_enum = true; | 1740 | bool pure_enum = true; |
| ... | @@ -1935,25 +1749,16 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) | ... | @@ -1935,25 +1749,16 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 1935 | } | 1749 | } |
| 1936 | } | 1750 | } |
| 1937 | | 1751 | |
| 1938 | TypeTableEntry *tag_int_type = resolve_qual_type(c, enum_decl->getIntegerType(), enum_decl); | 1752 | AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation()); |
| | 1753 | assert(tag_int_type); |
| 1939 | | 1754 | |
| 1940 | if (pure_enum) { | 1755 | if (pure_enum) { |
| 1941 | TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, | 1756 | AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl); |
| 1942 | ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern); | 1757 | enum_node->data.container_decl.kind = ContainerKindEnum; |
| 1943 | TypeTableEntry *tag_type_entry = create_enum_tag_type(c->codegen, enum_type, tag_int_type); | 1758 | enum_node->data.container_decl.layout = ContainerLayoutExtern; |
| 1944 | c->enum_type_table.put(bare_name, enum_type); | 1759 | enum_node->data.container_decl.init_arg_expr = tag_int_type; |
| 1945 | c->decl_table.put(enum_decl, enum_type); | | |
| 1946 | | | |
| 1947 | enum_type->data.enumeration.gen_field_count = 0; | | |
| 1948 | enum_type->data.enumeration.complete = true; | | |
| 1949 | enum_type->data.enumeration.zero_bits_known = true; | | |
| 1950 | enum_type->data.enumeration.abi_alignment = 1; | | |
| 1951 | enum_type->data.enumeration.tag_type = tag_type_entry; | | |
| 1952 | | | |
| 1953 | enum_type->data.enumeration.src_field_count = field_count; | | |
| 1954 | enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); | | |
| 1955 | ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); | | |
| 1956 | | 1760 | |
| | 1761 | enum_node->data.container_decl.fields.resize(field_count); |
| 1957 | uint32_t i = 0; | 1762 | uint32_t i = 0; |
| 1958 | for (auto it = enum_def->enumerator_begin(), | 1763 | for (auto it = enum_def->enumerator_begin(), |
| 1959 | it_end = enum_def->enumerator_end(); | 1764 | it_end = enum_def->enumerator_end(); |
| ... | @@ -1963,92 +1768,63 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) | ... | @@ -1963,92 +1768,63 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) |
| 1963 | | 1768 | |
| 1964 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); | 1769 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| 1965 | Buf *field_name; | 1770 | Buf *field_name; |
| 1966 | if (buf_starts_with_buf(enum_val_name, bare_name)) { | 1771 | if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) { |
| 1967 | field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); | 1772 | field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name)); |
| 1968 | } else { | 1773 | } else { |
| 1969 | field_name = enum_val_name; | 1774 | field_name = enum_val_name; |
| 1970 | } | 1775 | } |
| 1971 | | 1776 | |
| 1972 | TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; | 1777 | AstNode *field_node = trans_create_node(c, NodeTypeStructField); |
| 1973 | type_enum_field->name = field_name; | 1778 | field_node->data.struct_field.name = field_name; |
| 1974 | type_enum_field->type_entry = c->codegen->builtin_types.entry_void; | 1779 | field_node->data.struct_field.type = nullptr; |
| 1975 | type_enum_field->value = i; | 1780 | enum_node->data.container_decl.fields.items[i] = field_node; |
| 1976 | | | |
| 1977 | di_enumerators[i] = ZigLLVMCreateDebugEnumerator(c->codegen->dbuilder, buf_ptr(type_enum_field->name), i); | | |
| 1978 | | | |
| 1979 | | 1781 | |
| 1980 | // in C each enum value is in the global namespace. so we put them there too. | 1782 | // in C each enum value is in the global namespace. so we put them there too. |
| 1981 | // at this point we can rely on the enum emitting successfully | 1783 | // at this point we can rely on the enum emitting successfully |
| 1982 | add_global(c, create_global_num_lit_unsigned_negative(c, enum_val_name, i, false)); | 1784 | AstNode *field_access_node = trans_create_node_field_access(c, |
| | 1785 | trans_create_node_symbol(c, full_type_name), field_name); |
| | 1786 | add_global_var(c, enum_val_name, field_access_node); |
| 1983 | } | 1787 | } |
| 1984 | | 1788 | |
| 1985 | // create llvm type for root struct | 1789 | if (!is_anonymous) { |
| 1986 | enum_type->type_ref = tag_type_entry->type_ref; | 1790 | c->enum_type_table.put(bare_name, enum_node); |
| 1987 | | 1791 | add_global_weak_alias(c, bare_name, enum_node); |
| 1988 | enum_type->data.enumeration.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref, | 1792 | add_global_var(c, full_type_name, enum_node); |
| 1989 | enum_type->type_ref); | | |
| 1990 | | | |
| 1991 | // create debug type for tag | | |
| 1992 | unsigned line = c->source_node ? (c->source_node->line + 1) : 0; | | |
| 1993 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, enum_type->type_ref); | | |
| 1994 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, enum_type->type_ref); | | |
| 1995 | ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(c->codegen->dbuilder, | | |
| 1996 | ZigLLVMFileToScope(c->import->di_file), buf_ptr(bare_name), | | |
| 1997 | c->import->di_file, line, | | |
| 1998 | debug_size_in_bits, | | |
| 1999 | debug_align_in_bits, | | |
| 2000 | di_enumerators, field_count, tag_type_entry->di_type, ""); | | |
| 2001 | | | |
| 2002 | ZigLLVMReplaceTemporary(c->codegen->dbuilder, enum_type->di_type, tag_di_type); | | |
| 2003 | enum_type->di_type = tag_di_type; | | |
| 2004 | | | |
| 2005 | return enum_type; | | |
| 2006 | } else { | | |
| 2007 | // TODO after issue #305 is solved, make this be an enum with tag_int_type | | |
| 2008 | // as the integer type and set the custom enum values | | |
| 2009 | TypeTableEntry *enum_type = tag_int_type; | | |
| 2010 | c->enum_type_table.put(bare_name, enum_type); | | |
| 2011 | c->decl_table.put(enum_decl, enum_type); | | |
| 2012 | | | |
| 2013 | // add variables for all the values with enum_type | | |
| 2014 | for (auto it = enum_def->enumerator_begin(), | | |
| 2015 | it_end = enum_def->enumerator_end(); | | |
| 2016 | it != it_end; ++it) | | |
| 2017 | { | | |
| 2018 | const EnumConstantDecl *enum_const = *it; | | |
| 2019 | | | |
| 2020 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); | | |
| 2021 | | | |
| 2022 | Tld *tld = create_global_num_lit_ap(c, enum_decl, enum_val_name, enum_const->getInitVal()); | | |
| 2023 | if (!tld) | | |
| 2024 | return c->codegen->builtin_types.entry_invalid; | | |
| 2025 | | | |
| 2026 | add_global(c, tld); | | |
| 2027 | } | 1793 | } |
| | 1794 | c->decl_table.put(enum_decl, enum_node); |
| 2028 | | 1795 | |
| 2029 | return enum_type; | 1796 | return enum_node; |
| 2030 | } | 1797 | } |
| 2031 | } | | |
| 2032 | | 1798 | |
| 2033 | static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { | 1799 | // TODO after issue #305 is solved, make this be an enum with tag_int_type |
| 2034 | TypeTableEntry *enum_type = resolve_enum_decl(c, enum_decl); | 1800 | // as the integer type and set the custom enum values |
| | 1801 | AstNode *enum_node = tag_int_type; |
| 2035 | | 1802 | |
| 2036 | if (enum_type->id == TypeTableEntryIdInvalid) | | |
| 2037 | return; | | |
| 2038 | | 1803 | |
| 2039 | // make an alias without the "enum_" prefix. this will get emitted at the | 1804 | // add variables for all the values with enum_node |
| 2040 | // end if it doesn't conflict with anything else | 1805 | for (auto it = enum_def->enumerator_begin(), |
| 2041 | bool is_anonymous = (decl_name(enum_decl)[0] == 0); | 1806 | it_end = enum_def->enumerator_end(); |
| 2042 | if (is_anonymous) | 1807 | it != it_end; ++it) |
| 2043 | return; | 1808 | { |
| | 1809 | const EnumConstantDecl *enum_const = *it; |
| | 1810 | |
| | 1811 | Buf *enum_val_name = buf_create_from_str(decl_name(enum_const)); |
| | 1812 | AstNode *int_node = trans_create_node_apint(c, enum_const->getInitVal()); |
| | 1813 | AstNode *var_node = add_global_var(c, enum_val_name, int_node); |
| | 1814 | var_node->data.variable_declaration.type = tag_int_type; |
| | 1815 | } |
| 2044 | | 1816 | |
| 2045 | Buf *bare_name = buf_create_from_str(decl_name(enum_decl)); | 1817 | if (!is_anonymous) { |
| | 1818 | c->enum_type_table.put(bare_name, enum_node); |
| | 1819 | add_global_weak_alias(c, bare_name, enum_node); |
| | 1820 | add_global_var(c, full_type_name, enum_node); |
| | 1821 | } |
| | 1822 | c->decl_table.put(enum_decl, enum_node); |
| 2046 | | 1823 | |
| 2047 | Tld *tld = add_container_tld(c, enum_type); | 1824 | return enum_node; |
| 2048 | add_global_weak_alias(c, bare_name, tld); | | |
| 2049 | } | 1825 | } |
| 2050 | | 1826 | |
| 2051 | static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl) { | 1827 | static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) { |
| 2052 | auto existing_entry = c->decl_table.maybe_get((void*)record_decl); | 1828 | auto existing_entry = c->decl_table.maybe_get((void*)record_decl); |
| 2053 | if (existing_entry) { | 1829 | if (existing_entry) { |
| 2054 | return existing_entry->value; | 1830 | return existing_entry->value; |
| ... | @@ -2058,35 +1834,26 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ | ... | @@ -2058,35 +1834,26 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 2058 | | 1834 | |
| 2059 | if (!record_decl->isStruct()) { | 1835 | if (!record_decl->isStruct()) { |
| 2060 | emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name); | 1836 | emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct", raw_name); |
| 2061 | return c->codegen->builtin_types.entry_invalid; | 1837 | c->decl_table.put(record_decl, nullptr); |
| 2062 | } | 1838 | return nullptr; |
| 2063 | | | |
| 2064 | Buf *bare_name; | | |
| 2065 | if (record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0) { | | |
| 2066 | bare_name = buf_sprintf("anon_$%" PRIu32, get_next_anon_index(c)); | | |
| 2067 | } else { | | |
| 2068 | bare_name = buf_create_from_str(raw_name); | | |
| 2069 | } | 1839 | } |
| 2070 | | 1840 | |
| 2071 | Buf *full_type_name = buf_sprintf("struct_%s", buf_ptr(bare_name)); | 1841 | bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0; |
| 2072 | | 1842 | Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name); |
| 2073 | | 1843 | Buf *full_type_name = (bare_name == nullptr) ? nullptr : buf_sprintf("struct_%s", buf_ptr(bare_name)); |
| 2074 | TypeTableEntry *struct_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base, | | |
| 2075 | ContainerKindStruct, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern); | | |
| 2076 | struct_type->data.structure.zero_bits_known = true; | | |
| 2077 | struct_type->data.structure.abi_alignment = 1; | | |
| 2078 | | | |
| 2079 | c->struct_type_table.put(bare_name, struct_type); | | |
| 2080 | c->decl_table.put(record_decl, struct_type); | | |
| 2081 | | 1844 | |
| 2082 | RecordDecl *record_def = record_decl->getDefinition(); | 1845 | RecordDecl *record_def = record_decl->getDefinition(); |
| 2083 | unsigned line = c->source_node ? c->source_node->line : 0; | 1846 | if (record_def == nullptr) { |
| 2084 | if (!record_def) { | 1847 | AstNode *opaque_node = trans_create_node_opaque(c); |
| 2085 | replace_with_fwd_decl(c, struct_type, full_type_name); | 1848 | if (!is_anonymous) { |
| 2086 | return struct_type; | 1849 | c->struct_type_table.put(bare_name, opaque_node); |
| | 1850 | add_global_weak_alias(c, bare_name, opaque_node); |
| | 1851 | add_global_var(c, full_type_name, opaque_node); |
| | 1852 | } |
| | 1853 | c->decl_table.put(record_decl, opaque_node); |
| | 1854 | return opaque_node; |
| 2087 | } | 1855 | } |
| 2088 | | 1856 | |
| 2089 | | | |
| 2090 | // count fields and validate | 1857 | // count fields and validate |
| 2091 | uint32_t field_count = 0; | 1858 | uint32_t field_count = 0; |
| 2092 | for (auto it = record_def->field_begin(), | 1859 | for (auto it = record_def->field_begin(), |
| ... | @@ -2096,105 +1863,69 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ | ... | @@ -2096,105 +1863,69 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ |
| 2096 | const FieldDecl *field_decl = *it; | 1863 | const FieldDecl *field_decl = *it; |
| 2097 | | 1864 | |
| 2098 | if (field_decl->isBitField()) { | 1865 | if (field_decl->isBitField()) { |
| 2099 | emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield\n", buf_ptr(bare_name)); | 1866 | emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - has bitfield", |
| 2100 | replace_with_fwd_decl(c, struct_type, full_type_name); | 1867 | is_anonymous ? "(anon)" : buf_ptr(bare_name)); |
| 2101 | return struct_type; | 1868 | |
| | 1869 | AstNode *opaque_node = trans_create_node_opaque(c); |
| | 1870 | |
| | 1871 | if (!is_anonymous) { |
| | 1872 | c->struct_type_table.put(bare_name, opaque_node); |
| | 1873 | add_global_weak_alias(c, bare_name, opaque_node); |
| | 1874 | add_global_var(c, full_type_name, opaque_node); |
| | 1875 | } |
| | 1876 | c->decl_table.put(record_decl, opaque_node); |
| | 1877 | return opaque_node;; |
| 2102 | } | 1878 | } |
| 2103 | } | 1879 | } |
| 2104 | | 1880 | |
| 2105 | struct_type->data.structure.src_field_count = field_count; | 1881 | AstNode *struct_node = trans_create_node(c, NodeTypeContainerDecl); |
| 2106 | struct_type->data.structure.fields = allocate<TypeStructField>(field_count); | 1882 | struct_node->data.container_decl.kind = ContainerKindStruct; |
| 2107 | LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count); | 1883 | struct_node->data.container_decl.layout = ContainerLayoutExtern; |
| 2108 | ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count); | | |
| 2109 | | 1884 | |
| 2110 | // next, populate element_types as its needed for LLVMStructSetBody which is needed for LLVMOffsetOfElement | 1885 | // TODO handle attribute packed |
| 2111 | uint32_t i = 0; | | |
| 2112 | for (auto it = record_def->field_begin(), | | |
| 2113 | it_end = record_def->field_end(); | | |
| 2114 | it != it_end; ++it, i += 1) | | |
| 2115 | { | | |
| 2116 | const FieldDecl *field_decl = *it; | | |
| 2117 | | 1886 | |
| 2118 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; | 1887 | struct_node->data.container_decl.fields.resize(field_count); |
| 2119 | type_struct_field->name = buf_create_from_str(decl_name(field_decl)); | | |
| 2120 | type_struct_field->src_index = i; | | |
| 2121 | type_struct_field->gen_index = i; | | |
| 2122 | TypeTableEntry *field_type = resolve_qual_type(c, field_decl->getType(), field_decl); | | |
| 2123 | type_struct_field->type_entry = field_type; | | |
| 2124 | | | |
| 2125 | if (type_is_invalid(field_type) || !type_is_complete(field_type)) { | | |
| 2126 | emit_warning(c, field_decl->getLocation(), "struct %s demoted to opaque type - unresolved type\n", buf_ptr(bare_name)); | | |
| 2127 | replace_with_fwd_decl(c, struct_type, full_type_name); | | |
| 2128 | return struct_type; | | |
| 2129 | } | | |
| 2130 | | 1888 | |
| 2131 | element_types[i] = field_type->type_ref; | 1889 | // must be before fields in case a circular reference happens |
| 2132 | assert(element_types[i]); | 1890 | if (!is_anonymous) { |
| | 1891 | c->struct_type_table.put(bare_name, struct_node); |
| | 1892 | add_global_weak_alias(c, bare_name, struct_node); |
| | 1893 | add_global_var(c, full_type_name, struct_node); |
| 2133 | } | 1894 | } |
| | 1895 | c->decl_table.put(record_decl, struct_node); |
| 2134 | | 1896 | |
| 2135 | LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false); | 1897 | uint32_t i = 0; |
| 2136 | | | |
| 2137 | // finally populate debug info | | |
| 2138 | i = 0; | | |
| 2139 | for (auto it = record_def->field_begin(), | 1898 | for (auto it = record_def->field_begin(), |
| 2140 | it_end = record_def->field_end(); | 1899 | it_end = record_def->field_end(); |
| 2141 | it != it_end; ++it, i += 1) | 1900 | it != it_end; ++it, i += 1) |
| 2142 | { | 1901 | { |
| 2143 | TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; | 1902 | const FieldDecl *field_decl = *it; |
| 2144 | TypeTableEntry *field_type = type_struct_field->type_entry; | | |
| 2145 | | | |
| 2146 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, field_type->type_ref); | | |
| 2147 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, field_type->type_ref); | | |
| 2148 | uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(c->codegen->target_data_ref, struct_type->type_ref, i); | | |
| 2149 | di_element_types[i] = ZigLLVMCreateDebugMemberType(c->codegen->dbuilder, | | |
| 2150 | ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name), | | |
| 2151 | c->import->di_file, line + 1, | | |
| 2152 | debug_size_in_bits, | | |
| 2153 | debug_align_in_bits, | | |
| 2154 | debug_offset_in_bits, | | |
| 2155 | 0, field_type->di_type); | | |
| 2156 | | | |
| 2157 | assert(di_element_types[i]); | | |
| 2158 | | 1903 | |
| 2159 | } | 1904 | AstNode *field_node = trans_create_node(c, NodeTypeStructField); |
| 2160 | struct_type->data.structure.embedded_in_current = false; | 1905 | field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl)); |
| 2161 | | 1906 | field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), field_decl->getLocation()); |
| 2162 | struct_type->data.structure.gen_field_count = field_count; | | |
| 2163 | struct_type->data.structure.complete = true; | | |
| 2164 | struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref, | | |
| 2165 | struct_type->type_ref); | | |
| 2166 | | | |
| 2167 | uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, struct_type->type_ref); | | |
| 2168 | uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, struct_type->type_ref); | | |
| 2169 | ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(c->codegen->dbuilder, | | |
| 2170 | ZigLLVMFileToScope(c->import->di_file), | | |
| 2171 | buf_ptr(full_type_name), c->import->di_file, line + 1, | | |
| 2172 | debug_size_in_bits, | | |
| 2173 | debug_align_in_bits, | | |
| 2174 | 0, | | |
| 2175 | nullptr, di_element_types, field_count, 0, nullptr, ""); | | |
| 2176 | | | |
| 2177 | ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type); | | |
| 2178 | struct_type->di_type = replacement_di_type; | | |
| 2179 | | | |
| 2180 | return struct_type; | | |
| 2181 | } | | |
| 2182 | | 1907 | |
| 2183 | static void visit_record_decl(Context *c, const RecordDecl *record_decl) { | 1908 | if (field_node->data.struct_field.type == nullptr) { |
| 2184 | TypeTableEntry *struct_type = resolve_record_decl(c, record_decl); | 1909 | emit_warning(c, field_decl->getLocation(), |
| | 1910 | "struct %s demoted to opaque type - unresolved type", |
| | 1911 | is_anonymous ? "(anon)" : buf_ptr(bare_name)); |
| 2185 | | 1912 | |
| 2186 | if (struct_type->id == TypeTableEntryIdInvalid) { | 1913 | AstNode *opaque_node = trans_create_node_opaque(c); |
| 2187 | return; | 1914 | if (!is_anonymous) { |
| 2188 | } | 1915 | c->struct_type_table.put(bare_name, opaque_node); |
| | 1916 | add_global_weak_alias(c, bare_name, opaque_node); |
| | 1917 | add_global_var(c, full_type_name, opaque_node); |
| | 1918 | } |
| | 1919 | c->decl_table.put(record_decl, opaque_node); |
| 2189 | | 1920 | |
| 2190 | bool is_anonymous = (record_decl->isAnonymousStructOrUnion() || decl_name(record_decl)[0] == 0); | 1921 | return opaque_node; |
| 2191 | if (is_anonymous) | 1922 | } |
| 2192 | return; | 1923 | |
| | 1924 | struct_node->data.container_decl.fields.items[i] = field_node; |
| | 1925 | } |
| 2193 | | 1926 | |
| 2194 | Buf *bare_name = buf_create_from_str(decl_name(record_decl)); | | |
| 2195 | | 1927 | |
| 2196 | Tld *tld = add_container_tld(c, struct_type); | 1928 | return struct_node; |
| 2197 | add_global_weak_alias(c, bare_name, tld); | | |
| 2198 | } | 1929 | } |
| 2199 | | 1930 | |
| 2200 | static void visit_var_decl(Context *c, const VarDecl *var_decl) { | 1931 | static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| ... | @@ -2204,17 +1935,19 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { | ... | @@ -2204,17 +1935,19 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| 2204 | case VarDecl::TLS_None: | 1935 | case VarDecl::TLS_None: |
| 2205 | break; | 1936 | break; |
| 2206 | case VarDecl::TLS_Static: | 1937 | case VarDecl::TLS_Static: |
| 2207 | emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - static thread local storage\n", buf_ptr(name)); | 1938 | emit_warning(c, var_decl->getLocation(), |
| | 1939 | "ignoring variable '%s' - static thread local storage", buf_ptr(name)); |
| 2208 | return; | 1940 | return; |
| 2209 | case VarDecl::TLS_Dynamic: | 1941 | case VarDecl::TLS_Dynamic: |
| 2210 | emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - dynamic thread local storage\n", buf_ptr(name)); | 1942 | emit_warning(c, var_decl->getLocation(), |
| | 1943 | "ignoring variable '%s' - dynamic thread local storage", buf_ptr(name)); |
| 2211 | return; | 1944 | return; |
| 2212 | } | 1945 | } |
| 2213 | | 1946 | |
| 2214 | QualType qt = var_decl->getType(); | 1947 | QualType qt = var_decl->getType(); |
| 2215 | TypeTableEntry *var_type = resolve_qual_type(c, qt, var_decl); | 1948 | AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation()); |
| 2216 | if (var_type->id == TypeTableEntryIdInvalid) { | 1949 | if (var_type == nullptr) { |
| 2217 | emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type\n", buf_ptr(name)); | 1950 | emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name)); |
| 2218 | return; | 1951 | return; |
| 2219 | } | 1952 | } |
| 2220 | | 1953 | |
| ... | @@ -2223,59 +1956,53 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { | ... | @@ -2223,59 +1956,53 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { |
| 2223 | bool is_const = qt.isConstQualified(); | 1956 | bool is_const = qt.isConstQualified(); |
| 2224 | | 1957 | |
| 2225 | if (is_static && !is_extern) { | 1958 | if (is_static && !is_extern) { |
| 2226 | if (!var_decl->hasInit()) { | 1959 | AstNode *init_node; |
| 2227 | emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - no initializer\n", buf_ptr(name)); | 1960 | if (var_decl->hasInit()) { |
| 2228 | return; | 1961 | APValue *ap_value = var_decl->evaluateValue(); |
| 2229 | } | 1962 | if (ap_value == nullptr) { |
| 2230 | APValue *ap_value = var_decl->evaluateValue(); | | |
| 2231 | if (!ap_value) { | | |
| 2232 | emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unable to evaluate initializer\n", buf_ptr(name)); | | |
| 2233 | return; | | |
| 2234 | } | | |
| 2235 | ConstExprValue *init_value = nullptr; | | |
| 2236 | switch (ap_value->getKind()) { | | |
| 2237 | case APValue::Int: | | |
| 2238 | { | | |
| 2239 | if (var_type->id != TypeTableEntryIdInt) { | | |
| 2240 | emit_warning(c, var_decl->getLocation(), | | |
| 2241 | "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name)); | | |
| 2242 | return; | | |
| 2243 | } | | |
| 2244 | init_value = create_const_int_ap(c, var_type, var_decl, ap_value->getInt()); | | |
| 2245 | if (!init_value) | | |
| 2246 | return; | | |
| 2247 | | | |
| 2248 | break; | | |
| 2249 | } | | |
| 2250 | case APValue::Uninitialized: | | |
| 2251 | case APValue::Float: | | |
| 2252 | case APValue::ComplexInt: | | |
| 2253 | case APValue::ComplexFloat: | | |
| 2254 | case APValue::LValue: | | |
| 2255 | case APValue::Vector: | | |
| 2256 | case APValue::Array: | | |
| 2257 | case APValue::Struct: | | |
| 2258 | case APValue::Union: | | |
| 2259 | case APValue::MemberPointer: | | |
| 2260 | case APValue::AddrLabelDiff: | | |
| 2261 | emit_warning(c, var_decl->getLocation(), | 1963 | emit_warning(c, var_decl->getLocation(), |
| 2262 | "ignoring variable '%s' - unrecognized initializer value kind\n", buf_ptr(name)); | 1964 | "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name)); |
| 2263 | return; | 1965 | return; |
| | 1966 | } |
| | 1967 | switch (ap_value->getKind()) { |
| | 1968 | case APValue::Int: |
| | 1969 | init_node = trans_create_node_apint(c, ap_value->getInt()); |
| | 1970 | break; |
| | 1971 | case APValue::Uninitialized: |
| | 1972 | init_node = trans_create_node_symbol_str(c, "undefined"); |
| | 1973 | break; |
| | 1974 | case APValue::Float: |
| | 1975 | case APValue::ComplexInt: |
| | 1976 | case APValue::ComplexFloat: |
| | 1977 | case APValue::LValue: |
| | 1978 | case APValue::Vector: |
| | 1979 | case APValue::Array: |
| | 1980 | case APValue::Struct: |
| | 1981 | case APValue::Union: |
| | 1982 | case APValue::MemberPointer: |
| | 1983 | case APValue::AddrLabelDiff: |
| | 1984 | emit_warning(c, var_decl->getLocation(), |
| | 1985 | "ignoring variable '%s' - unrecognized initializer value kind", buf_ptr(name)); |
| | 1986 | return; |
| | 1987 | } |
| | 1988 | } else { |
| | 1989 | init_node = trans_create_node_symbol_str(c, "undefined"); |
| 2264 | } | 1990 | } |
| 2265 | | 1991 | |
| 2266 | TldVar *tld_var = create_global_var(c, name, init_value, true); | 1992 | AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, init_node); |
| 2267 | add_global(c, &tld_var->base); | 1993 | c->root->data.root.top_level_decls.append(var_node); |
| 2268 | return; | 1994 | return; |
| 2269 | } | 1995 | } |
| 2270 | | 1996 | |
| 2271 | if (is_extern) { | 1997 | if (is_extern) { |
| 2272 | TldVar *tld_var = create_global_var(c, name, create_const_runtime(var_type), is_const); | 1998 | AstNode *var_node = trans_create_node_var_decl(c, is_const, name, var_type, nullptr); |
| 2273 | tld_var->var->linkage = VarLinkageExternal; | 1999 | var_node->data.variable_declaration.is_extern = true; |
| 2274 | add_global(c, &tld_var->base); | 2000 | c->root->data.root.top_level_decls.append(var_node); |
| 2275 | return; | 2001 | return; |
| 2276 | } | 2002 | } |
| 2277 | | 2003 | |
| 2278 | emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - non-extern, non-static variable\n", buf_ptr(name)); | 2004 | emit_warning(c, var_decl->getLocation(), |
| | 2005 | "ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name)); |
| 2279 | return; | 2006 | return; |
| 2280 | } | 2007 | } |
| 2281 | | 2008 | |
| ... | @@ -2290,25 +2017,22 @@ static bool decl_visitor(void *context, const Decl *decl) { | ... | @@ -2290,25 +2017,22 @@ static bool decl_visitor(void *context, const Decl *decl) { |
| 2290 | visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl)); | 2017 | visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl)); |
| 2291 | break; | 2018 | break; |
| 2292 | case Decl::Enum: | 2019 | case Decl::Enum: |
| 2293 | visit_enum_decl(c, static_cast<const EnumDecl *>(decl)); | 2020 | resolve_enum_decl(c, static_cast<const EnumDecl *>(decl)); |
| 2294 | break; | 2021 | break; |
| 2295 | case Decl::Record: | 2022 | case Decl::Record: |
| 2296 | visit_record_decl(c, static_cast<const RecordDecl *>(decl)); | 2023 | resolve_record_decl(c, static_cast<const RecordDecl *>(decl)); |
| 2297 | break; | 2024 | break; |
| 2298 | case Decl::Var: | 2025 | case Decl::Var: |
| 2299 | visit_var_decl(c, static_cast<const VarDecl *>(decl)); | 2026 | visit_var_decl(c, static_cast<const VarDecl *>(decl)); |
| 2300 | break; | 2027 | break; |
| 2301 | default: | 2028 | default: |
| 2302 | emit_warning(c, decl->getLocation(), "ignoring %s decl\n", decl->getDeclKindName()); | 2029 | emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName()); |
| 2303 | } | 2030 | } |
| 2304 | | 2031 | |
| 2305 | return true; | 2032 | return true; |
| 2306 | } | 2033 | } |
| 2307 | | 2034 | |
| 2308 | static bool name_exists(Context *c, Buf *name) { | 2035 | static bool name_exists(Context *c, Buf *name) { |
| 2309 | if (c->global_type_table.maybe_get(name)) { | | |
| 2310 | return true; | | |
| 2311 | } | | |
| 2312 | if (get_global(c, name)) { | 2036 | if (get_global(c, name)) { |
| 2313 | return true; | 2037 | return true; |
| 2314 | } | 2038 | } |
| ... | @@ -2324,7 +2048,7 @@ static void render_aliases(Context *c) { | ... | @@ -2324,7 +2048,7 @@ static void render_aliases(Context *c) { |
| 2324 | if (name_exists(c, alias->name)) | 2048 | if (name_exists(c, alias->name)) |
| 2325 | continue; | 2049 | continue; |
| 2326 | | 2050 | |
| 2327 | add_global_alias(c, alias->name, alias->tld); | 2051 | add_global_var(c, alias->name, alias->node); |
| 2328 | } | 2052 | } |
| 2329 | } | 2053 | } |
| 2330 | | 2054 | |
| ... | @@ -2335,8 +2059,7 @@ static void render_macros(Context *c) { | ... | @@ -2335,8 +2059,7 @@ static void render_macros(Context *c) { |
| 2335 | if (!entry) | 2059 | if (!entry) |
| 2336 | break; | 2060 | break; |
| 2337 | | 2061 | |
| 2338 | Tld *var_tld = entry->value; | 2062 | add_global_var(c, entry->key, entry->value); |
| 2339 | add_global(c, var_tld); | | |
| 2340 | } | 2063 | } |
| 2341 | } | 2064 | } |
| 2342 | | 2065 | |
| ... | @@ -2355,52 +2078,52 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch | ... | @@ -2355,52 +2078,52 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch |
| 2355 | switch (tok->id) { | 2078 | switch (tok->id) { |
| 2356 | case CTokIdCharLit: | 2079 | case CTokIdCharLit: |
| 2357 | if (is_last && is_first) { | 2080 | if (is_last && is_first) { |
| 2358 | Tld *tld = create_global_num_lit_unsigned_negative(c, name, tok->data.char_lit, false); | 2081 | AstNode *node = trans_create_node_unsigned(c, tok->data.char_lit); |
| 2359 | c->macro_table.put(name, tld); | 2082 | c->macro_table.put(name, node); |
| 2360 | } | 2083 | } |
| 2361 | return; | 2084 | return; |
| 2362 | case CTokIdStrLit: | 2085 | case CTokIdStrLit: |
| 2363 | if (is_last && is_first) { | 2086 | if (is_last && is_first) { |
| 2364 | Tld *tld = create_global_str_lit_var(c, name, buf_create_from_buf(&tok->data.str_lit)); | 2087 | AstNode *node = trans_create_node_str_lit_c(c, buf_create_from_buf(&tok->data.str_lit)); |
| 2365 | c->macro_table.put(name, tld); | 2088 | c->macro_table.put(name, node); |
| 2366 | } | 2089 | } |
| 2367 | return; | 2090 | return; |
| 2368 | case CTokIdNumLitInt: | 2091 | case CTokIdNumLitInt: |
| 2369 | if (is_last) { | 2092 | if (is_last) { |
| 2370 | Tld *tld; | 2093 | AstNode *node; |
| 2371 | switch (tok->data.num_lit_int.suffix) { | 2094 | switch (tok->data.num_lit_int.suffix) { |
| 2372 | case CNumLitSuffixNone: | 2095 | case CNumLitSuffixNone: |
| 2373 | tld = create_global_num_lit_unsigned_negative(c, name, tok->data.num_lit_int.x, negate); | 2096 | node = trans_create_node_unsigned_negative(c, tok->data.num_lit_int.x, negate); |
| 2374 | break; | 2097 | break; |
| 2375 | case CNumLitSuffixL: | 2098 | case CNumLitSuffixL: |
| 2376 | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, | 2099 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 2377 | c->codegen->builtin_types.entry_c_int[CIntTypeLong]); | 2100 | "c_long"); |
| 2378 | break; | 2101 | break; |
| 2379 | case CNumLitSuffixU: | 2102 | case CNumLitSuffixU: |
| 2380 | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, | 2103 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 2381 | c->codegen->builtin_types.entry_c_int[CIntTypeUInt]); | 2104 | "c_uint"); |
| 2382 | break; | 2105 | break; |
| 2383 | case CNumLitSuffixLU: | 2106 | case CNumLitSuffixLU: |
| 2384 | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, | 2107 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 2385 | c->codegen->builtin_types.entry_c_int[CIntTypeULong]); | 2108 | "c_ulong"); |
| 2386 | break; | 2109 | break; |
| 2387 | case CNumLitSuffixLL: | 2110 | case CNumLitSuffixLL: |
| 2388 | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, | 2111 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 2389 | c->codegen->builtin_types.entry_c_int[CIntTypeLongLong]); | 2112 | "c_longlong"); |
| 2390 | break; | 2113 | break; |
| 2391 | case CNumLitSuffixLLU: | 2114 | case CNumLitSuffixLLU: |
| 2392 | tld = create_global_num_lit_unsigned_negative_type(c, name, tok->data.num_lit_int.x, negate, | 2115 | node = trans_create_node_unsigned_negative_type(c, tok->data.num_lit_int.x, negate, |
| 2393 | c->codegen->builtin_types.entry_c_int[CIntTypeULongLong]); | 2116 | "c_ulonglong"); |
| 2394 | break; | 2117 | break; |
| 2395 | } | 2118 | } |
| 2396 | c->macro_table.put(name, tld); | 2119 | c->macro_table.put(name, node); |
| 2397 | } | 2120 | } |
| 2398 | return; | 2121 | return; |
| 2399 | case CTokIdNumLitFloat: | 2122 | case CTokIdNumLitFloat: |
| 2400 | if (is_last) { | 2123 | if (is_last) { |
| 2401 | double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float; | 2124 | double value = negate ? -tok->data.num_lit_float : tok->data.num_lit_float; |
| 2402 | Tld *tld = create_global_num_lit_float(c, name, value); | 2125 | AstNode *node = trans_create_node_float_lit(c, value); |
| 2403 | c->macro_table.put(name, tld); | 2126 | c->macro_table.put(name, node); |
| 2404 | } | 2127 | } |
| 2405 | return; | 2128 | return; |
| 2406 | case CTokIdSymbol: | 2129 | case CTokIdSymbol: |
| ... | @@ -2429,29 +2152,29 @@ static void process_symbol_macros(Context *c) { | ... | @@ -2429,29 +2152,29 @@ static void process_symbol_macros(Context *c) { |
| 2429 | for (size_t i = 0; i < c->macro_symbols.length; i += 1) { | 2152 | for (size_t i = 0; i < c->macro_symbols.length; i += 1) { |
| 2430 | MacroSymbol ms = c->macro_symbols.at(i); | 2153 | MacroSymbol ms = c->macro_symbols.at(i); |
| 2431 | | 2154 | |
| 2432 | // If this macro aliases another top level declaration, we can make that happen by | 2155 | // Check if this macro aliases another top level declaration |
| 2433 | // putting another entry in the decl table pointing to the same top level decl. | 2156 | AstNode *existing_node = get_global(c, ms.value); |
| 2434 | Tld *existing_tld = get_global(c, ms.value); | 2157 | if (!existing_node || name_exists(c, ms.name)) |
| 2435 | if (!existing_tld) | | |
| 2436 | continue; | 2158 | continue; |
| 2437 | | 2159 | |
| 2438 | // If a macro aliases a global variable which is a function pointer, we conclude that | 2160 | // If a macro aliases a global variable which is a function pointer, we conclude that |
| 2439 | // the macro is intended to represent a function that assumes the function pointer | 2161 | // the macro is intended to represent a function that assumes the function pointer |
| 2440 | // variable is non-null and calls it. | 2162 | // variable is non-null and calls it. |
| 2441 | if (existing_tld->id == TldIdVar) { | 2163 | if (existing_node->type == NodeTypeVariableDeclaration) { |
| 2442 | TldVar *tld_var = (TldVar *)existing_tld; | 2164 | AstNode *var_expr = existing_node->data.variable_declaration.expr; |
| 2443 | TypeTableEntry *var_type = tld_var->var->value->type; | 2165 | if (var_expr != nullptr && var_expr->type == NodeTypePrefixOpExpr && |
| 2444 | if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) { | 2166 | var_expr->data.prefix_op_expr.prefix_op == PrefixOpMaybe) |
| 2445 | TypeTableEntry *child_type = var_type->data.maybe.child_type; | 2167 | { |
| 2446 | if (child_type->id == TypeTableEntryIdFn) { | 2168 | AstNode *fn_proto_node = var_expr->data.prefix_op_expr.primary_expr; |
| 2447 | Tld *tld = create_inline_fn_tld(c, ms.name, tld_var); | 2169 | if (fn_proto_node->type == NodeTypeFnProto) { |
| 2448 | c->macro_table.put(ms.name, tld); | 2170 | AstNode *inline_fn_node = trans_create_node_inline_fn(c, ms.name, ms.value, fn_proto_node); |
| | 2171 | c->macro_table.put(ms.name, inline_fn_node); |
| 2449 | continue; | 2172 | continue; |
| 2450 | } | 2173 | } |
| 2451 | } | 2174 | } |
| 2452 | } | 2175 | } |
| 2453 | | 2176 | |
| 2454 | add_global_alias(c, ms.name, existing_tld); | 2177 | add_global_var(c, ms.name, existing_node); |
| 2455 | } | 2178 | } |
| 2456 | } | 2179 | } |
| 2457 | | 2180 | |
| ... | @@ -2651,15 +2374,17 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch | ... | @@ -2651,15 +2374,17 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch |
| 2651 | | 2374 | |
| 2652 | c->ctx = &ast_unit->getASTContext(); | 2375 | c->ctx = &ast_unit->getASTContext(); |
| 2653 | c->source_manager = &ast_unit->getSourceManager(); | 2376 | c->source_manager = &ast_unit->getSourceManager(); |
| | 2377 | c->root = trans_create_node(c, NodeTypeRoot); |
| 2654 | | 2378 | |
| 2655 | ast_unit->visitLocalTopLevelDecls(c, decl_visitor); | 2379 | ast_unit->visitLocalTopLevelDecls(c, decl_visitor); |
| 2656 | | 2380 | |
| 2657 | process_preprocessor_entities(c, *ast_unit); | 2381 | process_preprocessor_entities(c, *ast_unit); |
| 2658 | | 2382 | |
| 2659 | process_symbol_macros(c); | | |
| 2660 | | | |
| 2661 | render_macros(c); | 2383 | render_macros(c); |
| | 2384 | process_symbol_macros(c); |
| 2662 | render_aliases(c); | 2385 | render_aliases(c); |
| 2663 | | 2386 | |
| | 2387 | import->root = c->root; |
| | 2388 | |
| 2664 | return 0; | 2389 | return 0; |
| 2665 | } | 2390 | } |