commit 4074e79748ad9ecc39a4127cd1c28c115efff56a (tree)
parent 669c2054a83cac594e5bbca4a7ca677e3b3a1a0d
Author: Veikka Tuominen <git@vexu.eu>
Date: Sat, 20 Feb 2021 13:32:07 +0200
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.
Diffstat:
3 files changed, 37 insertions(+), 5 deletions(-)
diff --git 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
@@ -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
@@ -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 =