mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
translate-c: elide some unecessary casts of literals
This commit is contained in:
parent
74e9d4ca82
commit
9a826ccbe0
@ -127,6 +127,9 @@ pub const APSInt = opaque {
|
||||
|
||||
pub const getNumWords = ZigClangAPSInt_getNumWords;
|
||||
extern fn ZigClangAPSInt_getNumWords(*const APSInt) c_uint;
|
||||
|
||||
pub const lessThanEqual = ZigClangAPSInt_lessThanEqual;
|
||||
extern fn ZigClangAPSInt_lessThanEqual(*const APSInt, rhs: u64) bool;
|
||||
};
|
||||
|
||||
pub const ASTContext = opaque {
|
||||
@ -407,7 +410,7 @@ pub const Expr = opaque {
|
||||
pub const getBeginLoc = ZigClangExpr_getBeginLoc;
|
||||
extern fn ZigClangExpr_getBeginLoc(*const Expr) SourceLocation;
|
||||
|
||||
pub const EvaluateAsConstantExpr = ZigClangExpr_EvaluateAsConstantExpr;
|
||||
pub const evaluateAsConstantExpr = ZigClangExpr_EvaluateAsConstantExpr;
|
||||
extern fn ZigClangExpr_EvaluateAsConstantExpr(*const Expr, *ExprEvalResult, Expr_ConstExprUsage, *const ASTContext) bool;
|
||||
};
|
||||
|
||||
|
||||
@ -1820,11 +1820,55 @@ fn transExprCoercing(c: *Context, scope: *Scope, expr: *const clang.Expr, used:
|
||||
return transExprCoercing(c, scope, un_expr.getSubExpr(), used);
|
||||
}
|
||||
},
|
||||
.ImplicitCastExprClass => {
|
||||
const cast_expr = @ptrCast(*const clang.ImplicitCastExpr, expr);
|
||||
const sub_expr = cast_expr.getSubExpr();
|
||||
switch (@ptrCast(*const clang.Stmt, sub_expr).getStmtClass()) {
|
||||
.IntegerLiteralClass, .CharacterLiteralClass => switch (cast_expr.getCastKind()) {
|
||||
.IntegralToFloating => return transExprCoercing(c, scope, sub_expr, used),
|
||||
.IntegralCast => {
|
||||
const dest_type = getExprQualType(c, expr);
|
||||
if (literalFitsInType(c, sub_expr, dest_type))
|
||||
return transExprCoercing(c, scope, sub_expr, used);
|
||||
},
|
||||
else => {},
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
return transExpr(c, scope, expr, .used);
|
||||
}
|
||||
|
||||
fn literalFitsInType(c: *Context, expr: *const clang.Expr, qt: clang.QualType) bool {
|
||||
var width = qualTypeIntBitWidth(c, qt) catch 8;
|
||||
if (width == 0) width = 8; // Byte is the smallest type.
|
||||
const is_signed = cIsSignedInteger(qt);
|
||||
const width_max_int= (@as(u64, 1) << math.lossyCast(u6, width - @boolToInt(is_signed))) - 1;
|
||||
|
||||
switch (@ptrCast(*const clang.Stmt, expr).getStmtClass()) {
|
||||
.CharacterLiteralClass => {
|
||||
const char_lit = @ptrCast(*const clang.CharacterLiteral, expr);
|
||||
const val = char_lit.getValue();
|
||||
// If the val is less than the max int then it fits.
|
||||
return val <= width_max_int;
|
||||
},
|
||||
.IntegerLiteralClass => {
|
||||
const int_lit = @ptrCast(*const clang.IntegerLiteral, expr);
|
||||
var eval_result: clang.ExprEvalResult = undefined;
|
||||
if (!int_lit.EvaluateAsInt(&eval_result, c.clang_context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const int = eval_result.Val.getInt();
|
||||
return int.lessThanEqual(width_max_int);
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn transInitListExprRecord(
|
||||
c: *Context,
|
||||
scope: *Scope,
|
||||
@ -2331,7 +2375,7 @@ fn transDefault(
|
||||
|
||||
fn transConstantExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used: ResultUsed) TransError!Node {
|
||||
var result: clang.ExprEvalResult = undefined;
|
||||
if (!expr.EvaluateAsConstantExpr(&result, .EvaluateForCodeGen, c.clang_context))
|
||||
if (!expr.evaluateAsConstantExpr(&result, .EvaluateForCodeGen, c.clang_context))
|
||||
return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "invalid constant expression", .{});
|
||||
|
||||
switch (result.Val.getKind()) {
|
||||
@ -3171,7 +3215,7 @@ fn qualTypeIsBoolean(qt: clang.QualType) bool {
|
||||
return qualTypeCanon(qt).isBooleanType();
|
||||
}
|
||||
|
||||
fn qualTypeIntBitWidth(c: *Context, qt: clang.QualType, source_loc: clang.SourceLocation) !u32 {
|
||||
fn qualTypeIntBitWidth(c: *Context, qt: clang.QualType) !u32 {
|
||||
const ty = qt.getTypePtr();
|
||||
|
||||
switch (ty.getTypeClass()) {
|
||||
@ -3211,12 +3255,10 @@ fn qualTypeIntBitWidth(c: *Context, qt: clang.QualType, source_loc: clang.Source
|
||||
},
|
||||
else => return 0,
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
||||
|
||||
fn qualTypeToLog2IntRef(c: *Context, qt: clang.QualType, source_loc: clang.SourceLocation) !Node {
|
||||
const int_bit_width = try qualTypeIntBitWidth(c, qt, source_loc);
|
||||
const int_bit_width = try qualTypeIntBitWidth(c, qt);
|
||||
|
||||
if (int_bit_width != 0) {
|
||||
// we can perform the log2 now.
|
||||
|
||||
@ -2244,6 +2244,11 @@ unsigned ZigClangAPSInt_getNumWords(const ZigClangAPSInt *self) {
|
||||
return casted->getNumWords();
|
||||
}
|
||||
|
||||
bool ZigClangAPSInt_lessThanEqual(const ZigClangAPSInt *self, uint64_t rhs) {
|
||||
auto casted = reinterpret_cast<const llvm::APSInt *>(self);
|
||||
return casted->ule(rhs);
|
||||
}
|
||||
|
||||
uint64_t ZigClangAPInt_getLimitedValue(const ZigClangAPInt *self, uint64_t limit) {
|
||||
auto casted = reinterpret_cast<const llvm::APInt *>(self);
|
||||
return casted->getLimitedValue(limit);
|
||||
|
||||
@ -1097,6 +1097,7 @@ ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangAPSInt_negate(const struct Zig
|
||||
ZIG_EXTERN_C void ZigClangAPSInt_free(const struct ZigClangAPSInt *self);
|
||||
ZIG_EXTERN_C const uint64_t *ZigClangAPSInt_getRawData(const struct ZigClangAPSInt *self);
|
||||
ZIG_EXTERN_C unsigned ZigClangAPSInt_getNumWords(const struct ZigClangAPSInt *self);
|
||||
ZIG_EXTERN_C bool ZigClangAPSInt_lessThanEqual(const struct ZigClangAPSInt *self, uint64_t rhs);
|
||||
|
||||
ZIG_EXTERN_C uint64_t ZigClangAPInt_getLimitedValue(const struct ZigClangAPInt *self, uint64_t limit);
|
||||
|
||||
|
||||
@ -313,22 +313,22 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub const uuid_t = [16]u8;
|
||||
\\pub const UUID_NULL: uuid_t = [16]u8{
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\ 0,
|
||||
\\};
|
||||
});
|
||||
|
||||
@ -382,10 +382,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\};
|
||||
\\pub export var ub: union_unnamed_1 = union_unnamed_1{
|
||||
\\ .c = [4]u8{
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 'a'))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 'b'))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 'b'))),
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 'a'))),
|
||||
\\ 'a',
|
||||
\\ 'b',
|
||||
\\ 'b',
|
||||
\\ 'a',
|
||||
\\ },
|
||||
\\};
|
||||
});
|
||||
@ -512,7 +512,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() void {
|
||||
\\ var a: c_int = undefined;
|
||||
\\ var b: u8 = @bitCast(u8, @truncate(i8, @as(c_int, 123)));
|
||||
\\ var b: u8 = 123;
|
||||
\\ const c: c_int = undefined;
|
||||
\\ const d: c_uint = @bitCast(c_uint, @as(c_int, 440));
|
||||
\\ var e: c_int = 10;
|
||||
@ -1468,7 +1468,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub fn foo() callconv(.C) void {
|
||||
\\ var arr: [10]u8 = [1]u8{
|
||||
\\ @bitCast(u8, @truncate(i8, @as(c_int, 1))),
|
||||
\\ 1,
|
||||
\\ } ++ [1]u8{0} ** 9;
|
||||
\\ var arr1: [10][*c]u8 = [1][*c]u8{
|
||||
\\ null,
|
||||
@ -1721,13 +1721,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ unsigned d = 440;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub var a: c_long = @bitCast(c_long, @as(c_long, @as(c_int, 2)));
|
||||
\\pub var b: c_long = @bitCast(c_long, @as(c_long, @as(c_int, 2)));
|
||||
\\pub var a: c_long = 2;
|
||||
\\pub var b: c_long = 2;
|
||||
\\pub var c: c_int = 4;
|
||||
\\pub export fn foo(arg_c_1: u8) void {
|
||||
\\ var c_1 = arg_c_1;
|
||||
\\ var a_2: c_int = undefined;
|
||||
\\ var b_3: u8 = @bitCast(u8, @truncate(i8, @as(c_int, 123)));
|
||||
\\ var b_3: u8 = 123;
|
||||
\\ b_3 = @bitCast(u8, @truncate(i8, a_2));
|
||||
\\ {
|
||||
\\ var d: c_int = 5;
|
||||
@ -1838,7 +1838,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ };
|
||||
\\ }
|
||||
\\ }
|
||||
\\ var i: u8 = @bitCast(u8, @truncate(i8, @as(c_int, 2)));
|
||||
\\ var i: u8 = 2;
|
||||
\\}
|
||||
});
|
||||
|
||||
@ -1846,7 +1846,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\unsigned anyerror = 2;
|
||||
\\#define noreturn _Noreturn
|
||||
, &[_][]const u8{
|
||||
\\pub export var anyerror_1: c_uint = @bitCast(c_uint, @as(c_int, 2));
|
||||
\\pub export var anyerror_1: c_uint = 2;
|
||||
,
|
||||
\\pub const noreturn_2 = @compileError("unable to translate C expr: unexpected token .Keyword_noreturn");
|
||||
});
|
||||
@ -1860,7 +1860,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub export var a: f32 = @floatCast(f32, 3.1415);
|
||||
\\pub export var b: f64 = 3.1415;
|
||||
\\pub export var c: c_int = @floatToInt(c_int, 3.1415);
|
||||
\\pub export var d: f64 = @intToFloat(f64, @as(c_int, 3));
|
||||
\\pub export var d: f64 = 3;
|
||||
});
|
||||
|
||||
cases.add("conditional operator",
|
||||
@ -2009,7 +2009,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
// TODO translate-c should in theory be able to figure out to drop all these casts
|
||||
cases.add("escape sequences",
|
||||
\\const char *escapes() {
|
||||
\\char a = '\'',
|
||||
@ -2028,17 +2027,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\
|
||||
, &[_][]const u8{
|
||||
\\pub export fn escapes() [*c]const u8 {
|
||||
\\ var a: u8 = @bitCast(u8, @truncate(i8, @as(c_int, '\'')));
|
||||
\\ var b: u8 = @bitCast(u8, @truncate(i8, @as(c_int, '\\')));
|
||||
\\ var c: u8 = @bitCast(u8, @truncate(i8, @as(c_int, '\x07')));
|
||||
\\ var d: u8 = @bitCast(u8, @truncate(i8, @as(c_int, '\x08')));
|
||||
\\ var e: u8 = @bitCast(u8, @truncate(i8, @as(c_int, '\x0c')));
|
||||
\\ var f: u8 = @bitCast(u8, @truncate(i8, @as(c_int, '\n')));
|
||||
\\ var g: u8 = @bitCast(u8, @truncate(i8, @as(c_int, '\r')));
|
||||
\\ var h: u8 = @bitCast(u8, @truncate(i8, @as(c_int, '\t')));
|
||||
\\ var i: u8 = @bitCast(u8, @truncate(i8, @as(c_int, '\x0b')));
|
||||
\\ var j: u8 = @bitCast(u8, @truncate(i8, @as(c_int, '\x00')));
|
||||
\\ var k: u8 = @bitCast(u8, @truncate(i8, @as(c_int, '\"')));
|
||||
\\ var a: u8 = '\'';
|
||||
\\ var b: u8 = '\\';
|
||||
\\ var c: u8 = '\x07';
|
||||
\\ var d: u8 = '\x08';
|
||||
\\ var e: u8 = '\x0c';
|
||||
\\ var f: u8 = '\n';
|
||||
\\ var g: u8 = '\r';
|
||||
\\ var h: u8 = '\t';
|
||||
\\ var i: u8 = '\x0b';
|
||||
\\ var j: u8 = '\x00';
|
||||
\\ var k: u8 = '\"';
|
||||
\\ return "\'\\\x07\x08\x0c\n\r\t\x0b\x00\"";
|
||||
\\}
|
||||
});
|
||||
@ -2308,8 +2307,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() void {
|
||||
\\ var a: [10]c_longlong = undefined;
|
||||
\\ var i: c_longlong = @bitCast(c_longlong, @as(c_longlong, @as(c_int, 0)));
|
||||
\\ a[@intCast(usize, i)] = @bitCast(c_longlong, @as(c_longlong, @as(c_int, 0)));
|
||||
\\ var i: c_longlong = 0;
|
||||
\\ a[@intCast(usize, i)] = 0;
|
||||
\\}
|
||||
});
|
||||
|
||||
@ -2321,8 +2320,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() void {
|
||||
\\ var a: [10]c_uint = undefined;
|
||||
\\ var i: c_uint = @bitCast(c_uint, @as(c_int, 0));
|
||||
\\ a[i] = @bitCast(c_uint, @as(c_int, 0));
|
||||
\\ var i: c_uint = 0;
|
||||
\\ a[i] = 0;
|
||||
\\}
|
||||
});
|
||||
|
||||
@ -2527,7 +2526,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() void {
|
||||
\\ var i: c_int = 0;
|
||||
\\ var u: c_uint = @bitCast(c_uint, @as(c_int, 0));
|
||||
\\ var u: c_uint = 0;
|
||||
\\ i += 1;
|
||||
\\ i -= 1;
|
||||
\\ u +%= 1;
|
||||
@ -2614,7 +2613,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() void {
|
||||
\\ var a: c_int = 0;
|
||||
\\ var b: c_uint = @bitCast(c_uint, @as(c_int, 0));
|
||||
\\ var b: c_uint = 0;
|
||||
\\ a += blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* += @as(c_int, 1);
|
||||
@ -2692,7 +2691,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() void {
|
||||
\\ var a: c_uint = @bitCast(c_uint, @as(c_int, 0));
|
||||
\\ var a: c_uint = 0;
|
||||
\\ a +%= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* +%= @bitCast(c_uint, @as(c_int, 1));
|
||||
@ -2752,7 +2751,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() void {
|
||||
\\ var i: c_int = 0;
|
||||
\\ var u: c_uint = @bitCast(c_uint, @as(c_int, 0));
|
||||
\\ var u: c_uint = 0;
|
||||
\\ i += 1;
|
||||
\\ i -= 1;
|
||||
\\ u +%= 1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user