| ... | @@ -11,6 +11,7 @@ | ... | @@ -11,6 +11,7 @@ |
| 11 | #include "error.hpp" | 11 | #include "error.hpp" |
| 12 | #include "parser.hpp" | 12 | #include "parser.hpp" |
| 13 | #include "all_types.hpp" | 13 | #include "all_types.hpp" |
| | 14 | #include "tokenizer.hpp" |
| 14 | | 15 | |
| 15 | #include <clang/Frontend/ASTUnit.h> | 16 | #include <clang/Frontend/ASTUnit.h> |
| 16 | #include <clang/Frontend/CompilerInstance.h> | 17 | #include <clang/Frontend/CompilerInstance.h> |
| ... | @@ -24,11 +25,12 @@ struct Context { | ... | @@ -24,11 +25,12 @@ struct Context { |
| 24 | ZigList<ErrorMsg *> *errors; | 25 | ZigList<ErrorMsg *> *errors; |
| 25 | bool warnings_on; | 26 | bool warnings_on; |
| 26 | VisibMod visib_mod; | 27 | VisibMod visib_mod; |
| 27 | AstNode *c_void_decl_node; | 28 | bool have_c_void_decl_node; |
| 28 | AstNode *root; | 29 | AstNode *root; |
| 29 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> type_table; | 30 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> type_table; |
| 30 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table; | 31 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table; |
| 31 | SourceManager *source_manager; | 32 | SourceManager *source_manager; |
| | 33 | ZigList<AstNode *> aliases; |
| 32 | }; | 34 | }; |
| 33 | | 35 | |
| 34 | __attribute__ ((format (printf, 3, 4))) | 36 | __attribute__ ((format (printf, 3, 4))) |
| ... | @@ -57,7 +59,7 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...) | ... | @@ -57,7 +59,7 @@ static void emit_warning(Context *c, const Decl *decl, const char *format, ...) |
| 57 | fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg)); | 59 | fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg)); |
| 58 | } | 60 | } |
| 59 | | 61 | |
| 60 | static AstNode *make_qual_type_node(Context *c, QualType qt, Decl *decl); | 62 | static AstNode *make_qual_type_node(Context *c, QualType qt, const Decl *decl); |
| 61 | | 63 | |
| 62 | static AstNode *create_node(Context *c, NodeType type) { | 64 | static AstNode *create_node(Context *c, NodeType type) { |
| 63 | AstNode *node = allocate<AstNode>(1); | 65 | AstNode *node = allocate<AstNode>(1); |
| ... | @@ -66,33 +68,48 @@ static AstNode *create_node(Context *c, NodeType type) { | ... | @@ -66,33 +68,48 @@ static AstNode *create_node(Context *c, NodeType type) { |
| 66 | return node; | 68 | return node; |
| 67 | } | 69 | } |
| 68 | | 70 | |
| 69 | static AstNode *simple_type_node(Context *c, const char *type_name) { | 71 | static AstNode *create_symbol_node(Context *c, const char *type_name) { |
| 70 | AstNode *node = create_node(c, NodeTypeSymbol); | 72 | AstNode *node = create_node(c, NodeTypeSymbol); |
| 71 | buf_init_from_str(&node->data.symbol_expr.symbol, type_name); | 73 | buf_init_from_str(&node->data.symbol_expr.symbol, type_name); |
| 72 | return node; | 74 | return node; |
| 73 | } | 75 | } |
| 74 | | 76 | |
| 75 | static const char *decl_name(const Decl *decl) { | 77 | static AstNode *create_field_access_node(Context *c, const char *lhs, const char *rhs) { |
| 76 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); | 78 | AstNode *node = create_node(c, NodeTypeFieldAccessExpr); |
| 77 | return (const char *)named_decl->getName().bytes_begin(); | 79 | node->data.field_access_expr.struct_expr = create_symbol_node(c, lhs); |
| | 80 | buf_init_from_str(&node->data.field_access_expr.field_name, rhs); |
| | 81 | normalize_parent_ptrs(node); |
| | 82 | return node; |
| 78 | } | 83 | } |
| 79 | | 84 | |
| 80 | static ZigList<AstNode *> *create_empty_directives(Context *c) { | 85 | static ZigList<AstNode *> *create_empty_directives(Context *c) { |
| 81 | return allocate<ZigList<AstNode*>>(1); | 86 | return allocate<ZigList<AstNode*>>(1); |
| 82 | } | 87 | } |
| 83 | | 88 | |
| 84 | static AstNode *create_typedef_node(Context *c, Buf *new_name, AstNode *target_node) { | 89 | static AstNode *create_var_decl_node(Context *c, const char *var_name, AstNode *expr_node) { |
| 85 | if (!target_node) { | | |
| 86 | return nullptr; | | |
| 87 | } | | |
| 88 | AstNode *node = create_node(c, NodeTypeVariableDeclaration); | 90 | AstNode *node = create_node(c, NodeTypeVariableDeclaration); |
| 89 | buf_init_from_buf(&node->data.variable_declaration.symbol, new_name); | 91 | buf_init_from_str(&node->data.variable_declaration.symbol, var_name); |
| 90 | node->data.variable_declaration.is_const = true; | 92 | node->data.variable_declaration.is_const = true; |
| 91 | node->data.variable_declaration.visib_mod = c->visib_mod; | 93 | node->data.variable_declaration.visib_mod = c->visib_mod; |
| 92 | node->data.variable_declaration.expr = target_node; | 94 | node->data.variable_declaration.expr = expr_node; |
| 93 | node->data.variable_declaration.directives = create_empty_directives(c); | 95 | node->data.variable_declaration.directives = create_empty_directives(c); |
| 94 | normalize_parent_ptrs(node); | 96 | normalize_parent_ptrs(node); |
| | 97 | return node; |
| | 98 | } |
| | 99 | |
| | 100 | static const char *decl_name(const Decl *decl) { |
| | 101 | const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl); |
| | 102 | return (const char *)named_decl->getName().bytes_begin(); |
| | 103 | } |
| | 104 | |
| 95 | | 105 | |
| | 106 | static AstNode *add_typedef_node(Context *c, Buf *new_name, AstNode *target_node) { |
| | 107 | if (!target_node) { |
| | 108 | return nullptr; |
| | 109 | } |
| | 110 | AstNode *node = create_var_decl_node(c, buf_ptr(new_name), target_node); |
| | 111 | |
| | 112 | c->type_table.put(new_name, true); |
| 96 | c->root->data.root.top_level_decls.append(node); | 113 | c->root->data.root.top_level_decls.append(node); |
| 97 | return node; | 114 | return node; |
| 98 | } | 115 | } |
| ... | @@ -101,12 +118,11 @@ static AstNode *convert_to_c_void(Context *c, AstNode *type_node) { | ... | @@ -101,12 +118,11 @@ static AstNode *convert_to_c_void(Context *c, AstNode *type_node) { |
| 101 | if (type_node->type == NodeTypeSymbol && | 118 | if (type_node->type == NodeTypeSymbol && |
| 102 | buf_eql_str(&type_node->data.symbol_expr.symbol, "void")) | 119 | buf_eql_str(&type_node->data.symbol_expr.symbol, "void")) |
| 103 | { | 120 | { |
| 104 | if (!c->c_void_decl_node) { | 121 | if (!c->have_c_void_decl_node) { |
| 105 | c->c_void_decl_node = create_typedef_node(c, buf_create_from_str("c_void"), | 122 | add_typedef_node(c, buf_create_from_str("c_void"), create_symbol_node(c, "u8")); |
| 106 | simple_type_node(c, "u8")); | 123 | c->have_c_void_decl_node = true; |
| 107 | assert(c->c_void_decl_node); | | |
| 108 | } | 124 | } |
| 109 | return simple_type_node(c, "c_void"); | 125 | return create_symbol_node(c, "c_void"); |
| 110 | } else { | 126 | } else { |
| 111 | return type_node; | 127 | return type_node; |
| 112 | } | 128 | } |
| ... | @@ -123,42 +139,42 @@ static AstNode *pointer_to_type(Context *c, AstNode *type_node, bool is_const) { | ... | @@ -123,42 +139,42 @@ static AstNode *pointer_to_type(Context *c, AstNode *type_node, bool is_const) { |
| 123 | return node; | 139 | return node; |
| 124 | } | 140 | } |
| 125 | | 141 | |
| 126 | static AstNode *make_type_node(Context *c, const Type *ty, Decl *decl) { | 142 | static AstNode *make_type_node(Context *c, const Type *ty, const Decl *decl) { |
| 127 | switch (ty->getTypeClass()) { | 143 | switch (ty->getTypeClass()) { |
| 128 | case Type::Builtin: | 144 | case Type::Builtin: |
| 129 | { | 145 | { |
| 130 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); | 146 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); |
| 131 | switch (builtin_ty->getKind()) { | 147 | switch (builtin_ty->getKind()) { |
| 132 | case BuiltinType::Void: | 148 | case BuiltinType::Void: |
| 133 | return simple_type_node(c, "void"); | 149 | return create_symbol_node(c, "void"); |
| 134 | case BuiltinType::Bool: | 150 | case BuiltinType::Bool: |
| 135 | return simple_type_node(c, "bool"); | 151 | return create_symbol_node(c, "bool"); |
| 136 | case BuiltinType::Char_U: | 152 | case BuiltinType::Char_U: |
| 137 | case BuiltinType::UChar: | 153 | case BuiltinType::UChar: |
| 138 | case BuiltinType::Char_S: | 154 | case BuiltinType::Char_S: |
| 139 | return simple_type_node(c, "u8"); | 155 | return create_symbol_node(c, "u8"); |
| 140 | case BuiltinType::SChar: | 156 | case BuiltinType::SChar: |
| 141 | return simple_type_node(c, "i8"); | 157 | return create_symbol_node(c, "i8"); |
| 142 | case BuiltinType::UShort: | 158 | case BuiltinType::UShort: |
| 143 | return simple_type_node(c, "c_ushort"); | 159 | return create_symbol_node(c, "c_ushort"); |
| 144 | case BuiltinType::UInt: | 160 | case BuiltinType::UInt: |
| 145 | return simple_type_node(c, "c_uint"); | 161 | return create_symbol_node(c, "c_uint"); |
| 146 | case BuiltinType::ULong: | 162 | case BuiltinType::ULong: |
| 147 | return simple_type_node(c, "c_ulong"); | 163 | return create_symbol_node(c, "c_ulong"); |
| 148 | case BuiltinType::ULongLong: | 164 | case BuiltinType::ULongLong: |
| 149 | return simple_type_node(c, "c_ulonglong"); | 165 | return create_symbol_node(c, "c_ulonglong"); |
| 150 | case BuiltinType::Short: | 166 | case BuiltinType::Short: |
| 151 | return simple_type_node(c, "c_short"); | 167 | return create_symbol_node(c, "c_short"); |
| 152 | case BuiltinType::Int: | 168 | case BuiltinType::Int: |
| 153 | return simple_type_node(c, "c_int"); | 169 | return create_symbol_node(c, "c_int"); |
| 154 | case BuiltinType::Long: | 170 | case BuiltinType::Long: |
| 155 | return simple_type_node(c, "c_long"); | 171 | return create_symbol_node(c, "c_long"); |
| 156 | case BuiltinType::LongLong: | 172 | case BuiltinType::LongLong: |
| 157 | return simple_type_node(c, "c_longlong"); | 173 | return create_symbol_node(c, "c_longlong"); |
| 158 | case BuiltinType::Float: | 174 | case BuiltinType::Float: |
| 159 | return simple_type_node(c, "f32"); | 175 | return create_symbol_node(c, "f32"); |
| 160 | case BuiltinType::Double: | 176 | case BuiltinType::Double: |
| 161 | return simple_type_node(c, "f64"); | 177 | return create_symbol_node(c, "f64"); |
| 162 | case BuiltinType::LongDouble: | 178 | case BuiltinType::LongDouble: |
| 163 | case BuiltinType::WChar_U: | 179 | case BuiltinType::WChar_U: |
| 164 | case BuiltinType::Char16: | 180 | case BuiltinType::Char16: |
| ... | @@ -204,29 +220,29 @@ static AstNode *make_type_node(Context *c, const Type *ty, Decl *decl) { | ... | @@ -204,29 +220,29 @@ static AstNode *make_type_node(Context *c, const Type *ty, Decl *decl) { |
| 204 | const TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); | 220 | const TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); |
| 205 | Buf *type_name = buf_create_from_str(decl_name(typedef_decl)); | 221 | Buf *type_name = buf_create_from_str(decl_name(typedef_decl)); |
| 206 | if (buf_eql_str(type_name, "uint8_t")) { | 222 | if (buf_eql_str(type_name, "uint8_t")) { |
| 207 | return simple_type_node(c, "u8"); | 223 | return create_symbol_node(c, "u8"); |
| 208 | } else if (buf_eql_str(type_name, "int8_t")) { | 224 | } else if (buf_eql_str(type_name, "int8_t")) { |
| 209 | return simple_type_node(c, "i8"); | 225 | return create_symbol_node(c, "i8"); |
| 210 | } else if (buf_eql_str(type_name, "uint16_t")) { | 226 | } else if (buf_eql_str(type_name, "uint16_t")) { |
| 211 | return simple_type_node(c, "u16"); | 227 | return create_symbol_node(c, "u16"); |
| 212 | } else if (buf_eql_str(type_name, "int16_t")) { | 228 | } else if (buf_eql_str(type_name, "int16_t")) { |
| 213 | return simple_type_node(c, "i16"); | 229 | return create_symbol_node(c, "i16"); |
| 214 | } else if (buf_eql_str(type_name, "uint32_t")) { | 230 | } else if (buf_eql_str(type_name, "uint32_t")) { |
| 215 | return simple_type_node(c, "u32"); | 231 | return create_symbol_node(c, "u32"); |
| 216 | } else if (buf_eql_str(type_name, "int32_t")) { | 232 | } else if (buf_eql_str(type_name, "int32_t")) { |
| 217 | return simple_type_node(c, "i32"); | 233 | return create_symbol_node(c, "i32"); |
| 218 | } else if (buf_eql_str(type_name, "uint64_t")) { | 234 | } else if (buf_eql_str(type_name, "uint64_t")) { |
| 219 | return simple_type_node(c, "u64"); | 235 | return create_symbol_node(c, "u64"); |
| 220 | } else if (buf_eql_str(type_name, "int64_t")) { | 236 | } else if (buf_eql_str(type_name, "int64_t")) { |
| 221 | return simple_type_node(c, "i64"); | 237 | return create_symbol_node(c, "i64"); |
| 222 | } else if (buf_eql_str(type_name, "intptr_t")) { | 238 | } else if (buf_eql_str(type_name, "intptr_t")) { |
| 223 | return simple_type_node(c, "isize"); | 239 | return create_symbol_node(c, "isize"); |
| 224 | } else if (buf_eql_str(type_name, "uintptr_t")) { | 240 | } else if (buf_eql_str(type_name, "uintptr_t")) { |
| 225 | return simple_type_node(c, "usize"); | 241 | return create_symbol_node(c, "usize"); |
| 226 | } else { | 242 | } else { |
| 227 | auto entry = c->type_table.maybe_get(type_name); | 243 | auto entry = c->type_table.maybe_get(type_name); |
| 228 | if (entry) { | 244 | if (entry) { |
| 229 | return simple_type_node(c, buf_ptr(type_name)); | 245 | return create_symbol_node(c, buf_ptr(type_name)); |
| 230 | } else { | 246 | } else { |
| 231 | return nullptr; | 247 | return nullptr; |
| 232 | } | 248 | } |
| ... | @@ -280,7 +296,7 @@ static AstNode *make_type_node(Context *c, const Type *ty, Decl *decl) { | ... | @@ -280,7 +296,7 @@ static AstNode *make_type_node(Context *c, const Type *ty, Decl *decl) { |
| 280 | } | 296 | } |
| 281 | } | 297 | } |
| 282 | | 298 | |
| 283 | static AstNode *make_qual_type_node(Context *c, QualType qt, Decl *decl) { | 299 | static AstNode *make_qual_type_node(Context *c, QualType qt, const Decl *decl) { |
| 284 | return make_type_node(c, qt.getTypePtr(), decl); | 300 | return make_type_node(c, qt.getTypePtr(), decl); |
| 285 | } | 301 | } |
| 286 | | 302 | |
| ... | @@ -311,7 +327,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { | ... | @@ -311,7 +327,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 311 | buf_init_from_str(&param_decl_node->data.param_decl.name, name); | 327 | buf_init_from_str(&param_decl_node->data.param_decl.name, name); |
| 312 | QualType qt = param->getOriginalType(); | 328 | QualType qt = param->getOriginalType(); |
| 313 | param_decl_node->data.param_decl.is_noalias = qt.isRestrictQualified(); | 329 | param_decl_node->data.param_decl.is_noalias = qt.isRestrictQualified(); |
| 314 | param_decl_node->data.param_decl.type = make_qual_type_node(c, qt, (Decl*)fn_decl); | 330 | param_decl_node->data.param_decl.type = make_qual_type_node(c, qt, fn_decl); |
| 315 | if (!param_decl_node->data.param_decl.type) { | 331 | if (!param_decl_node->data.param_decl.type) { |
| 316 | all_ok = false; | 332 | all_ok = false; |
| 317 | break; | 333 | break; |
| ... | @@ -322,9 +338,9 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { | ... | @@ -322,9 +338,9 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 322 | } | 338 | } |
| 323 | | 339 | |
| 324 | if (fn_decl->isNoReturn()) { | 340 | if (fn_decl->isNoReturn()) { |
| 325 | node->data.fn_proto.return_type = simple_type_node(c, "unreachable"); | 341 | node->data.fn_proto.return_type = create_symbol_node(c, "unreachable"); |
| 326 | } else { | 342 | } else { |
| 327 | node->data.fn_proto.return_type = make_qual_type_node(c, fn_decl->getReturnType(), (Decl*)fn_decl); | 343 | node->data.fn_proto.return_type = make_qual_type_node(c, fn_decl->getReturnType(), fn_decl); |
| 328 | } | 344 | } |
| 329 | | 345 | |
| 330 | if (!node->data.fn_proto.return_type) { | 346 | if (!node->data.fn_proto.return_type) { |
| ... | @@ -332,7 +348,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { | ... | @@ -332,7 +348,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) { |
| 332 | } | 348 | } |
| 333 | if (!all_ok) { | 349 | if (!all_ok) { |
| 334 | // not all the types could be resolved, so we give up on the function decl | 350 | // not all the types could be resolved, so we give up on the function decl |
| 335 | emit_warning(c, (Decl*)fn_decl, "skipping function %s\n", buf_ptr(&node->data.fn_proto.name)); | 351 | emit_warning(c, fn_decl, "skipping function %s\n", buf_ptr(&node->data.fn_proto.name)); |
| 336 | return; | 352 | return; |
| 337 | } | 353 | } |
| 338 | | 354 | |
| ... | @@ -361,12 +377,92 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) | ... | @@ -361,12 +377,92 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) |
| 361 | return; | 377 | return; |
| 362 | } | 378 | } |
| 363 | | 379 | |
| 364 | AstNode *node = create_typedef_node(c, type_name, make_qual_type_node(c, child_qt, (Decl*)typedef_decl)); | 380 | add_typedef_node(c, type_name, make_qual_type_node(c, child_qt, typedef_decl)); |
| | 381 | } |
| | 382 | |
| | 383 | static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { |
| | 384 | Buf bare_name = BUF_INIT; |
| | 385 | buf_init_from_str(&bare_name, decl_name(enum_decl)); |
| | 386 | |
| | 387 | Buf *type_name = buf_alloc(); |
| | 388 | buf_appendf(type_name, "enum_%s", buf_ptr(&bare_name)); |
| | 389 | |
| | 390 | if (c->type_table.maybe_get(type_name)) { |
| | 391 | // we've already seen it |
| | 392 | return; |
| | 393 | } |
| | 394 | |
| | 395 | const EnumDecl *enum_def = enum_decl->getDefinition(); |
| | 396 | |
| | 397 | if (!enum_def) { |
| | 398 | // this is a type that we can point to but that's it, same as `struct Foo;`. |
| | 399 | add_typedef_node(c, type_name, create_symbol_node(c, "u8")); |
| | 400 | return; |
| | 401 | } |
| | 402 | |
| | 403 | AstNode *node = create_node(c, NodeTypeStructDecl); |
| | 404 | buf_init_from_buf(&node->data.struct_decl.name, type_name); |
| | 405 | |
| | 406 | node->data.struct_decl.kind = ContainerKindEnum; |
| | 407 | node->data.struct_decl.visib_mod = c->visib_mod; |
| | 408 | node->data.struct_decl.directives = create_empty_directives(c); |
| | 409 | |
| | 410 | ZigList<AstNode *> var_decls = {0}; |
| | 411 | int i = 0; |
| | 412 | for (auto it = enum_def->enumerator_begin(), |
| | 413 | it_end = enum_def->enumerator_end(); |
| | 414 | it != it_end; ++it, i += 1) |
| | 415 | { |
| | 416 | const EnumConstantDecl *enum_const = *it; |
| | 417 | if (enum_const->getInitExpr()) { |
| | 418 | emit_warning(c, enum_const, "skipping enum %s - has init expression\n", buf_ptr(type_name)); |
| | 419 | return; |
| | 420 | } |
| | 421 | AstNode *field_node = create_node(c, NodeTypeStructField); |
| | 422 | Buf enum_val_name = BUF_INIT; |
| | 423 | buf_init_from_str(&enum_val_name, decl_name(enum_const)); |
| | 424 | |
| | 425 | if (buf_starts_with_buf(&enum_val_name, &bare_name)) { |
| | 426 | Buf *slice = buf_slice(&enum_val_name, buf_len(&bare_name), buf_len(&enum_val_name)); |
| | 427 | if (valid_symbol_starter(buf_ptr(slice)[0])) { |
| | 428 | buf_init_from_buf(&field_node->data.struct_field.name, slice); |
| | 429 | } else { |
| | 430 | buf_resize(&field_node->data.struct_field.name, 0); |
| | 431 | buf_appendf(&field_node->data.struct_field.name, "_%s", buf_ptr(slice)); |
| | 432 | } |
| | 433 | } else { |
| | 434 | buf_init_from_buf(&field_node->data.struct_field.name, &enum_val_name); |
| | 435 | } |
| | 436 | |
| | 437 | field_node->data.struct_field.directives = create_empty_directives(c); |
| | 438 | field_node->data.struct_field.visib_mod = VisibModPub; |
| | 439 | field_node->data.struct_field.type = create_symbol_node(c, "void"); |
| | 440 | |
| | 441 | normalize_parent_ptrs(field_node); |
| | 442 | node->data.struct_decl.fields.append(field_node); |
| | 443 | |
| | 444 | // in C each enum value is in the global namespace. so we put them there too. |
| | 445 | AstNode *field_access_node = create_field_access_node(c, buf_ptr(type_name), |
| | 446 | buf_ptr(&field_node->data.struct_field.name)); |
| | 447 | AstNode *var_node = create_var_decl_node(c, buf_ptr(&enum_val_name), field_access_node); |
| | 448 | var_decls.append(var_node); |
| | 449 | } |
| | 450 | |
| | 451 | c->type_table.put(type_name, true); |
| 365 | | 452 | |
| 366 | if (node) { | 453 | normalize_parent_ptrs(node); |
| 367 | normalize_parent_ptrs(node); | 454 | c->root->data.root.top_level_decls.append(node); |
| 368 | c->type_table.put(type_name, true); | 455 | |
| | 456 | for (int i = 0; i < var_decls.length; i += 1) { |
| | 457 | AstNode *var_node = var_decls.at(i); |
| | 458 | c->root->data.root.top_level_decls.append(var_node); |
| 369 | } | 459 | } |
| | 460 | |
| | 461 | // make an alias without the "enum_" prefix. this will get emitted at the |
| | 462 | // end if it doesn't conflict with anything else |
| | 463 | AstNode *alias_node = create_var_decl_node(c, buf_ptr(&bare_name), create_symbol_node(c, buf_ptr(type_name))); |
| | 464 | c->aliases.append(alias_node); |
| | 465 | |
| 370 | } | 466 | } |
| 371 | | 467 | |
| 372 | static bool decl_visitor(void *context, const Decl *decl) { | 468 | static bool decl_visitor(void *context, const Decl *decl) { |
| ... | @@ -379,6 +475,9 @@ static bool decl_visitor(void *context, const Decl *decl) { | ... | @@ -379,6 +475,9 @@ static bool decl_visitor(void *context, const Decl *decl) { |
| 379 | case Decl::Typedef: | 475 | case Decl::Typedef: |
| 380 | visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl)); | 476 | visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl)); |
| 381 | break; | 477 | break; |
| | 478 | case Decl::Enum: |
| | 479 | visit_enum_decl(c, static_cast<const EnumDecl *>(decl)); |
| | 480 | break; |
| 382 | default: | 481 | default: |
| 383 | emit_warning(c, decl, "ignoring %s decl\n", decl->getDeclKindName()); | 482 | emit_warning(c, decl, "ignoring %s decl\n", decl->getDeclKindName()); |
| 384 | } | 483 | } |
| ... | @@ -386,6 +485,21 @@ static bool decl_visitor(void *context, const Decl *decl) { | ... | @@ -386,6 +485,21 @@ static bool decl_visitor(void *context, const Decl *decl) { |
| 386 | return true; | 485 | return true; |
| 387 | } | 486 | } |
| 388 | | 487 | |
| | 488 | static void render_aliases(Context *c) { |
| | 489 | for (int i = 0; i < c->aliases.length; i += 1) { |
| | 490 | AstNode *alias_node = c->aliases.at(i); |
| | 491 | assert(alias_node->type == NodeTypeVariableDeclaration); |
| | 492 | Buf *name = &alias_node->data.variable_declaration.symbol; |
| | 493 | if (c->type_table.maybe_get(name)) { |
| | 494 | continue; |
| | 495 | } |
| | 496 | if (c->fn_table.maybe_get(name)) { |
| | 497 | continue; |
| | 498 | } |
| | 499 | c->root->data.root.top_level_decls.append(alias_node); |
| | 500 | } |
| | 501 | } |
| | 502 | |
| 389 | int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *source, | 503 | int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *source, |
| 390 | const char **args, int args_len, const char *libc_include_path, bool warnings_on) | 504 | const char **args, int args_len, const char *libc_include_path, bool warnings_on) |
| 391 | { | 505 | { |
| ... | @@ -514,8 +628,10 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, | ... | @@ -514,8 +628,10 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, |
| 514 | | 628 | |
| 515 | c->root = create_node(c, NodeTypeRoot); | 629 | c->root = create_node(c, NodeTypeRoot); |
| 516 | ast_unit->visitLocalTopLevelDecls(c, decl_visitor); | 630 | ast_unit->visitLocalTopLevelDecls(c, decl_visitor); |
| 517 | normalize_parent_ptrs(c->root); | | |
| 518 | | 631 | |
| | 632 | render_aliases(c); |
| | 633 | |
| | 634 | normalize_parent_ptrs(c->root); |
| 519 | import->root = c->root; | 635 | import->root = c->root; |
| 520 | | 636 | |
| 521 | return 0; | 637 | return 0; |