diff --git a/src/parseh.cpp b/src/parseh.cpp index 0dc853bb12..3633c0d497 100644 --- a/src/parseh.cpp +++ b/src/parseh.cpp @@ -225,6 +225,14 @@ static AstNode *add_typedef_node(Context *c, TypeTableEntry *type_decl) { return node; } +static AstNode *add_const_var_node(Context *c, Buf *name, TypeTableEntry *type_entry) { + AstNode *node = create_var_decl_node(c, buf_ptr(name), make_type_node(c, type_entry)); + + c->global_type_table.put(name, type_entry); + c->root->data.root.top_level_decls.append(node); + return node; +} + static TypeTableEntry *get_c_void_type(Context *c) { if (!c->c_void_type) { c->c_void_type = get_typedecl_type(c->codegen, "c_void", c->codegen->builtin_types.entry_u8); @@ -625,8 +633,7 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) emit_warning(c, typedef_decl, "typedef %s - unresolved child type", buf_ptr(type_name)); return; } - TypeTableEntry *decl_type = get_typedecl_type(c->codegen, buf_ptr(type_name), child_type); - add_typedef_node(c, decl_type); + add_const_var_node(c, type_name, child_type); } static void add_alias(Context *c, const char *new_name, const char *target_name) { @@ -803,7 +810,15 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ c->struct_type_table.put(bare_name, struct_type); RecordDecl *record_def = record_decl->getDefinition(); + unsigned line = c->source_node ? c->source_node->line : 0; if (!record_def) { + LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugForwardDeclType(c->codegen->dbuilder, + LLVMZigTag_DW_structure_type(), buf_ptr(full_type_name), + LLVMZigFileToScope(c->import->di_file), c->import->di_file, line); + + LLVMZigReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type); + struct_type->di_type = replacement_di_type; + return struct_type; } @@ -835,7 +850,6 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ uint64_t offset_in_bits = 0; uint32_t i = 0; - unsigned line = c->source_node ? c->source_node->line : 0; for (auto it = record_def->field_begin(), it_end = record_def->field_end(); it != it_end; ++it, i += 1) diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index a46d591298..ea4606bffa 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -262,6 +262,17 @@ LLVMZigDIType *LLVMZigCreateReplaceableCompositeType(LLVMZigDIBuilder *dibuilder return reinterpret_cast(di_type); } +LLVMZigDIType *LLVMZigCreateDebugForwardDeclType(LLVMZigDIBuilder *dibuilder, unsigned tag, + const char *name, LLVMZigDIScope *scope, LLVMZigDIFile *file, unsigned line) +{ + DIType *di_type = reinterpret_cast(dibuilder)->createForwardDecl( + tag, name, + reinterpret_cast(scope), + reinterpret_cast(file), + line); + return reinterpret_cast(di_type); +} + void LLVMZigReplaceTemporary(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *type, LLVMZigDIType *replacement) { diff --git a/src/zig_llvm.hpp b/src/zig_llvm.hpp index c0e06ae787..39c6a8d6fe 100644 --- a/src/zig_llvm.hpp +++ b/src/zig_llvm.hpp @@ -75,6 +75,9 @@ LLVMZigDIType *LLVMZigCreateDebugMemberType(LLVMZigDIBuilder *dibuilder, LLVMZig LLVMZigDIType *LLVMZigCreateReplaceableCompositeType(LLVMZigDIBuilder *dibuilder, unsigned tag, const char *name, LLVMZigDIScope *scope, LLVMZigDIFile *file, unsigned line); +LLVMZigDIType *LLVMZigCreateDebugForwardDeclType(LLVMZigDIBuilder *dibuilder, unsigned tag, + const char *name, LLVMZigDIScope *scope, LLVMZigDIFile *file, unsigned line); + void LLVMZigReplaceTemporary(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *type, LLVMZigDIType *replacement); diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 3cee4852cd..c873ae1b0d 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -2046,8 +2046,8 @@ typedef void Foo; Foo fun(Foo *a); )SOURCE", 3, "pub type c_void = u8;", - "pub type Foo = c_void;", - "pub extern fn fun(a: ?&Foo);"); + "pub const Foo = c_void;", + "pub extern fn fun(a: ?&c_void);"); } static void print_compiler_invocation(TestCase *test_case) {