diff --git a/src-self-hosted/c_tokenizer.zig b/src-self-hosted/c_tokenizer.zig index ba44467565..1bc3c5f25c 100644 --- a/src-self-hosted/c_tokenizer.zig +++ b/src-self-hosted/c_tokenizer.zig @@ -17,6 +17,7 @@ pub const CToken = struct { NumLitInt, NumLitFloat, Identifier, + Plus, Minus, Slash, LParen, @@ -24,10 +25,17 @@ pub const CToken = struct { Eof, Dot, Asterisk, + Ampersand, + And, + Or, Bang, Tilde, Shl, + Shr, Lt, + Gt, + Increment, + Decrement, Comma, Fn, Arrow, @@ -226,6 +234,11 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*: var state: enum { Start, GotLt, + GotGt, + GotPlus, + GotMinus, + GotAmpersand, + GotPipe, CharLit, OpenComment, Comment, @@ -246,7 +259,6 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*: NumLitIntSuffixL, NumLitIntSuffixLL, NumLitIntSuffixUL, - Minus, Done, } = .Start; @@ -275,13 +287,17 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*: return result; }, .Start, - .Minus, + .GotMinus, .Done, .NumLitIntSuffixU, .NumLitIntSuffixL, .NumLitIntSuffixUL, .NumLitIntSuffixLL, .GotLt, + .GotGt, + .GotPlus, + .GotAmpersand, + .GotPipe, => { return result; }, @@ -345,6 +361,10 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*: result.id = .Lt; state = .GotLt; }, + '>' => { + result.id = .Gt; + state = .GotGt; + }, '(' => { result.id = .LParen; state = .Done; @@ -357,9 +377,13 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*: result.id = .Asterisk; state = .Done; }, + '+' => { + result.id = .Plus; + state = .GotPlus; + }, '-' => { - state = .Minus; result.id = .Minus; + state = .GotMinus; }, '!' => { result.id = .Bang; @@ -383,7 +407,11 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*: }, '|' => { result.id = .Pipe; - state = .Done; + state = .GotPipe; + }, + '&' => { + result.id = .Ampersand; + state = .GotAmpersand; }, '?' => { result.id = .QuestionMark; @@ -400,12 +428,27 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*: } }, .Done => return result, - .Minus => { + .GotMinus => { switch (c) { '>' => { result.id = .Arrow; state = .Done; }, + '-' => { + result.id = .Decrement; + state = .Done; + }, + else => { + return result; + }, + } + }, + .GotPlus => { + switch (c) { + '+' => { + result.id = .Increment; + state = .Done; + }, else => { return result; }, @@ -422,6 +465,39 @@ fn next(ctx: *Context, loc: ZigClangSourceLocation, name: []const u8, chars: [*: }, } }, + .GotGt => { + switch (c) { + '>' => { + result.id = .Shr; + state = .Done; + }, + else => { + return result; + }, + } + }, + .GotPipe => { + switch (c) { + '|' => { + result.id = .Or; + state = .Done; + }, + else => { + return result; + }, + } + }, + .GotAmpersand => { + switch (c) { + '&' => { + result.id = .And; + state = .Done; + }, + else => { + return result; + }, + } + }, .Float => { switch (c) { '.', '0'...'9' => {}, diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 87970168e8..e8670af70e 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -43,6 +43,7 @@ pub const struct_ZigClangImplicitCastExpr = @OpaqueType(); pub const struct_ZigClangIncompleteArrayType = @OpaqueType(); pub const struct_ZigClangIntegerLiteral = @OpaqueType(); pub const struct_ZigClangMacroDefinitionRecord = @OpaqueType(); +pub const struct_ZigClangMacroExpansion = @OpaqueType(); pub const struct_ZigClangMacroQualifiedType = @OpaqueType(); pub const struct_ZigClangMemberExpr = @OpaqueType(); pub const struct_ZigClangNamedDecl = @OpaqueType(); @@ -889,6 +890,7 @@ pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr; pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType; pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral; pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord; +pub const ZigClangMacroExpansion = struct_ZigClangMacroExpansion; pub const ZigClangMacroQualifiedType = struct_ZigClangMacroQualifiedType; pub const ZigClangMemberExpr = struct_ZigClangMemberExpr; pub const ZigClangNamedDecl = struct_ZigClangNamedDecl; @@ -1058,6 +1060,8 @@ pub extern fn ZigClangMacroDefinitionRecord_getName_getNameStart(*const ZigClang pub extern fn ZigClangMacroDefinitionRecord_getSourceRange_getBegin(*const ZigClangMacroDefinitionRecord) ZigClangSourceLocation; pub extern fn ZigClangMacroDefinitionRecord_getSourceRange_getEnd(*const ZigClangMacroDefinitionRecord) ZigClangSourceLocation; +pub extern fn ZigClangMacroExpansion_getDefinition(*const ZigClangMacroExpansion) *const ZigClangMacroDefinitionRecord; + pub extern fn ZigClangIfStmt_getThen(*const ZigClangIfStmt) *const ZigClangStmt; pub extern fn ZigClangIfStmt_getElse(*const ZigClangIfStmt) ?*const ZigClangStmt; pub extern fn ZigClangIfStmt_getCond(*const ZigClangIfStmt) *const ZigClangStmt; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index cd3282fb88..1bd4651060 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -4542,6 +4542,18 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig }; node = &bitshift_node.base; }, + .Shr => { + const op_token = try appendToken(rp.c, .AngleBracketAngleBracketRight, ">>"); + const rhs = try parseCExpr(rp, it, source_loc, scope); + const bitshift_node = try rp.c.a().create(ast.Node.InfixOp); + bitshift_node.* = .{ + .op_token = op_token, + .lhs = node, + .op = .BitShiftRight, + .rhs = rhs, + }; + node = &bitshift_node.base; + }, .Pipe => { const op_token = try appendToken(c, .Pipe, "|"); const rhs = try parseCExpr(c, it, source_loc, scope); @@ -4554,6 +4566,66 @@ fn parseCSuffixOpExpr(c: *Context, it: *ctok.TokenList.Iterator, source_loc: Zig }; node = &or_node.base; }, + .Ampersand => { + const op_token = try appendToken(rp.c, .Ampersand, "&"); + const rhs = try parseCExpr(rp, it, source_loc, scope); + const bitand_node = try rp.c.a().create(ast.Node.InfixOp); + bitand_node.* = .{ + .op_token = op_token, + .lhs = node, + .op = .BitAnd, + .rhs = rhs, + }; + node = &bitand_node.base; + }, + .Plus => { + const op_token = try appendToken(rp.c, .Plus, "+"); + const rhs = try parseCExpr(rp, it, source_loc, scope); + const add_node = try rp.c.a().create(ast.Node.InfixOp); + add_node.* = .{ + .op_token = op_token, + .lhs = node, + .op = .Add, + .rhs = rhs, + }; + node = &add_node.base; + }, + .Minus => { + const op_token = try appendToken(rp.c, .Minus, "-"); + const rhs = try parseCExpr(rp, it, source_loc, scope); + const sub_node = try rp.c.a().create(ast.Node.InfixOp); + sub_node.* = .{ + .op_token = op_token, + .lhs = node, + .op = .Sub, + .rhs = rhs, + }; + node = &sub_node.base; + }, + .And => { + const op_token = try appendToken(rp.c, .Keyword_and, "and"); + const rhs = try parseCExpr(rp, it, source_loc, scope); + const and_node = try rp.c.a().create(ast.Node.InfixOp); + and_node.* = .{ + .op_token = op_token, + .lhs = node, + .op = .BoolAnd, + .rhs = rhs, + }; + node = &and_node.base; + }, + .Or => { + const op_token = try appendToken(rp.c, .Keyword_or, "or"); + const rhs = try parseCExpr(rp, it, source_loc, scope); + const or_node = try rp.c.a().create(ast.Node.InfixOp); + or_node.* = .{ + .op_token = op_token, + .lhs = node, + .op = .BoolOr, + .rhs = rhs, + }; + node = &or_node.base; + }, .LBrace => { const arr_node = try transCreateNodeArrayAccess(c, node); arr_node.op.ArrayAccess = try parseCExpr(c, it, source_loc, scope); diff --git a/test/translate_c.zig b/test/translate_c.zig index 5f91d95990..cb979419a0 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -195,6 +195,15 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub const REDISMODULE_READ = 1 << 0; }); + cases.add("macro with right shift", + \\#define FLASH_SIZE 0x200000UL /* 2 MB */ + \\#define FLASH_BANK_SIZE (FLASH_SIZE >> 1) /* 1 MB */ + , &[_][]const u8{ + \\pub const FLASH_SIZE = @as(c_ulong, 0x200000); + , + \\pub const FLASH_BANK_SIZE = FLASH_SIZE >> 1; + }); + cases.add("double define struct", \\typedef struct Bar Bar; \\typedef struct Foo Foo; @@ -1068,6 +1077,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub const FOO_CHAR = '\xff'; }); + cases.add("macro add", + \\#define PERIPH_BASE (0x40000000UL) /*!< Base address of : AHB/APB Peripherals */ + \\#define D3_APB1PERIPH_BASE (PERIPH_BASE + 0x18000000UL) + \\#define RCC_BASE (D3_AHB1PERIPH_BASE + 0x4400UL) + , &[_][]const u8{ + \\pub const PERIPH_BASE = @as(c_ulong, 0x40000000); + , + \\pub const D3_APB1PERIPH_BASE = PERIPH_BASE + @as(c_ulong, 0x18000000); + , + \\pub const RCC_BASE = D3_AHB1PERIPH_BASE + @as(c_ulong, 0x4400); + }); + cases.add("variable aliasing", \\static long a = 2; \\static long b = 2;