Merge pull request #7479 from ziglang/translate-c-ast

Make translate-c use intermediate AST
This commit is contained in:
Veikka Tuominen 2021-02-19 13:03:29 +02:00 committed by GitHub
commit d672c20b8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 4949 additions and 4064 deletions

View File

@ -577,6 +577,7 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/src/windows_sdk.zig"
"${CMAKE_SOURCE_DIR}/src/zir.zig"
"${CMAKE_SOURCE_DIR}/src/zir_sema.zig"
"${CMAKE_SOURCE_DIR}/src/translate_c/ast.zig"
)
if(MSVC)

View File

@ -3695,12 +3695,12 @@ test "zig fmt: hexadeciaml float literals with underscore separators" {
);
}
//test "zig fmt: C var args" {
// try testCanonical(
// \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
// \\
// );
//}
test "zig fmt: C var args" {
try testCanonical(
\\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
\\
);
}
//test "zig fmt: Only indent multiline string literals in function calls" {
// try testCanonical(

View File

@ -556,14 +556,11 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
.builtin_call_two, .builtin_call_two_comma => {
if (datas[node].lhs == 0) {
const params = [_]ast.Node.Index{};
return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);
return renderBuiltinCall(ais, tree, main_tokens[node], &.{}, space);
} else if (datas[node].rhs == 0) {
const params = [_]ast.Node.Index{datas[node].lhs};
return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);
return renderBuiltinCall(ais, tree, main_tokens[node], &.{datas[node].lhs}, space);
} else {
const params = [_]ast.Node.Index{ datas[node].lhs, datas[node].rhs };
return renderBuiltinCall(ais, tree, main_tokens[node], &params, space);
return renderBuiltinCall(ais, tree, main_tokens[node], &.{ datas[node].lhs, datas[node].rhs }, space);
}
},
.builtin_call, .builtin_call_comma => {
@ -1319,7 +1316,7 @@ fn renderFnProto(ais: *Ais, tree: ast.Tree, fn_proto: ast.full.FnProto, space: S
.r_paren => break,
.comma => {
try renderToken(ais, tree, last_param_token, .space); // ,
last_param_token += 1;
continue;
},
else => {}, // Parameter type without a name.
}

View File

@ -1334,7 +1334,7 @@ pub fn update(self: *Compilation) !void {
self.c_object_work_queue.writeItemAssumeCapacity(entry.key);
}
const use_stage1 = build_options.is_stage1 and self.bin_file.options.use_llvm;
const use_stage1 = build_options.omit_stage2 or build_options.is_stage1 and self.bin_file.options.use_llvm;
if (!use_stage1) {
if (self.bin_file.options.module) |module| {
module.compile_log_text.shrinkAndFree(module.gpa, 0);

View File

@ -2935,8 +2935,11 @@ fn identifier(
return mod.failNode(scope, ident, "TODO implement '_' identifier", .{});
}
if (getSimplePrimitiveValue(ident_name)) |typed_value| {
const result = try addZIRInstConst(mod, scope, src, typed_value);
if (simple_types.get(ident_name)) |val_tag| {
const result = try addZIRInstConst(mod, scope, src, TypedValue{
.ty = Type.initTag(.type),
.val = Value.initTag(val_tag),
});
return rvalue(mod, scope, rl, result);
}
@ -3617,42 +3620,33 @@ fn callExpr(
return rvalue(mod, scope, rl, result);
}
fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {
const simple_types = std.ComptimeStringMap(Value.Tag, .{
.{ "u8", .u8_type },
.{ "i8", .i8_type },
.{ "isize", .isize_type },
.{ "usize", .usize_type },
.{ "c_short", .c_short_type },
.{ "c_ushort", .c_ushort_type },
.{ "c_int", .c_int_type },
.{ "c_uint", .c_uint_type },
.{ "c_long", .c_long_type },
.{ "c_ulong", .c_ulong_type },
.{ "c_longlong", .c_longlong_type },
.{ "c_ulonglong", .c_ulonglong_type },
.{ "c_longdouble", .c_longdouble_type },
.{ "f16", .f16_type },
.{ "f32", .f32_type },
.{ "f64", .f64_type },
.{ "f128", .f128_type },
.{ "c_void", .c_void_type },
.{ "bool", .bool_type },
.{ "void", .void_type },
.{ "type", .type_type },
.{ "anyerror", .anyerror_type },
.{ "comptime_int", .comptime_int_type },
.{ "comptime_float", .comptime_float_type },
.{ "noreturn", .noreturn_type },
});
if (simple_types.get(name)) |tag| {
return TypedValue{
.ty = Type.initTag(.type),
.val = Value.initTag(tag),
};
}
return null;
}
pub const simple_types = std.ComptimeStringMap(Value.Tag, .{
.{ "u8", .u8_type },
.{ "i8", .i8_type },
.{ "isize", .isize_type },
.{ "usize", .usize_type },
.{ "c_short", .c_short_type },
.{ "c_ushort", .c_ushort_type },
.{ "c_int", .c_int_type },
.{ "c_uint", .c_uint_type },
.{ "c_long", .c_long_type },
.{ "c_ulong", .c_ulong_type },
.{ "c_longlong", .c_longlong_type },
.{ "c_ulonglong", .c_ulonglong_type },
.{ "c_longdouble", .c_longdouble_type },
.{ "f16", .f16_type },
.{ "f32", .f32_type },
.{ "f64", .f64_type },
.{ "f128", .f128_type },
.{ "c_void", .c_void_type },
.{ "bool", .bool_type },
.{ "void", .void_type },
.{ "type", .type_type },
.{ "anyerror", .anyerror_type },
.{ "comptime_int", .comptime_int_type },
.{ "comptime_float", .comptime_float_type },
.{ "noreturn", .noreturn_type },
});
fn nodeMayNeedMemoryLocation(scope: *Scope, start_node: ast.Node.Index) bool {
const tree = scope.tree();

View File

@ -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 {
@ -270,12 +273,12 @@ pub const CompoundAssignOperator = opaque {
pub const CompoundStmt = opaque {
pub const body_begin = ZigClangCompoundStmt_body_begin;
extern fn ZigClangCompoundStmt_body_begin(*const CompoundStmt) const_body_iterator;
extern fn ZigClangCompoundStmt_body_begin(*const CompoundStmt) ConstBodyIterator;
pub const body_end = ZigClangCompoundStmt_body_end;
extern fn ZigClangCompoundStmt_body_end(*const CompoundStmt) const_body_iterator;
extern fn ZigClangCompoundStmt_body_end(*const CompoundStmt) ConstBodyIterator;
pub const const_body_iterator = [*]const *Stmt;
pub const ConstBodyIterator = [*]const *Stmt;
};
pub const ConditionalOperator = 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;
};

File diff suppressed because it is too large Load Diff

2531
src/translate_c/ast.zig Normal file

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -357,6 +359,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -506,6 +510,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -772,6 +778,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -868,6 +876,7 @@ pub const Type = extern union {
.i16, .u16 => return 2,
.i32, .u32 => return 4,
.i64, .u64 => return 8,
.u128, .i128 => return 16,
.isize,
.usize,
@ -1010,6 +1019,7 @@ pub const Type = extern union {
.i16, .u16 => return 2,
.i32, .u32 => return 4,
.i64, .u64 => return 8,
.u128, .i128 => return 16,
.@"anyframe", .anyframe_T, .isize, .usize => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
@ -1109,6 +1119,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -1191,6 +1203,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -1278,6 +1292,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -1359,6 +1375,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -1440,6 +1458,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -1522,6 +1542,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -1660,6 +1682,8 @@ pub const Type = extern union {
.i32 => unreachable,
.u64 => unreachable,
.i64 => unreachable,
.u128 => unreachable,
.i128 => unreachable,
.usize => unreachable,
.isize => unreachable,
.c_short => unreachable,
@ -1776,6 +1800,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -1856,6 +1882,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -2009,6 +2037,8 @@ pub const Type = extern union {
.i16,
.i32,
.i64,
.u128,
.i128,
=> true,
};
}
@ -2061,6 +2091,8 @@ pub const Type = extern union {
.i16,
.i32,
.i64,
.u128,
.i128,
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
@ -2167,6 +2199,8 @@ pub const Type = extern union {
.i32 => .{ .signedness = .signed, .bits = 32 },
.u64 => .{ .signedness = .unsigned, .bits = 64 },
.i64 => .{ .signedness = .signed, .bits = 64 },
.u128 => .{ .signedness = .unsigned, .bits = 128 },
.i128 => .{ .signedness = .signed, .bits = 128 },
.usize => .{ .signedness = .unsigned, .bits = target.cpu.arch.ptrBitWidth() },
.isize => .{ .signedness = .signed, .bits = target.cpu.arch.ptrBitWidth() },
.c_short => .{ .signedness = .signed, .bits = CType.short.sizeInBits(target) },
@ -2227,6 +2261,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.optional,
.optional_single_mut_pointer,
.optional_single_const_pointer,
@ -2333,6 +2369,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -2417,6 +2455,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -2500,6 +2540,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -2583,6 +2625,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -2663,6 +2707,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -2743,6 +2789,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -2793,6 +2841,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -2874,6 +2924,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -2971,6 +3023,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -3060,6 +3114,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -3193,6 +3249,8 @@ pub const Type = extern union {
i32,
u64,
i64,
u128,
i128,
usize,
isize,
c_short,
@ -3277,6 +3335,8 @@ pub const Type = extern union {
.i32,
.u64,
.i64,
.u128,
.i128,
.usize,
.isize,
.c_short,
@ -3352,6 +3412,11 @@ pub const Type = extern union {
};
}
pub fn init(comptime t: Tag) Type {
comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);
return .{ .tag_if_small_enough = @enumToInt(t) };
}
pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Type {
const ptr = try ally.create(t.Type());
ptr.* = .{

View File

@ -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);

View File

@ -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);

View File

@ -3,6 +3,14 @@ const tests = @import("tests.zig");
const nl = std.cstr.line_sep;
pub fn addCases(cases: *tests.RunTranslatedCContext) void {
cases.add("failed macros are only declared once",
\\#define FOO =
\\#define FOO =
\\#define PtrToPtr64(p) ((void *POINTER_64) p)
\\#define STRUC_ALIGNED_STACK_COPY(t,s) ((CONST t *)(s))
\\int main(void) {}
, "");
cases.add("parenthesized string literal",
\\void foo(const char *s) {}
\\int main(void) {
@ -922,4 +930,13 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
\\ return 0;
\\}
, "");
cases.add("Use correct break label for statement expression in nested scope",
\\#include <stdlib.h>
\\int main(void) {
\\ int x = ({1, ({2; 3;});});
\\ if (x != 3) abort();
\\ return 0;
\\}
, "");
}

File diff suppressed because it is too large Load Diff