authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-01 18:53:08-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-01 18:53:08-05:00
log9298b9a4aab74524a3f4167fe127a35ea8ba13e8
treef68b601f55b8b7d1ccbd87c87bb541e6fb13678f
parentdc28526c6cd9320fefeebe15a90dd9269cf2b2ca
signature Commit is signed but in an unrecognized format.

translate-c: prevent name clashing of globals declared after locals


2 files changed, 48 insertions(+), 3 deletions(-)

src-self-hosted/translate_c.zig+35-3
...@@ -122,6 +122,7 @@ const Scope = struct {...@@ -122,6 +122,7 @@ const Scope = struct {
122 base: Scope,122 base: Scope,
123 sym_table: SymbolTable,123 sym_table: SymbolTable,
124 macro_table: SymbolTable,124 macro_table: SymbolTable,
125 context: *Context,
125126
126 fn init(c: *Context) Root {127 fn init(c: *Context) Root {
127 return .{128 return .{
...@@ -131,14 +132,20 @@ const Scope = struct {...@@ -131,14 +132,20 @@ const Scope = struct {
131 },132 },
132 .sym_table = SymbolTable.init(c.a()),133 .sym_table = SymbolTable.init(c.a()),
133 .macro_table = SymbolTable.init(c.a()),134 .macro_table = SymbolTable.init(c.a()),
135 .context = c,
134 };136 };
135 }137 }
136138
137 fn contains(scope: *Root, name: []const u8) bool {139 fn localContains(scope: *Root, name: []const u8) bool {
138 return isZigPrimitiveType(name) or140 return scope.sym_table.contains(name) or
139 scope.sym_table.contains(name) or
140 scope.macro_table.contains(name);141 scope.macro_table.contains(name);
141 }142 }
143
144 fn contains(scope: *Root, name: []const u8) bool {
145 return scope.localContains(name) or
146 isZigPrimitiveType(name) or
147 scope.context.global_names.contains(name);
148 }
142 };149 };
143150
144 fn findBlockScope(inner: *Scope, c: *Context) !*Scope.Block {151 fn findBlockScope(inner: *Scope, c: *Context) !*Scope.Block {
...@@ -207,6 +214,12 @@ pub const Context = struct {...@@ -207,6 +214,12 @@ pub const Context = struct {
207 clang_context: *ZigClangASTContext,214 clang_context: *ZigClangASTContext,
208 mangle_count: u32 = 0,215 mangle_count: u32 = 0,
209216
217 /// This one is different than the root scope's name table. This contains
218 /// a list of names that we found by visiting all the top level decls without
219 /// translating them. The other maps are updated as we translate; this one is updated
220 /// up front in a pre-processing step.
221 global_names: std.StringHashMap(void),
222
210 fn getMangle(c: *Context) u32 {223 fn getMangle(c: *Context) u32 {
211 c.mangle_count += 1;224 c.mangle_count += 1;
212 return c.mangle_count;225 return c.mangle_count;
...@@ -291,9 +304,14 @@ pub fn translate(...@@ -291,9 +304,14 @@ pub fn translate(
291 .alias_list = AliasList.init(arena),304 .alias_list = AliasList.init(arena),
292 .global_scope = try arena.create(Scope.Root),305 .global_scope = try arena.create(Scope.Root),
293 .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,306 .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
307 .global_names = std.StringHashMap(void).init(arena),
294 };308 };
295 context.global_scope.* = Scope.Root.init(&context);309 context.global_scope.* = Scope.Root.init(&context);
296310
311 if (!ZigClangASTUnit_visitLocalTopLevelDecls(ast_unit, &context, declVisitorNamesOnlyC)) {
312 return context.err;
313 }
314
297 if (!ZigClangASTUnit_visitLocalTopLevelDecls(ast_unit, &context, declVisitorC)) {315 if (!ZigClangASTUnit_visitLocalTopLevelDecls(ast_unit, &context, declVisitorC)) {
298 return context.err;316 return context.err;
299 }317 }
...@@ -321,6 +339,15 @@ pub fn translate(...@@ -321,6 +339,15 @@ pub fn translate(
321 return tree;339 return tree;
322}340}
323341
342extern fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const ZigClangDecl) bool {
343 const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context));
344 declVisitorNamesOnly(c, decl) catch |err| {
345 c.err = err;
346 return false;
347 };
348 return true;
349}
350
324extern fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) bool {351extern fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) bool {
325 const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context));352 const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context));
326 declVisitor(c, decl) catch |err| {353 declVisitor(c, decl) catch |err| {
...@@ -330,6 +357,11 @@ extern fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) bool {...@@ -330,6 +357,11 @@ extern fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) bool {
330 return true;357 return true;
331}358}
332359
360fn declVisitorNamesOnly(c: *Context, decl: *const ZigClangDecl) Error!void {
361 const decl_name = try c.str(ZigClangDecl_getName_bytes_begin(decl));
362 _ = try c.global_names.put(decl_name, {});
363}
364
333fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {365fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
334 switch (ZigClangDecl_getKind(decl)) {366 switch (ZigClangDecl_getKind(decl)) {
335 .Function => {367 .Function => {
test/translate_c.zig+13
...@@ -2275,4 +2275,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2275,4 +2275,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2275 \\ return @bitCast(c_ushort, @truncate(c_short, x));2275 \\ return @bitCast(c_ushort, @truncate(c_short, x));
2276 \\}2276 \\}
2277 });2277 });
2278
2279 cases.add("arg name aliasing decl which comes after",
2280 \\int foo(int bar) {
2281 \\ bar = 2;
2282 \\}
2283 \\int bar = 4;
2284 , &[_][]const u8{
2285 \\pub export fn foo(arg_bar_1: c_int) c_int {
2286 \\ var bar_1 = arg_bar_1;
2287 \\ bar_1 = 2;
2288 \\}
2289 \\pub export var bar: c_int = 4;
2290 });
2278}2291}