From 4074e79748ad9ecc39a4127cd1c28c115efff56a Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Sat, 20 Feb 2021 13:32:07 +0200 Subject: [PATCH] translate-c: use global scope for typedef/record/enum type translation if needed If the type is a reference to a global declaration that has not yet been translated we need to use the global scope for translation so that other functions can also reference it. --- src/clang.zig | 2 -- src/translate_c.zig | 21 ++++++++++++++++++--- test/run_translated_c.zig | 19 +++++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/clang.zig b/src/clang.zig index 5adb858b90..270f477ddb 100644 --- a/src/clang.zig +++ b/src/clang.zig @@ -697,8 +697,6 @@ pub const ReturnStmt = opaque { extern fn ZigClangReturnStmt_getRetValue(*const ReturnStmt) ?*const Expr; }; -pub const SkipFunctionBodiesScope = opaque {}; - pub const SourceManager = opaque { pub const getSpellingLoc = ZigClangSourceManager_getSpellingLoc; extern fn ZigClangSourceManager_getSpellingLoc(*const SourceManager, Loc: SourceLocation) SourceLocation; diff --git a/src/translate_c.zig b/src/translate_c.zig index f29dfccfa3..dc13e5e380 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -3741,7 +3741,12 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan const typedef_ty = @ptrCast(*const clang.TypedefType, ty); const typedef_decl = typedef_ty.getDecl(); - try transTypeDef(c, scope, typedef_decl); + var trans_scope = scope; + if (@ptrCast(*const clang.Decl, typedef_decl).castToNamedDecl()) |named_decl| { + const decl_name = try c.str(named_decl.getName_bytes_begin()); + if (c.global_names.get(decl_name)) |_| trans_scope = &c.global_scope.base; + } + try transTypeDef(c, trans_scope, typedef_decl); const name = c.decl_table.get(@ptrToInt(typedef_decl.getCanonicalDecl())).?; return Tag.identifier.create(c.arena, name); }, @@ -3749,7 +3754,12 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan const record_ty = @ptrCast(*const clang.RecordType, ty); const record_decl = record_ty.getDecl(); - try transRecordDecl(c, scope, record_decl); + var trans_scope = scope; + if (@ptrCast(*const clang.Decl, record_decl).castToNamedDecl()) |named_decl| { + const decl_name = try c.str(named_decl.getName_bytes_begin()); + if (c.global_names.get(decl_name)) |_| trans_scope = &c.global_scope.base; + } + try transRecordDecl(c, trans_scope, record_decl); const name = c.decl_table.get(@ptrToInt(record_decl.getCanonicalDecl())).?; return Tag.identifier.create(c.arena, name); }, @@ -3757,7 +3767,12 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan const enum_ty = @ptrCast(*const clang.EnumType, ty); const enum_decl = enum_ty.getDecl(); - try transEnumDecl(c, scope, enum_decl); + var trans_scope = scope; + if (@ptrCast(*const clang.Decl, enum_decl).castToNamedDecl()) |named_decl| { + const decl_name = try c.str(named_decl.getName_bytes_begin()); + if (c.global_names.get(decl_name)) |_| trans_scope = &c.global_scope.base; + } + try transEnumDecl(c, trans_scope, enum_decl); const name = c.decl_table.get(@ptrToInt(enum_decl.getCanonicalDecl())).?; return Tag.identifier.create(c.arena, name); }, diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index 0b72ed2926..85b0f19c88 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -3,6 +3,25 @@ const tests = @import("tests.zig"); const nl = std.cstr.line_sep; pub fn addCases(cases: *tests.RunTranslatedCContext) void { + cases.add("use global scope for record/enum/typedef type transalation if needed", + \\void bar(void); + \\void baz(void); + \\struct foo { int x; }; + \\void bar() { + \\ struct foo tmp; + \\} + \\ + \\void baz() { + \\ struct foo tmp; + \\} + \\ + \\int main(void) { + \\ bar(); + \\ baz(); + \\ return 0; + \\} + , ""); + cases.add("failed macros are only declared once", \\#define FOO = \\#define FOO =