| ... | @@ -8,6 +8,7 @@ const Token = std.zig.Token; | ... | @@ -8,6 +8,7 @@ const Token = std.zig.Token; |
| 8 | usingnamespace @import("clang.zig"); | 8 | usingnamespace @import("clang.zig"); |
| 9 | const ctok = @import("c_tokenizer.zig"); | 9 | const ctok = @import("c_tokenizer.zig"); |
| 10 | const CToken = ctok.CToken; | 10 | const CToken = ctok.CToken; |
| | 11 | const mem = std.mem; |
| 11 | | 12 | |
| 12 | const CallingConvention = std.builtin.TypeInfo.CallingConvention; | 13 | const CallingConvention = std.builtin.TypeInfo.CallingConvention; |
| 13 | | 14 | |
| ... | @@ -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 | } |
| 235 | | 236 | |
| 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 | } |
| 239 | | 240 | |
| 240 | /// Convert a null-terminated C string to a slice allocated in the arena | 241 | /// 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 | } |
| 244 | | 245 | |
| 245 | /// Convert a clang source location to a file:line:column string | 246 | /// 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 | }; |
| 256 | | 257 | |
| 257 | pub fn translate( | 258 | pub 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 |
| 540 | | 541 | |
| 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))); |
| 542 | | 543 | |
| 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"); |
| 567 | | 568 | |
| 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 |
| 704 | | 705 | |
| 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, "="); |
| 709 | | 710 | |
| 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 |
| 762 | | 763 | |
| 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))); |
| 764 | | 765 | |
| 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 | else | 768 | 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 size | 1541 | // TODO: maybe widen to increase size |
| 1551 | // TODO: maybe bitcast to change sign | 1542 | // TODO: maybe bitcast to change sign |
| 1552 | // TODO: maybe truncate to reduce size | 1543 | // TODO: maybe truncate to reduce size |
| ... | @@ -2364,9 +2355,9 @@ fn transCreatePostCrement( | ... | @@ -2364,9 +2355,9 @@ fn transCreatePostCrement( |
| 2364 | fn transCompoundAssignOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundAssignOperator, used: ResultUsed) TransError!*ast.Node { | 2355 | fn 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 | else | 2359 | 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 | else | 2363 | 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))); |
| 2647 | | 2638 | |
| 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 | } |
| 3178 | | 3169 | |
| 3179 | fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_alias_node: *ast.Node) !*ast.Node { | 3170 | fn 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; |
| 3181 | | 3172 | |
| 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, "("); |
| 3187 | | 3178 | |
| 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") or | 3940 | return mem.eql(u8, name, "comptime_float") or |
| 3952 | std.mem.eql(u8, name, "comptime_int") or | 3941 | mem.eql(u8, name, "comptime_int") or |
| 3953 | std.mem.eql(u8, name, "bool") or | 3942 | mem.eql(u8, name, "bool") or |
| 3954 | std.mem.eql(u8, name, "isize") or | 3943 | mem.eql(u8, name, "isize") or |
| 3955 | std.mem.eql(u8, name, "usize") or | 3944 | mem.eql(u8, name, "usize") or |
| 3956 | std.mem.eql(u8, name, "f16") or | 3945 | mem.eql(u8, name, "f16") or |
| 3957 | std.mem.eql(u8, name, "f32") or | 3946 | mem.eql(u8, name, "f32") or |
| 3958 | std.mem.eql(u8, name, "f64") or | 3947 | mem.eql(u8, name, "f64") or |
| 3959 | std.mem.eql(u8, name, "f128") or | 3948 | mem.eql(u8, name, "f128") or |
| 3960 | std.mem.eql(u8, name, "c_longdouble") or | 3949 | mem.eql(u8, name, "c_longdouble") or |
| 3961 | std.mem.eql(u8, name, "noreturn") or | 3950 | mem.eql(u8, name, "noreturn") or |
| 3962 | std.mem.eql(u8, name, "type") or | 3951 | mem.eql(u8, name, "type") or |
| 3963 | std.mem.eql(u8, name, "anyerror") or | 3952 | mem.eql(u8, name, "anyerror") or |
| 3964 | std.mem.eql(u8, name, "c_short") or | 3953 | mem.eql(u8, name, "c_short") or |
| 3965 | std.mem.eql(u8, name, "c_ushort") or | 3954 | mem.eql(u8, name, "c_ushort") or |
| 3966 | std.mem.eql(u8, name, "c_int") or | 3955 | mem.eql(u8, name, "c_int") or |
| 3967 | std.mem.eql(u8, name, "c_uint") or | 3956 | mem.eql(u8, name, "c_uint") or |
| 3968 | std.mem.eql(u8, name, "c_long") or | 3957 | mem.eql(u8, name, "c_long") or |
| 3969 | std.mem.eql(u8, name, "c_ulong") or | 3958 | mem.eql(u8, name, "c_ulong") or |
| 3970 | std.mem.eql(u8, name, "c_longlong") or | 3959 | mem.eql(u8, name, "c_longlong") or |
| 3971 | std.mem.eql(u8, name, "c_ulonglong"); | 3960 | mem.eql(u8, name, "c_ulonglong"); |
| 3972 | } | 3961 | } |
| 3973 | | 3962 | |
| 3974 | fn isValidZigIdentifier(name: []const u8) bool { | 3963 | fn 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 { |
| 4039 | | 4028 | |
| 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 stdin | 4036 | // #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 | } |
| 4495 | | 4484 | |
| 4496 | fn getFnDecl(c: *Context, ref: *ast.Node) ?*ast.Node { | 4485 | fn 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 | else | 4489 | return node; |
| 4501 | return null; | 4490 | } else if (node.cast(ast.Node.Identifier)) |ident| { |
| 4502 | // TODO a.b.c | 4491 | 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 | |
| | 4514 | fn 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 | |
| | 4542 | fn 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 { |
| 4517 | fn addMacros(c: *Context) !void { | 4556 | fn 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 that | 4560 | // 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 pointer | 4561 | // 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. |