authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-19 20:54:39+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-12-19 20:58:48+02:00
log61482be15380be22c8333ff4c6557108596efba2
treee82c17a5d615cf50ceb0c572ef55eda1d7ba876b
parentf837c7c9cd8f355aeea1dea1e9b328820802ee34
signature Commit is signed but in an unrecognized format.

translate-c-2 improve macro fn ptr caller


4 files changed, 131 insertions(+), 92 deletions(-)

lib/std/zig/ast.zig+4-4
...@@ -1436,8 +1436,8 @@ pub const Node = struct {...@@ -1436,8 +1436,8 @@ pub const Node = struct {
1436 AssignMod,1436 AssignMod,
1437 AssignAdd,1437 AssignAdd,
1438 AssignAddWrap,1438 AssignAddWrap,
1439 AssignMult,1439 AssignMul,
1440 AssignMultWrap,1440 AssignMulWrap,
1441 BangEqual,1441 BangEqual,
1442 BitAnd,1442 BitAnd,
1443 BitOr,1443 BitOr,
...@@ -1495,8 +1495,8 @@ pub const Node = struct {...@@ -1495,8 +1495,8 @@ pub const Node = struct {
1495 Op.AssignMod,1495 Op.AssignMod,
1496 Op.AssignAdd,1496 Op.AssignAdd,
1497 Op.AssignAddWrap,1497 Op.AssignAddWrap,
1498 Op.AssignMult,1498 Op.AssignMul,
1499 Op.AssignMultWrap,1499 Op.AssignMulWrap,
1500 Op.BangEqual,1500 Op.BangEqual,
1501 Op.BitAnd,1501 Op.BitAnd,
1502 Op.BitOr,1502 Op.BitOr,
lib/std/zig/parse.zig+2-2
...@@ -1981,7 +1981,7 @@ fn parseAssignOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1981,7 +1981,7 @@ fn parseAssignOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
19811981
1982 const token = nextToken(it);1982 const token = nextToken(it);
1983 const op = switch (token.ptr.id) {1983 const op = switch (token.ptr.id) {
1984 .AsteriskEqual => Op{ .AssignMult = {} },1984 .AsteriskEqual => Op{ .AssignMul = {} },
1985 .SlashEqual => Op{ .AssignDiv = {} },1985 .SlashEqual => Op{ .AssignDiv = {} },
1986 .PercentEqual => Op{ .AssignMod = {} },1986 .PercentEqual => Op{ .AssignMod = {} },
1987 .PlusEqual => Op{ .AssignAdd = {} },1987 .PlusEqual => Op{ .AssignAdd = {} },
...@@ -1991,7 +1991,7 @@ fn parseAssignOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1991,7 +1991,7 @@ fn parseAssignOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1991 .AmpersandEqual => Op{ .AssignBitAnd = {} },1991 .AmpersandEqual => Op{ .AssignBitAnd = {} },
1992 .CaretEqual => Op{ .AssignBitXor = {} },1992 .CaretEqual => Op{ .AssignBitXor = {} },
1993 .PipeEqual => Op{ .AssignBitOr = {} },1993 .PipeEqual => Op{ .AssignBitOr = {} },
1994 .AsteriskPercentEqual => Op{ .AssignMultWrap = {} },1994 .AsteriskPercentEqual => Op{ .AssignMulWrap = {} },
1995 .PlusPercentEqual => Op{ .AssignAddWrap = {} },1995 .PlusPercentEqual => Op{ .AssignAddWrap = {} },
1996 .MinusPercentEqual => Op{ .AssignSubWrap = {} },1996 .MinusPercentEqual => Op{ .AssignSubWrap = {} },
1997 .Equal => Op{ .Assign = {} },1997 .Equal => Op{ .Assign = {} },
src-self-hosted/translate_c.zig+117-78
...@@ -8,6 +8,7 @@ const Token = std.zig.Token;...@@ -8,6 +8,7 @@ const Token = std.zig.Token;
8usingnamespace @import("clang.zig");8usingnamespace @import("clang.zig");
9const ctok = @import("c_tokenizer.zig");9const ctok = @import("c_tokenizer.zig");
10const CToken = ctok.CToken;10const CToken = ctok.CToken;
11const mem = std.mem;
1112
12const CallingConvention = std.builtin.TypeInfo.CallingConvention;13const CallingConvention = std.builtin.TypeInfo.CallingConvention;
1314
...@@ -83,7 +84,7 @@ const Scope = struct {...@@ -83,7 +84,7 @@ const Scope = struct {
83 fn getAlias(scope: *Block, name: []const u8) ?[]const u8 {84 fn getAlias(scope: *Block, name: []const u8) ?[]const u8 {
84 var it = scope.variables.iterator(0);85 var it = scope.variables.iterator(0);
85 while (it.next()) |p| {86 while (it.next()) |p| {
86 if (std.mem.eql(u8, p.name, name))87 if (mem.eql(u8, p.name, name))
87 return p.alias;88 return p.alias;
88 }89 }
89 return scope.base.parent.?.getAlias(name);90 return scope.base.parent.?.getAlias(name);
...@@ -92,7 +93,7 @@ const Scope = struct {...@@ -92,7 +93,7 @@ const Scope = struct {
92 fn contains(scope: *Block, name: []const u8) bool {93 fn contains(scope: *Block, name: []const u8) bool {
93 var it = scope.variables.iterator(0);94 var it = scope.variables.iterator(0);
94 while (it.next()) |p| {95 while (it.next()) |p| {
95 if (std.mem.eql(u8, p.name, name))96 if (mem.eql(u8, p.name, name))
96 return true;97 return true;
97 }98 }
98 return scope.base.parent.?.contains(name);99 return scope.base.parent.?.contains(name);
...@@ -137,7 +138,7 @@ const Scope = struct {...@@ -137,7 +138,7 @@ const Scope = struct {
137 fn getAlias(scope: *FnDef, name: []const u8) ?[]const u8 {138 fn getAlias(scope: *FnDef, name: []const u8) ?[]const u8 {
138 var it = scope.params.iterator(0);139 var it = scope.params.iterator(0);
139 while (it.next()) |p| {140 while (it.next()) |p| {
140 if (std.mem.eql(u8, p.name, name))141 if (mem.eql(u8, p.name, name))
141 return p.alias;142 return p.alias;
142 }143 }
143 return scope.base.parent.?.getAlias(name);144 return scope.base.parent.?.getAlias(name);
...@@ -146,7 +147,7 @@ const Scope = struct {...@@ -146,7 +147,7 @@ const Scope = struct {
146 fn contains(scope: *FnDef, name: []const u8) bool {147 fn contains(scope: *FnDef, name: []const u8) bool {
147 var it = scope.params.iterator(0);148 var it = scope.params.iterator(0);
148 while (it.next()) |p| {149 while (it.next()) |p| {
149 if (std.mem.eql(u8, p.name, name))150 if (mem.eql(u8, p.name, name))
150 return true;151 return true;
151 }152 }
152 return scope.base.parent.?.contains(name);153 return scope.base.parent.?.contains(name);
...@@ -233,13 +234,13 @@ const Context = struct {...@@ -233,13 +234,13 @@ const Context = struct {
233 return c.mangle_count;234 return c.mangle_count;
234 }235 }
235236
236 fn a(c: *Context) *std.mem.Allocator {237 fn a(c: *Context) *mem.Allocator {
237 return &c.tree.arena_allocator.allocator;238 return &c.tree.arena_allocator.allocator;
238 }239 }
239240
240 /// Convert a null-terminated C string to a slice allocated in the arena241 /// Convert a null-terminated C string to a slice allocated in the arena
241 fn str(c: *Context, s: [*:0]const u8) ![]u8 {242 fn str(c: *Context, s: [*:0]const u8) ![]u8 {
242 return std.mem.dupe(c.a(), u8, std.mem.toSliceConst(u8, s));243 return mem.dupe(c.a(), u8, mem.toSliceConst(u8, s));
243 }244 }
244245
245 /// Convert a clang source location to a file:line:column string246 /// Convert a clang source location to a file:line:column string
...@@ -255,7 +256,7 @@ const Context = struct {...@@ -255,7 +256,7 @@ const Context = struct {
255};256};
256257
257pub fn translate(258pub fn translate(
258 backing_allocator: *std.mem.Allocator,259 backing_allocator: *mem.Allocator,
259 args_begin: [*]?[*]const u8,260 args_begin: [*]?[*]const u8,
260 args_end: [*]?[*]const u8,261 args_end: [*]?[*]const u8,
261 errors: *[]ClangErrMsg,262 errors: *[]ClangErrMsg,
...@@ -540,29 +541,29 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error...@@ -540,29 +541,29 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl) Error
540541
541 const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));542 const typedef_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
542543
543 if (std.mem.eql(u8, typedef_name, "uint8_t"))544 if (mem.eql(u8, typedef_name, "uint8_t"))
544 return transTypeDefAsBuiltin(c, typedef_decl, "u8")545 return transTypeDefAsBuiltin(c, typedef_decl, "u8")
545 else if (std.mem.eql(u8, typedef_name, "int8_t"))546 else if (mem.eql(u8, typedef_name, "int8_t"))
546 return transTypeDefAsBuiltin(c, typedef_decl, "i8")547 return transTypeDefAsBuiltin(c, typedef_decl, "i8")
547 else if (std.mem.eql(u8, typedef_name, "uint16_t"))548 else if (mem.eql(u8, typedef_name, "uint16_t"))
548 return transTypeDefAsBuiltin(c, typedef_decl, "u16")549 return transTypeDefAsBuiltin(c, typedef_decl, "u16")
549 else if (std.mem.eql(u8, typedef_name, "int16_t"))550 else if (mem.eql(u8, typedef_name, "int16_t"))
550 return transTypeDefAsBuiltin(c, typedef_decl, "i16")551 return transTypeDefAsBuiltin(c, typedef_decl, "i16")
551 else if (std.mem.eql(u8, typedef_name, "uint32_t"))552 else if (mem.eql(u8, typedef_name, "uint32_t"))
552 return transTypeDefAsBuiltin(c, typedef_decl, "u32")553 return transTypeDefAsBuiltin(c, typedef_decl, "u32")
553 else if (std.mem.eql(u8, typedef_name, "int32_t"))554 else if (mem.eql(u8, typedef_name, "int32_t"))
554 return transTypeDefAsBuiltin(c, typedef_decl, "i32")555 return transTypeDefAsBuiltin(c, typedef_decl, "i32")
555 else if (std.mem.eql(u8, typedef_name, "uint64_t"))556 else if (mem.eql(u8, typedef_name, "uint64_t"))
556 return transTypeDefAsBuiltin(c, typedef_decl, "u64")557 return transTypeDefAsBuiltin(c, typedef_decl, "u64")
557 else if (std.mem.eql(u8, typedef_name, "int64_t"))558 else if (mem.eql(u8, typedef_name, "int64_t"))
558 return transTypeDefAsBuiltin(c, typedef_decl, "i64")559 return transTypeDefAsBuiltin(c, typedef_decl, "i64")
559 else if (std.mem.eql(u8, typedef_name, "intptr_t"))560 else if (mem.eql(u8, typedef_name, "intptr_t"))
560 return transTypeDefAsBuiltin(c, typedef_decl, "isize")561 return transTypeDefAsBuiltin(c, typedef_decl, "isize")
561 else if (std.mem.eql(u8, typedef_name, "uintptr_t"))562 else if (mem.eql(u8, typedef_name, "uintptr_t"))
562 return transTypeDefAsBuiltin(c, typedef_decl, "usize")563 return transTypeDefAsBuiltin(c, typedef_decl, "usize")
563 else if (std.mem.eql(u8, typedef_name, "ssize_t"))564 else if (mem.eql(u8, typedef_name, "ssize_t"))
564 return transTypeDefAsBuiltin(c, typedef_decl, "isize")565 return transTypeDefAsBuiltin(c, typedef_decl, "isize")
565 else if (std.mem.eql(u8, typedef_name, "size_t"))566 else if (mem.eql(u8, typedef_name, "size_t"))
566 return transTypeDefAsBuiltin(c, typedef_decl, "usize");567 return transTypeDefAsBuiltin(c, typedef_decl, "usize");
567568
568 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), typedef_name);569 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), typedef_name);
...@@ -704,7 +705,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No...@@ -704,7 +705,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
704705
705 const name = try std.fmt.allocPrint(c.a(), "enum_{}", .{bare_name});706 const name = try std.fmt.allocPrint(c.a(), "enum_{}", .{bare_name});
706 _ = try c.decl_table.put(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)), name);707 _ = try c.decl_table.put(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)), name);
707 const node = try transCreateNodeVarDecl(c, true, true, name);708 const node = try transCreateNodeVarDecl(c, !is_unnamed, true, name);
708 node.eq_token = try appendToken(c, .Equal, "=");709 node.eq_token = try appendToken(c, .Equal, "=");
709710
710 node.init_node = if (ZigClangEnumDecl_getDefinition(enum_decl)) |enum_def| blk: {711 node.init_node = if (ZigClangEnumDecl_getDefinition(enum_decl)) |enum_def| blk: {
...@@ -762,7 +763,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No...@@ -762,7 +763,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
762763
763 const enum_val_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, enum_const)));764 const enum_val_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, enum_const)));
764765
765 const field_name = if (!is_unnamed and std.mem.startsWith(u8, enum_val_name, bare_name))766 const field_name = if (!is_unnamed and mem.startsWith(u8, enum_val_name, bare_name))
766 enum_val_name[bare_name.len..]767 enum_val_name[bare_name.len..]
767 else768 else
768 enum_val_name;769 enum_val_name;
...@@ -1448,7 +1449,7 @@ fn writeEscapedString(buf: []u8, s: []const u8) void {...@@ -1448,7 +1449,7 @@ fn writeEscapedString(buf: []u8, s: []const u8) void {
1448 var i: usize = 0;1449 var i: usize = 0;
1449 for (s) |c| {1450 for (s) |c| {
1450 const escaped = escapeChar(c, &char_buf);1451 const escaped = escapeChar(c, &char_buf);
1451 std.mem.copy(u8, buf[i..], escaped);1452 mem.copy(u8, buf[i..], escaped);
1452 i += escaped.len;1453 i += escaped.len;
1453 }1454 }
1454}1455}
...@@ -1537,16 +1538,6 @@ fn transCCast(...@@ -1537,16 +1538,6 @@ fn transCCast(
1537 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");1538 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1538 return &builtin_node.base;1539 return &builtin_node.base;
1539 }1540 }
1540 // TODO
1541 // if (ZigClangQualType_getTypeClass(dst_type) == .Enum and
1542 // ZigClangQualType_getTypeClass(src_type) != .Enum) {
1543 // const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
1544 // try builtin_node.params.push(try transQualType(rp, dst_type, loc));
1545 // _ = try appendToken(rp.c, .Comma, ",");
1546 // try builtin_node.params.push(expr);
1547 // builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1548 // return &builtin_node.base;
1549 // }
1550 // TODO: maybe widen to increase size1541 // TODO: maybe widen to increase size
1551 // TODO: maybe bitcast to change sign1542 // TODO: maybe bitcast to change sign
1552 // TODO: maybe truncate to reduce size1543 // TODO: maybe truncate to reduce size
...@@ -2364,9 +2355,9 @@ fn transCreatePostCrement(...@@ -2364,9 +2355,9 @@ fn transCreatePostCrement(
2364fn transCompoundAssignOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundAssignOperator, used: ResultUsed) TransError!*ast.Node {2355fn transCompoundAssignOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundAssignOperator, used: ResultUsed) TransError!*ast.Node {
2365 switch (ZigClangCompoundAssignOperator_getOpcode(stmt)) {2356 switch (ZigClangCompoundAssignOperator_getOpcode(stmt)) {
2366 .MulAssign => if (qualTypeHaswrappingOverflow(ZigClangCompoundAssignOperator_getType(stmt)))2357 .MulAssign => if (qualTypeHaswrappingOverflow(ZigClangCompoundAssignOperator_getType(stmt)))
2367 return transCreateCompoundAssign(rp, scope, stmt, .AssignMultWrap, .AsteriskPercentEqual, "*%=", .MultWrap, .AsteriskPercent, "*%", used)2358 return transCreateCompoundAssign(rp, scope, stmt, .AssignMulWrap, .AsteriskPercentEqual, "*%=", .MultWrap, .AsteriskPercent, "*%", used)
2368 else2359 else
2369 return transCreateCompoundAssign(rp, scope, stmt, .AssignMult, .AsteriskEqual, "*=", .Mult, .Asterisk, "*", used),2360 return transCreateCompoundAssign(rp, scope, stmt, .AssignMul, .AsteriskEqual, "*=", .Mult, .Asterisk, "*", used),
2370 .AddAssign => if (qualTypeHaswrappingOverflow(ZigClangCompoundAssignOperator_getType(stmt)))2361 .AddAssign => if (qualTypeHaswrappingOverflow(ZigClangCompoundAssignOperator_getType(stmt)))
2371 return transCreateCompoundAssign(rp, scope, stmt, .AssignAddWrap, .PlusPercentEqual, "+%=", .AddWrap, .PlusPercent, "+%", used)2362 return transCreateCompoundAssign(rp, scope, stmt, .AssignAddWrap, .PlusPercentEqual, "+%=", .AddWrap, .PlusPercent, "+%", used)
2372 else2363 else
...@@ -2645,13 +2636,13 @@ fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigCl...@@ -2645,13 +2636,13 @@ fn qualTypeIntBitWidth(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigCl
2645 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);2636 const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
2646 const type_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));2637 const type_name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_decl)));
26472638
2648 if (std.mem.eql(u8, type_name, "uint8_t") or std.mem.eql(u8, type_name, "int8_t")) {2639 if (mem.eql(u8, type_name, "uint8_t") or mem.eql(u8, type_name, "int8_t")) {
2649 return 8;2640 return 8;
2650 } else if (std.mem.eql(u8, type_name, "uint16_t") or std.mem.eql(u8, type_name, "int16_t")) {2641 } else if (mem.eql(u8, type_name, "uint16_t") or mem.eql(u8, type_name, "int16_t")) {
2651 return 16;2642 return 16;
2652 } else if (std.mem.eql(u8, type_name, "uint32_t") or std.mem.eql(u8, type_name, "int32_t")) {2643 } else if (mem.eql(u8, type_name, "uint32_t") or mem.eql(u8, type_name, "int32_t")) {
2653 return 32;2644 return 32;
2654 } else if (std.mem.eql(u8, type_name, "uint64_t") or std.mem.eql(u8, type_name, "int64_t")) {2645 } else if (mem.eql(u8, type_name, "uint64_t") or mem.eql(u8, type_name, "int64_t")) {
2655 return 64;2646 return 64;
2656 } else {2647 } else {
2657 return 0;2648 return 0;
...@@ -3176,7 +3167,7 @@ fn transCreateNodeOpaqueType(c: *Context) !*ast.Node {...@@ -3176,7 +3167,7 @@ fn transCreateNodeOpaqueType(c: *Context) !*ast.Node {
3176 return &call_node.base;3167 return &call_node.base;
3177}3168}
31783169
3179fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_alias_node: *ast.Node) !*ast.Node {3170fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_alias: *ast.Node.FnProto) !*ast.Node {
3180 const scope = &c.global_scope.base;3171 const scope = &c.global_scope.base;
31813172
3182 const pub_tok = try appendToken(c, .Keyword_pub, "pub");3173 const pub_tok = try appendToken(c, .Keyword_pub, "pub");
...@@ -3185,8 +3176,6 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a...@@ -3185,8 +3176,6 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
3185 const name_tok = try appendIdentifier(c, name);3176 const name_tok = try appendIdentifier(c, name);
3186 _ = try appendToken(c, .LParen, "(");3177 _ = try appendToken(c, .LParen, "(");
31873178
3188 const proto_alias = proto_alias_node.cast(ast.Node.FnProto).?;
3189
3190 var fn_params = ast.Node.FnProto.ParamList.init(c.a());3179 var fn_params = ast.Node.FnProto.ParamList.init(c.a());
3191 var it = proto_alias.params.iterator(0);3180 var it = proto_alias.params.iterator(0);
3192 while (it.next()) |pn| {3181 while (it.next()) |pn| {
...@@ -3948,27 +3937,27 @@ fn isZigPrimitiveType(name: []const u8) bool {...@@ -3948,27 +3937,27 @@ fn isZigPrimitiveType(name: []const u8) bool {
3948 return true;3937 return true;
3949 }3938 }
3950 // void is invalid in c so it doesn't need to be checked.3939 // void is invalid in c so it doesn't need to be checked.
3951 return std.mem.eql(u8, name, "comptime_float") or3940 return mem.eql(u8, name, "comptime_float") or
3952 std.mem.eql(u8, name, "comptime_int") or3941 mem.eql(u8, name, "comptime_int") or
3953 std.mem.eql(u8, name, "bool") or3942 mem.eql(u8, name, "bool") or
3954 std.mem.eql(u8, name, "isize") or3943 mem.eql(u8, name, "isize") or
3955 std.mem.eql(u8, name, "usize") or3944 mem.eql(u8, name, "usize") or
3956 std.mem.eql(u8, name, "f16") or3945 mem.eql(u8, name, "f16") or
3957 std.mem.eql(u8, name, "f32") or3946 mem.eql(u8, name, "f32") or
3958 std.mem.eql(u8, name, "f64") or3947 mem.eql(u8, name, "f64") or
3959 std.mem.eql(u8, name, "f128") or3948 mem.eql(u8, name, "f128") or
3960 std.mem.eql(u8, name, "c_longdouble") or3949 mem.eql(u8, name, "c_longdouble") or
3961 std.mem.eql(u8, name, "noreturn") or3950 mem.eql(u8, name, "noreturn") or
3962 std.mem.eql(u8, name, "type") or3951 mem.eql(u8, name, "type") or
3963 std.mem.eql(u8, name, "anyerror") or3952 mem.eql(u8, name, "anyerror") or
3964 std.mem.eql(u8, name, "c_short") or3953 mem.eql(u8, name, "c_short") or
3965 std.mem.eql(u8, name, "c_ushort") or3954 mem.eql(u8, name, "c_ushort") or
3966 std.mem.eql(u8, name, "c_int") or3955 mem.eql(u8, name, "c_int") or
3967 std.mem.eql(u8, name, "c_uint") or3956 mem.eql(u8, name, "c_uint") or
3968 std.mem.eql(u8, name, "c_long") or3957 mem.eql(u8, name, "c_long") or
3969 std.mem.eql(u8, name, "c_ulong") or3958 mem.eql(u8, name, "c_ulong") or
3970 std.mem.eql(u8, name, "c_longlong") or3959 mem.eql(u8, name, "c_longlong") or
3971 std.mem.eql(u8, name, "c_ulonglong");3960 mem.eql(u8, name, "c_ulonglong");
3972}3961}
39733962
3974fn isValidZigIdentifier(name: []const u8) bool {3963fn isValidZigIdentifier(name: []const u8) bool {
...@@ -4039,13 +4028,13 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {...@@ -4039,13 +4028,13 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
40394028
4040 var tok_it = tok_list.iterator(0);4029 var tok_it = tok_list.iterator(0);
4041 const first_tok = tok_it.next().?;4030 const first_tok = tok_it.next().?;
4042 assert(first_tok.id == .Identifier and std.mem.eql(u8, first_tok.bytes, name));4031 assert(first_tok.id == .Identifier and mem.eql(u8, first_tok.bytes, name));
4043 const next = tok_it.peek().?;4032 const next = tok_it.peek().?;
4044 switch (next.id) {4033 switch (next.id) {
4045 .Identifier => {4034 .Identifier => {
4046 // if it equals itself, ignore. for example, from stdio.h:4035 // if it equals itself, ignore. for example, from stdio.h:
4047 // #define stdin stdin4036 // #define stdin stdin
4048 if (std.mem.eql(u8, checked_name, next.bytes)) {4037 if (mem.eql(u8, checked_name, next.bytes)) {
4049 continue;4038 continue;
4050 }4039 }
4051 },4040 },
...@@ -4493,21 +4482,71 @@ fn tokenSlice(c: *Context, token: ast.TokenIndex) []const u8 {...@@ -4493,21 +4482,71 @@ fn tokenSlice(c: *Context, token: ast.TokenIndex) []const u8 {
4493 return c.source_buffer.toSliceConst()[tok.start..tok.end];4482 return c.source_buffer.toSliceConst()[tok.start..tok.end];
4494}4483}
44954484
4496fn getFnDecl(c: *Context, ref: *ast.Node) ?*ast.Node {4485fn getContainer(c: *Context, node: *ast.Node) ?*ast.Node {
4497 const init = if (ref.cast(ast.Node.VarDecl)) |v| v.init_node.? else return null;4486 if (node.id == .ContainerDecl) {
4498 const name = if (init.cast(ast.Node.Identifier)) |id|4487 return node;
4499 tokenSlice(c, id.token)4488 } else if (node.id == .PrefixOp) {
4500 else4489 return node;
4501 return null;4490 } else if (node.cast(ast.Node.Identifier)) |ident| {
4502 // TODO a.b.c4491 if (c.global_scope.sym_table.get(tokenSlice(c, ident.token))) |kv| {
4503 if (c.global_scope.sym_table.get(name)) |kv| {4492 if (kv.value.cast(ast.Node.VarDecl)) |var_decl|
4504 if (kv.value.cast(ast.Node.VarDecl)) |val| {4493 return getContainer(c, var_decl.init_node.?);
4505 if (val.type_node) |type_node| {4494 }
4506 if (type_node.cast(ast.Node.PrefixOp)) |casted| {4495 } else if (node.cast(ast.Node.InfixOp)) |infix| {
4507 if (casted.rhs.id == .FnProto) {4496 if (infix.op != .Period)
4508 return casted.rhs;4497 return null;
4498 if (getContainerTypeOf(c, infix.lhs)) |ty_node| {
4499 if (ty_node.cast(ast.Node.ContainerDecl)) |container| {
4500 var it = container.fields_and_decls.iterator(0);
4501 while (it.next()) |field_ref| {
4502 const field = field_ref.*.cast(ast.Node.ContainerField).?;
4503 const ident = infix.rhs.cast(ast.Node.Identifier).?;
4504 if (mem.eql(u8, tokenSlice(c, field.name_token), tokenSlice(c, ident.token))) {
4505 return getContainer(c, field.type_expr.?);
4506 }
4507 }
4508 }
4509 }
4510 }
4511 return null;
4512}
4513
4514fn getContainerTypeOf(c: *Context, ref: *ast.Node) ?*ast.Node {
4515 if (ref.cast(ast.Node.Identifier)) |ident| {
4516 if (c.global_scope.sym_table.get(tokenSlice(c, ident.token))) |kv| {
4517 if (kv.value.cast(ast.Node.VarDecl)) |var_decl| {
4518 if (var_decl.type_node) |ty|
4519 return getContainer(c, ty);
4520 }
4521 }
4522 } else if (ref.cast(ast.Node.InfixOp)) |infix| {
4523 if (infix.op != .Period)
4524 return null;
4525 if (getContainerTypeOf(c, infix.lhs)) |ty_node| {
4526 if (ty_node.cast(ast.Node.ContainerDecl)) |container| {
4527 var it = container.fields_and_decls.iterator(0);
4528 while (it.next()) |field_ref| {
4529 const field = field_ref.*.cast(ast.Node.ContainerField).?;
4530 const ident = infix.rhs.cast(ast.Node.Identifier).?;
4531 if (mem.eql(u8, tokenSlice(c, field.name_token), tokenSlice(c, ident.token))) {
4532 return getContainer(c, field.type_expr.?);
4509 }4533 }
4510 }4534 }
4535 } else
4536 return ty_node;
4537 }
4538 }
4539 return null;
4540}
4541
4542fn getFnProto(c: *Context, ref: *ast.Node) ?*ast.Node.FnProto {
4543 const init = if (ref.cast(ast.Node.VarDecl)) |v| v.init_node.? else return null;
4544 if (getContainerTypeOf(c, init)) |ty_node| {
4545 if (ty_node.cast(ast.Node.PrefixOp)) |prefix| {
4546 if (prefix.op == .OptionalType) {
4547 if (prefix.rhs.cast(ast.Node.FnProto)) |fn_proto| {
4548 return fn_proto;
4549 }
4511 }4550 }
4512 }4551 }
4513 }4552 }
...@@ -4517,7 +4556,7 @@ fn getFnDecl(c: *Context, ref: *ast.Node) ?*ast.Node {...@@ -4517,7 +4556,7 @@ fn getFnDecl(c: *Context, ref: *ast.Node) ?*ast.Node {
4517fn addMacros(c: *Context) !void {4556fn addMacros(c: *Context) !void {
4518 var macro_it = c.global_scope.macro_table.iterator();4557 var macro_it = c.global_scope.macro_table.iterator();
4519 while (macro_it.next()) |kv| {4558 while (macro_it.next()) |kv| {
4520 if (getFnDecl(c, kv.value)) |proto_node| {4559 if (getFnProto(c, kv.value)) |proto_node| {
4521 // If a macro aliases a global variable which is a function pointer, we conclude that4560 // If a macro aliases a global variable which is a function pointer, we conclude that
4522 // the macro is intended to represent a function that assumes the function pointer4561 // the macro is intended to represent a function that assumes the function pointer
4523 // variable is non-null and calls it.4562 // variable is non-null and calls it.
test/translate_c.zig+8-8
...@@ -887,7 +887,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -887,7 +887,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
887 \\pub const a = enum_unnamed_1.a;887 \\pub const a = enum_unnamed_1.a;
888 \\pub const b = enum_unnamed_1.b;888 \\pub const b = enum_unnamed_1.b;
889 \\pub const c = enum_unnamed_1.c;889 \\pub const c = enum_unnamed_1.c;
890 \\pub const enum_unnamed_1 = extern enum {890 \\const enum_unnamed_1 = extern enum {
891 \\ a,891 \\ a,
892 \\ b,892 \\ b,
893 \\ c,893 \\ c,
...@@ -896,7 +896,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -896,7 +896,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
896 \\pub const e = enum_unnamed_2.e;896 \\pub const e = enum_unnamed_2.e;
897 \\pub const f = enum_unnamed_2.f;897 \\pub const f = enum_unnamed_2.f;
898 \\pub const g = enum_unnamed_2.g;898 \\pub const g = enum_unnamed_2.g;
899 \\pub const enum_unnamed_2 = extern enum {899 \\const enum_unnamed_2 = extern enum {
900 \\ e = 0,900 \\ e = 0,
901 \\ f = 4,901 \\ f = 4,
902 \\ g = 5,902 \\ g = 5,
...@@ -905,7 +905,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -905,7 +905,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
905 \\pub const i = enum_unnamed_3.i;905 \\pub const i = enum_unnamed_3.i;
906 \\pub const j = enum_unnamed_3.j;906 \\pub const j = enum_unnamed_3.j;
907 \\pub const k = enum_unnamed_3.k;907 \\pub const k = enum_unnamed_3.k;
908 \\pub const enum_unnamed_3 = extern enum {908 \\const enum_unnamed_3 = extern enum {
909 \\ i,909 \\ i,
910 \\ j,910 \\ j,
911 \\ k,911 \\ k,
...@@ -1027,10 +1027,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1027,10 +1027,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1027 \\pub extern var glProcs: union_OpenGLProcs;1027 \\pub extern var glProcs: union_OpenGLProcs;
1028 ,1028 ,
1029 \\pub const glClearPFN = PFNGLCLEARPROC;1029 \\pub const glClearPFN = PFNGLCLEARPROC;
1030 // , // TODO1030 ,
1031 // \\pub inline fn glClearUnion(arg_1: GLbitfield) void {1031 \\pub inline fn glClearUnion(arg_2: GLbitfield) void {
1032 // \\ return glProcs.gl.Clear.?(arg_1);1032 \\ return glProcs.gl.Clear.?(arg_2);
1033 // \\}1033 \\}
1034 ,1034 ,
1035 \\pub const OpenGLProcs = union_OpenGLProcs;1035 \\pub const OpenGLProcs = union_OpenGLProcs;
1036 });1036 });
...@@ -1348,7 +1348,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1348,7 +1348,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1348 , &[_][]const u8{1348 , &[_][]const u8{
1349 \\pub const One = enum_unnamed_1.One;1349 \\pub const One = enum_unnamed_1.One;
1350 \\pub const Two = enum_unnamed_1.Two;1350 \\pub const Two = enum_unnamed_1.Two;
1351 \\pub const enum_unnamed_1 = extern enum {1351 \\const enum_unnamed_1 = extern enum {
1352 \\ One,1352 \\ One,
1353 \\ Two,1353 \\ Two,
1354 \\};1354 \\};