Commit bf21747a42

Andrew Kelley <superjoe30@gmail.com>
2018-05-10 02:23:36
translate-c: fix typedef duplicate definition of variable
closes #998
1 parent 116914a
Changed files (2)
src/translate_c.cpp
@@ -3667,6 +3667,7 @@ static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_
     if (existing_entry) {
         return existing_entry->value;
     }
+
     QualType child_qt = typedef_decl->getUnderlyingType();
     Buf *type_name = buf_create_from_str(decl_name(typedef_decl));
 
@@ -3700,16 +3701,19 @@ static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_
     // use the name of this typedef
     // TODO
 
+    // trans_qual_type here might cause us to look at this typedef again so we put the item in the map first
+    AstNode *symbol_node = trans_create_node_symbol(c, type_name);
+    c->decl_table.put(typedef_decl->getCanonicalDecl(), symbol_node);
+
     AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation());
     if (type_node == nullptr) {
         emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name));
         c->decl_table.put(typedef_decl, nullptr);
+        // TODO add global var with type_name equal to @compileError("unable to resolve C type") 
         return nullptr;
     }
     add_global_var(c, type_name, type_node);
 
-    AstNode *symbol_node = trans_create_node_symbol(c, type_name);
-    c->decl_table.put(typedef_decl->getCanonicalDecl(), symbol_node);
     return symbol_node;
 }
 
test/translate_c.zig
@@ -1,6 +1,27 @@
 const tests = @import("tests.zig");
 
 pub fn addCases(cases: &tests.TranslateCContext) void {
+    cases.add("double define struct",
+        \\typedef struct Bar Bar;
+        \\typedef struct Foo Foo;
+        \\
+        \\struct Foo {
+        \\    Foo *a;
+        \\};
+        \\
+        \\struct Bar {
+        \\    Foo *a;
+        \\};
+    ,
+        \\pub const struct_Foo = extern struct {
+        \\    a: ?&Foo,
+        \\};
+        \\pub const Foo = struct_Foo;
+        \\pub const struct_Bar = extern struct {
+        \\    a: ?&Foo,
+        \\};
+    );
+
     cases.addAllowWarnings("simple data types",
         \\#include <stdint.h>
         \\int foo(char a, unsigned char b, signed char c);