translate-c: support sizeof and _Alignof in macros

Closes  #6301
This commit is contained in:
Vexu 2020-09-10 12:58:12 +03:00
parent 78baa16da0
commit 0833c8d06b
No known key found for this signature in database
GPG Key ID: 59AEB8936E16A6AC
3 changed files with 49 additions and 2 deletions

View File

@ -5899,6 +5899,10 @@ fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.N
saw_l_paren = true; saw_l_paren = true;
_ = m.next(); _ = m.next();
}, },
// (type)sizeof(x)
.Keyword_sizeof,
// (type)alignof(x)
.Keyword_alignof,
// (type)identifier // (type)identifier
.Identifier => {}, .Identifier => {},
// (type)integer // (type)integer
@ -6309,6 +6313,40 @@ fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast.
node.rhs = try parseCPrefixOpExpr(c, m, scope); node.rhs = try parseCPrefixOpExpr(c, m, scope);
return &node.base; return &node.base;
}, },
.Keyword_sizeof => {
const inner = if (m.peek().? == .LParen) blk: {
_ = m.next();
const inner = try parseCExpr(c, m, scope);
if (m.next().? != .RParen) {
try m.fail(c, "unable to translate C expr: expected ')'", .{});
return error.ParseError;
}
break :blk inner;
} else try parseCPrefixOpExpr(c, m, scope);
const builtin_call = try c.createBuiltinCall("@sizeOf", 1);
builtin_call.params()[0] = inner;
builtin_call.rparen_token = try appendToken(c, .RParen, ")");
return &builtin_call.base;
},
.Keyword_alignof => {
// TODO this won't work if using <stdalign.h>'s
// #define alignof _Alignof
if (m.next().? != .LParen) {
try m.fail(c, "unable to translate C expr: expected '('", .{});
return error.ParseError;
}
const inner = try parseCExpr(c, m, scope);
if (m.next().? != .RParen) {
try m.fail(c, "unable to translate C expr: expected ')'", .{});
return error.ParseError;
}
const builtin_call = try c.createBuiltinCall("@alignOf", 1);
builtin_call.params()[0] = inner;
builtin_call.rparen_token = try appendToken(c, .RParen, ")");
return &builtin_call.base;
},
else => { else => {
m.i -= 1; m.i -= 1;
return try parseCSuffixOpExpr(c, m, scope); return try parseCSuffixOpExpr(c, m, scope);

View File

@ -6,4 +6,7 @@ typedef struct Color {
unsigned char a; unsigned char a;
} Color; } Color;
#define CLITERAL(type) (type) #define CLITERAL(type) (type)
#define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray #define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray
#define MY_SIZEOF(x) ((int)sizeof(x))
#define MY_SIZEOF2(x) ((int)sizeof x)

View File

@ -1,12 +1,18 @@
const expect = @import("std").testing.expect; const expect = @import("std").testing.expect;
const expectEqual = @import("std").testing.expectEqual;
const h = @cImport(@cInclude("stage1/behavior/translate_c_macros.h")); const h = @cImport(@cInclude("stage1/behavior/translate_c_macros.h"));
test "initializer list expression" { test "initializer list expression" {
@import("std").testing.expectEqual(h.Color{ expectEqual(h.Color{
.r = 200, .r = 200,
.g = 200, .g = 200,
.b = 200, .b = 200,
.a = 255, .a = 255,
}, h.LIGHTGRAY); }, h.LIGHTGRAY);
} }
test "sizeof in macros" {
expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32));
expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32));
}