mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
Merge pull request #6883 from Vexu/translate-c
translate-c: correctly handle pointers to opaque demoted structs
This commit is contained in:
commit
9ca9819488
@ -91,7 +91,7 @@ fn genArray(file: *C, decl: *Decl) !void {
|
||||
if (tv.val.cast(Value.Payload.Bytes)) |payload|
|
||||
if (tv.ty.sentinel()) |sentinel|
|
||||
if (sentinel.toUnsignedInt() == 0)
|
||||
// TODO: static by default
|
||||
// TODO: static by default
|
||||
try file.constants.writer().print("const char *const {} = \"{}\";\n", .{ name, payload.data })
|
||||
else
|
||||
return file.fail(decl.src(), "TODO byte arrays with non-zero sentinels", .{})
|
||||
|
||||
@ -19,8 +19,6 @@ pub const Error = error{OutOfMemory};
|
||||
const TypeError = Error || error{UnsupportedType};
|
||||
const TransError = TypeError || error{UnsupportedTranslation};
|
||||
|
||||
const DeclTable = std.AutoArrayHashMap(usize, []const u8);
|
||||
|
||||
const SymbolTable = std.StringArrayHashMap(*ast.Node);
|
||||
const AliasList = std.ArrayList(struct {
|
||||
alias: []const u8,
|
||||
@ -254,24 +252,25 @@ const Scope = struct {
|
||||
pub const Context = struct {
|
||||
gpa: *mem.Allocator,
|
||||
arena: *mem.Allocator,
|
||||
token_ids: std.ArrayListUnmanaged(Token.Id),
|
||||
token_locs: std.ArrayListUnmanaged(Token.Loc),
|
||||
errors: std.ArrayListUnmanaged(ast.Error),
|
||||
token_ids: std.ArrayListUnmanaged(Token.Id) = .{},
|
||||
token_locs: std.ArrayListUnmanaged(Token.Loc) = .{},
|
||||
errors: std.ArrayListUnmanaged(ast.Error) = .{},
|
||||
source_buffer: *std.ArrayList(u8),
|
||||
err: Error,
|
||||
source_manager: *clang.SourceManager,
|
||||
decl_table: DeclTable,
|
||||
decl_table: std.AutoArrayHashMapUnmanaged(usize, []const u8) = .{},
|
||||
alias_list: AliasList,
|
||||
global_scope: *Scope.Root,
|
||||
clang_context: *clang.ASTContext,
|
||||
mangle_count: u32 = 0,
|
||||
root_decls: std.ArrayListUnmanaged(*ast.Node),
|
||||
root_decls: std.ArrayListUnmanaged(*ast.Node) = .{},
|
||||
opaque_demotes: std.AutoHashMapUnmanaged(usize, void) = .{},
|
||||
|
||||
/// This one is different than the root scope's name table. This contains
|
||||
/// a list of names that we found by visiting all the top level decls without
|
||||
/// translating them. The other maps are updated as we translate; this one is updated
|
||||
/// up front in a pre-processing step.
|
||||
global_names: std.StringArrayHashMap(void),
|
||||
global_names: std.StringArrayHashMapUnmanaged(void) = .{},
|
||||
|
||||
fn getMangle(c: *Context) u32 {
|
||||
c.mangle_count += 1;
|
||||
@ -362,24 +361,21 @@ pub fn translate(
|
||||
.source_buffer = &source_buffer,
|
||||
.source_manager = ast_unit.getSourceManager(),
|
||||
.err = undefined,
|
||||
.decl_table = DeclTable.init(gpa),
|
||||
.alias_list = AliasList.init(gpa),
|
||||
.global_scope = try arena.allocator.create(Scope.Root),
|
||||
.clang_context = ast_unit.getASTContext(),
|
||||
.global_names = std.StringArrayHashMap(void).init(gpa),
|
||||
.token_ids = .{},
|
||||
.token_locs = .{},
|
||||
.errors = .{},
|
||||
.root_decls = .{},
|
||||
};
|
||||
context.global_scope.* = Scope.Root.init(&context);
|
||||
defer context.decl_table.deinit();
|
||||
defer context.alias_list.deinit();
|
||||
defer context.token_ids.deinit(gpa);
|
||||
defer context.token_locs.deinit(gpa);
|
||||
defer context.errors.deinit(gpa);
|
||||
defer context.global_names.deinit();
|
||||
defer context.root_decls.deinit(gpa);
|
||||
defer {
|
||||
context.decl_table.deinit(gpa);
|
||||
context.alias_list.deinit();
|
||||
context.token_ids.deinit(gpa);
|
||||
context.token_locs.deinit(gpa);
|
||||
context.errors.deinit(gpa);
|
||||
context.global_names.deinit(gpa);
|
||||
context.root_decls.deinit(gpa);
|
||||
context.opaque_demotes.deinit(gpa);
|
||||
}
|
||||
|
||||
try prepopulateGlobalNameTable(ast_unit, &context);
|
||||
|
||||
@ -437,7 +433,7 @@ fn prepopulateGlobalNameTable(ast_unit: *clang.ASTUnit, c: *Context) !void {
|
||||
const macro = @ptrCast(*clang.MacroDefinitionRecord, entity);
|
||||
const raw_name = macro.getName_getNameStart();
|
||||
const name = try c.str(raw_name);
|
||||
_ = try c.global_names.put(name, {});
|
||||
_ = try c.global_names.put(c.gpa, name, {});
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
@ -465,7 +461,7 @@ fn declVisitorC(context: ?*c_void, decl: *const clang.Decl) callconv(.C) bool {
|
||||
fn declVisitorNamesOnly(c: *Context, decl: *const clang.Decl) Error!void {
|
||||
if (decl.castToNamedDecl()) |named_decl| {
|
||||
const decl_name = try c.str(named_decl.getName_bytes_begin());
|
||||
_ = try c.global_names.put(decl_name, {});
|
||||
_ = try c.global_names.put(c.gpa, decl_name, {});
|
||||
}
|
||||
}
|
||||
|
||||
@ -804,7 +800,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
|
||||
}
|
||||
|
||||
fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const clang.TypedefNameDecl, builtin_name: []const u8) !*ast.Node {
|
||||
_ = try c.decl_table.put(@ptrToInt(typedef_decl.getCanonicalDecl()), builtin_name);
|
||||
_ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin_name);
|
||||
return transCreateNodeIdentifier(c, builtin_name);
|
||||
}
|
||||
|
||||
@ -851,7 +847,7 @@ fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_lev
|
||||
return transCreateNodeIdentifier(c, checked_name);
|
||||
}
|
||||
|
||||
_ = try c.decl_table.put(@ptrToInt(typedef_decl.getCanonicalDecl()), checked_name);
|
||||
_ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), checked_name);
|
||||
const node = (try transCreateNodeTypedef(rp, typedef_decl, true, checked_name)) orelse return null;
|
||||
try addTopLevelDecl(c, checked_name, node);
|
||||
return transCreateNodeIdentifier(c, checked_name);
|
||||
@ -918,7 +914,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
|
||||
}
|
||||
|
||||
const name = try std.fmt.allocPrint(c.arena, "{}_{}", .{ container_kind_name, bare_name });
|
||||
_ = try c.decl_table.put(@ptrToInt(record_decl.getCanonicalDecl()), name);
|
||||
_ = try c.decl_table.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), name);
|
||||
|
||||
const visib_tok = if (!is_unnamed) try appendToken(c, .Keyword_pub, "pub") else null;
|
||||
const mut_tok = try appendToken(c, .Keyword_const, "const");
|
||||
@ -930,6 +926,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
|
||||
const init_node = blk: {
|
||||
const rp = makeRestorePoint(c);
|
||||
const record_def = record_decl.getDefinition() orelse {
|
||||
_ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
|
||||
const opaque_type = try transCreateNodeOpaqueType(c);
|
||||
semicolon = try appendToken(c, .Semicolon, ";");
|
||||
break :blk opaque_type;
|
||||
@ -954,6 +951,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
|
||||
const field_qt = field_decl.getType();
|
||||
|
||||
if (field_decl.isBitField()) {
|
||||
_ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
|
||||
const opaque_type = try transCreateNodeOpaqueType(c);
|
||||
semicolon = try appendToken(c, .Semicolon, ";");
|
||||
try emitWarning(c, field_loc, "{} demoted to opaque type - has bitfield", .{container_kind_name});
|
||||
@ -961,6 +959,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
|
||||
}
|
||||
|
||||
if (qualTypeCanon(field_qt).isIncompleteOrZeroLengthArrayType(c.clang_context)) {
|
||||
_ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
|
||||
const opaque_type = try transCreateNodeOpaqueType(c);
|
||||
semicolon = try appendToken(c, .Semicolon, ";");
|
||||
try emitWarning(c, field_loc, "{} demoted to opaque type - has variable length array", .{container_kind_name});
|
||||
@ -979,6 +978,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
|
||||
_ = try appendToken(c, .Colon, ":");
|
||||
const field_type = transQualType(rp, field_qt, field_loc) catch |err| switch (err) {
|
||||
error.UnsupportedType => {
|
||||
_ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
|
||||
const opaque_type = try transCreateNodeOpaqueType(c);
|
||||
semicolon = try appendToken(c, .Semicolon, ";");
|
||||
try emitWarning(c, record_loc, "{} demoted to opaque type - unable to translate type of field {}", .{ container_kind_name, raw_name });
|
||||
@ -988,13 +988,13 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
|
||||
};
|
||||
|
||||
const align_expr = blk_2: {
|
||||
const alignment = field_decl.getAlignedAttribute(rp.c.clang_context);
|
||||
const alignment = field_decl.getAlignedAttribute(c.clang_context);
|
||||
if (alignment != 0) {
|
||||
_ = try appendToken(rp.c, .Keyword_align, "align");
|
||||
_ = try appendToken(rp.c, .LParen, "(");
|
||||
_ = try appendToken(c, .Keyword_align, "align");
|
||||
_ = try appendToken(c, .LParen, "(");
|
||||
// Clang reports the alignment in bits
|
||||
const expr = try transCreateNodeInt(rp.c, alignment / 8);
|
||||
_ = try appendToken(rp.c, .RParen, ")");
|
||||
const expr = try transCreateNodeInt(c, alignment / 8);
|
||||
_ = try appendToken(c, .RParen, ")");
|
||||
|
||||
break :blk_2 expr;
|
||||
}
|
||||
@ -1013,6 +1013,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?*as
|
||||
|
||||
if (is_anon) {
|
||||
_ = try c.decl_table.put(
|
||||
c.gpa,
|
||||
@ptrToInt(field_decl.getCanonicalDecl()),
|
||||
raw_name,
|
||||
);
|
||||
@ -1065,7 +1066,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node
|
||||
}
|
||||
|
||||
const name = try std.fmt.allocPrint(c.arena, "enum_{}", .{bare_name});
|
||||
_ = try c.decl_table.put(@ptrToInt(enum_decl.getCanonicalDecl()), name);
|
||||
_ = try c.decl_table.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), name);
|
||||
|
||||
const visib_tok = if (!is_unnamed) try appendToken(c, .Keyword_pub, "pub") else null;
|
||||
const mut_tok = try appendToken(c, .Keyword_const, "const");
|
||||
@ -1204,8 +1205,10 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?*ast.Node
|
||||
};
|
||||
mem.copy(*ast.Node, container_node.fieldsAndDecls(), fields_and_decls.items);
|
||||
break :blk &container_node.base;
|
||||
} else
|
||||
try transCreateNodeOpaqueType(c);
|
||||
} else blk: {
|
||||
_ = try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {});
|
||||
break :blk try transCreateNodeOpaqueType(c);
|
||||
};
|
||||
|
||||
const semicolon_token = try appendToken(c, .Semicolon, ";");
|
||||
const node = try ast.Node.VarDecl.create(c.arena, .{
|
||||
@ -4767,7 +4770,7 @@ fn transType(rp: RestorePoint, ty: *const clang.Type, source_loc: clang.SourceLo
|
||||
optional_node.rhs = try transQualType(rp, child_qt, source_loc);
|
||||
return &optional_node.base;
|
||||
}
|
||||
if (typeIsOpaque(rp.c, child_qt.getTypePtr(), source_loc)) {
|
||||
if (typeIsOpaque(rp.c, child_qt.getTypePtr(), source_loc) or qualTypeWasDemotedToOpaque(rp.c, child_qt)) {
|
||||
const optional_node = try transCreateNodeSimplePrefixOp(rp.c, .OptionalType, .QuestionMark, "?");
|
||||
const pointer_node = try transCreateNodePtrType(
|
||||
rp.c,
|
||||
@ -4853,6 +4856,50 @@ fn transType(rp: RestorePoint, ty: *const clang.Type, source_loc: clang.SourceLo
|
||||
}
|
||||
}
|
||||
|
||||
fn qualTypeWasDemotedToOpaque(c: *Context, qt: clang.QualType) bool {
|
||||
const ty = qt.getTypePtr();
|
||||
switch (qt.getTypeClass()) {
|
||||
.Typedef => {
|
||||
const typedef_ty = @ptrCast(*const clang.TypedefType, ty);
|
||||
|
||||
const typedef_decl = typedef_ty.getDecl();
|
||||
const underlying_type = typedef_decl.getUnderlyingType();
|
||||
return qualTypeWasDemotedToOpaque(c, underlying_type);
|
||||
},
|
||||
.Record => {
|
||||
const record_ty = @ptrCast(*const clang.RecordType, ty);
|
||||
|
||||
const record_decl = record_ty.getDecl();
|
||||
const canonical = @ptrToInt(record_decl.getCanonicalDecl());
|
||||
return c.opaque_demotes.contains(canonical);
|
||||
},
|
||||
.Enum => {
|
||||
const enum_ty = @ptrCast(*const clang.EnumType, ty);
|
||||
|
||||
const enum_decl = enum_ty.getDecl();
|
||||
const canonical = @ptrToInt(enum_decl.getCanonicalDecl());
|
||||
return c.opaque_demotes.contains(canonical);
|
||||
},
|
||||
.Elaborated => {
|
||||
const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty);
|
||||
return qualTypeWasDemotedToOpaque(c, elaborated_ty.getNamedType());
|
||||
},
|
||||
.Decayed => {
|
||||
const decayed_ty = @ptrCast(*const clang.DecayedType, ty);
|
||||
return qualTypeWasDemotedToOpaque(c, decayed_ty.getDecayedType());
|
||||
},
|
||||
.Attributed => {
|
||||
const attributed_ty = @ptrCast(*const clang.AttributedType, ty);
|
||||
return qualTypeWasDemotedToOpaque(c, attributed_ty.getEquivalentType());
|
||||
},
|
||||
.MacroQualified => {
|
||||
const macroqualified_ty = @ptrCast(*const clang.MacroQualifiedType, ty);
|
||||
return qualTypeWasDemotedToOpaque(c, macroqualified_ty.getModifiedType());
|
||||
},
|
||||
else => return false,
|
||||
}
|
||||
}
|
||||
|
||||
fn isCVoid(qt: clang.QualType) bool {
|
||||
const ty = qt.getTypePtr();
|
||||
if (ty.getTypeClass() == .Builtin) {
|
||||
|
||||
@ -10,7 +10,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\ B = 1,
|
||||
\\ C = 2
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\void entry(enum Foo foo);
|
||||
});
|
||||
|
||||
@ -33,7 +33,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\ uint64_t E;
|
||||
\\ uint64_t F;
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\void entry(struct Foo foo);
|
||||
\\
|
||||
});
|
||||
@ -68,7 +68,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\ bool C;
|
||||
\\ struct Big D;
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\void entry(union Foo foo);
|
||||
\\
|
||||
});
|
||||
@ -79,7 +79,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\export fn entry(foo: ?*Foo) void { }
|
||||
, &[_][]const u8{
|
||||
\\struct Foo;
|
||||
,
|
||||
,
|
||||
\\void entry(struct Foo * foo);
|
||||
});
|
||||
|
||||
@ -94,7 +94,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\ int32_t A[2];
|
||||
\\ uint32_t * B[4];
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\void entry(struct Foo foo, uint8_t bar[]);
|
||||
\\
|
||||
});
|
||||
@ -109,7 +109,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\struct S;
|
||||
,
|
||||
,
|
||||
\\uint8_t a(struct S * s);
|
||||
\\
|
||||
});
|
||||
@ -125,7 +125,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\union U;
|
||||
,
|
||||
,
|
||||
\\uint8_t a(union U * s);
|
||||
\\
|
||||
});
|
||||
@ -141,7 +141,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\enum E;
|
||||
,
|
||||
,
|
||||
\\uint8_t a(enum E * s);
|
||||
\\
|
||||
});
|
||||
|
||||
@ -156,7 +156,7 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\ %0 = call(@a, [])
|
||||
\\ %1 = returnvoid()
|
||||
\\})
|
||||
,
|
||||
,
|
||||
&[_][]const u8{
|
||||
":18:21: error: message",
|
||||
},
|
||||
|
||||
@ -3,6 +3,26 @@ const std = @import("std");
|
||||
const CrossTarget = std.zig.CrossTarget;
|
||||
|
||||
pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("pointer to opaque demoted struct",
|
||||
\\typedef struct {
|
||||
\\ _Atomic int foo;
|
||||
\\} Foo;
|
||||
\\
|
||||
\\typedef struct {
|
||||
\\ Foo *bar;
|
||||
\\} Bar;
|
||||
, &[_][]const u8{
|
||||
\\const struct_unnamed_1 = //
|
||||
,
|
||||
\\warning: unsupported type: 'Atomic'
|
||||
\\ opaque {}; //
|
||||
,
|
||||
\\pub const Foo = struct_unnamed_1;
|
||||
\\const struct_unnamed_2 = extern struct {
|
||||
\\ bar: ?*Foo,
|
||||
\\};
|
||||
});
|
||||
|
||||
cases.add("macro expressions respect C operator precedence",
|
||||
\\#define FOO *((foo) + 2)
|
||||
\\#define VALUE (1 + 2 * 3 + 4 * 5 + 6 << 7 | 8 == 9)
|
||||
@ -11,9 +31,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ | (*((unsigned char *)(p) + 2) << 16))
|
||||
, &[_][]const u8{
|
||||
\\pub const FOO = (foo + 2).*;
|
||||
,
|
||||
,
|
||||
\\pub const VALUE = ((((1 + (2 * 3)) + (4 * 5)) + 6) << 7) | @boolToInt(8 == 9);
|
||||
,
|
||||
,
|
||||
\\pub inline fn _AL_READ3BYTES(p: anytype) @TypeOf(((@import("std").meta.cast([*c]u8, p)).* | (((@import("std").meta.cast([*c]u8, p)) + 1).* << 8)) | (((@import("std").meta.cast([*c]u8, p)) + 2).* << 16)) {
|
||||
\\ return ((@import("std").meta.cast([*c]u8, p)).* | (((@import("std").meta.cast([*c]u8, p)) + 1).* << 8)) | (((@import("std").meta.cast([*c]u8, p)) + 2).* << 16);
|
||||
\\}
|
||||
@ -81,11 +101,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ a: u8,
|
||||
\\};
|
||||
\\pub const Color = struct_Color;
|
||||
,
|
||||
,
|
||||
\\pub inline fn CLITERAL(type_1: anytype) @TypeOf(type_1) {
|
||||
\\ return type_1;
|
||||
\\}
|
||||
,
|
||||
,
|
||||
\\pub const LIGHTGRAY = @import("std").mem.zeroInit(CLITERAL(Color), .{ 200, 200, 200, 255 });
|
||||
});
|
||||
|
||||
@ -119,7 +139,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub inline fn FOO(x: anytype) @TypeOf(@boolToInt(x >= 0) + @boolToInt(x >= 0)) {
|
||||
\\ return @boolToInt(x >= 0) + @boolToInt(x >= 0);
|
||||
\\}
|
||||
,
|
||||
,
|
||||
\\pub const BAR = (1 != 0) and (2 > 4);
|
||||
});
|
||||
|
||||
@ -138,7 +158,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\struct bar { int x; int y[0]; };
|
||||
, &[_][]const u8{
|
||||
\\pub const struct_foo = opaque {};
|
||||
,
|
||||
,
|
||||
\\pub const struct_bar = opaque {};
|
||||
});
|
||||
|
||||
@ -166,7 +186,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ _ = foo;
|
||||
\\ break :blk bar;
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\pub inline fn bar(x: anytype) @TypeOf(baz(1, 2)) {
|
||||
\\ return blk: {
|
||||
\\ _ = &x;
|
||||
@ -185,7 +205,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define inline 2
|
||||
, &[_][]const u8{
|
||||
\\pub const foo = 1;
|
||||
,
|
||||
,
|
||||
\\pub const @"inline" = 2;
|
||||
});
|
||||
|
||||
@ -205,12 +225,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const struct_arcan_shmif_page = //
|
||||
,
|
||||
,
|
||||
\\warning: unsupported type: 'Atomic'
|
||||
\\ opaque {}; //
|
||||
,
|
||||
,
|
||||
\\ warning: struct demoted to opaque type - unable to translate type of field abufused
|
||||
, // TODO should be `addr: *struct_arcan_shmif_page`
|
||||
, // TODO should be `addr: *struct_arcan_shmif_page`
|
||||
\\pub const struct_arcan_shmif_cont = extern struct {
|
||||
\\ addr: [*c]struct_arcan_shmif_page,
|
||||
\\};
|
||||
@ -529,7 +549,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\Foo fun(Foo *a);
|
||||
, &[_][]const u8{
|
||||
\\pub const Foo = c_void;
|
||||
,
|
||||
,
|
||||
\\pub extern fn fun(a: ?*Foo) Foo;
|
||||
});
|
||||
|
||||
@ -629,7 +649,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const struct_Foo = opaque {};
|
||||
,
|
||||
,
|
||||
\\pub const struct_Bar = extern struct {
|
||||
\\ foo: ?*struct_Foo,
|
||||
\\};
|
||||
@ -646,7 +666,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#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;
|
||||
});
|
||||
|
||||
@ -665,13 +685,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub const struct_Foo = extern struct {
|
||||
\\ a: [*c]Foo,
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\pub const Foo = struct_Foo;
|
||||
,
|
||||
,
|
||||
\\pub const struct_Bar = extern struct {
|
||||
\\ a: [*c]Foo,
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\pub const Bar = struct_Bar;
|
||||
});
|
||||
|
||||
@ -685,7 +705,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ x: c_int,
|
||||
\\ y: [*c]u8,
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\pub const Foo = struct_Foo;
|
||||
});
|
||||
|
||||
@ -697,7 +717,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub const struct_Foo = extern struct {
|
||||
\\ derp: ?fn ([*c]struct_Foo) callconv(.C) void,
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\pub const Foo = struct_Foo;
|
||||
});
|
||||
|
||||
@ -706,9 +726,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\struct Foo *some_func(struct Foo *foo, int x);
|
||||
, &[_][]const u8{
|
||||
\\pub const struct_Foo = opaque {};
|
||||
,
|
||||
,
|
||||
\\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;
|
||||
,
|
||||
,
|
||||
\\pub const Foo = struct_Foo;
|
||||
});
|
||||
|
||||
@ -723,7 +743,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define THING1 1234
|
||||
, &[_][]const u8{
|
||||
\\pub const THING1 = 1234;
|
||||
,
|
||||
,
|
||||
\\pub const THING2 = THING1;
|
||||
});
|
||||
|
||||
@ -741,7 +761,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub const struct_Bar = extern struct {
|
||||
\\ next: [*c]struct_Foo,
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\pub const struct_Foo = extern struct {
|
||||
\\ next: [*c]struct_Bar,
|
||||
\\};
|
||||
@ -761,7 +781,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub const struct_comptime = extern struct {
|
||||
\\ @"defer": c_int,
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\pub const @"comptime" = struct_comptime;
|
||||
});
|
||||
|
||||
@ -1003,7 +1023,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ x: c_int,
|
||||
\\ y: f64,
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\pub const Foo = union_Foo;
|
||||
});
|
||||
|
||||
@ -1446,7 +1466,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ p,
|
||||
\\ _,
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\pub const Baz = struct_Baz;
|
||||
});
|
||||
|
||||
@ -1512,13 +1532,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define bar fn_ptr2
|
||||
, &[_][]const u8{
|
||||
\\pub extern var fn_ptr: ?fn () callconv(.C) void;
|
||||
,
|
||||
,
|
||||
\\pub inline fn foo() void {
|
||||
\\ return fn_ptr.?();
|
||||
\\}
|
||||
,
|
||||
,
|
||||
\\pub extern var fn_ptr2: ?fn (c_int, f32) callconv(.C) u8;
|
||||
,
|
||||
,
|
||||
\\pub inline fn bar(arg_1: c_int, arg_2: f32) u8 {
|
||||
\\ return fn_ptr2.?(arg_1, arg_2);
|
||||
\\}
|
||||
@ -1549,13 +1569,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ gl: struct_unnamed_1,
|
||||
\\};
|
||||
\\pub extern var glProcs: union_OpenGLProcs;
|
||||
,
|
||||
,
|
||||
\\pub const glClearPFN = PFNGLCLEARPROC;
|
||||
,
|
||||
,
|
||||
\\pub inline fn glClearUnion(arg_2: GLbitfield) void {
|
||||
\\ return glProcs.gl.Clear.?(arg_2);
|
||||
\\}
|
||||
,
|
||||
,
|
||||
\\pub const OpenGLProcs = union_OpenGLProcs;
|
||||
});
|
||||
|
||||
@ -1571,11 +1591,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define FOO(L,b) (L + b)
|
||||
, &[_][]const u8{
|
||||
\\pub extern var c: c_int;
|
||||
,
|
||||
,
|
||||
\\pub inline fn BASIC(c_1: anytype) @TypeOf(c_1 * 2) {
|
||||
\\ return c_1 * 2;
|
||||
\\}
|
||||
,
|
||||
,
|
||||
\\pub inline fn FOO(L: anytype, b: anytype) @TypeOf(L + b) {
|
||||
\\ return L + b;
|
||||
\\}
|
||||
@ -1587,9 +1607,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define FOO_CHAR '\xfF'
|
||||
, &[_][]const u8{
|
||||
\\pub const FOO = "aoeu\xab derp";
|
||||
,
|
||||
,
|
||||
\\pub const FOO2 = "aoeu\x7a derp";
|
||||
,
|
||||
,
|
||||
\\pub const FOO_CHAR = '\xff';
|
||||
});
|
||||
|
||||
@ -1599,9 +1619,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#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);
|
||||
});
|
||||
|
||||
@ -1738,7 +1758,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub export var anyerror_1: c_uint = @bitCast(c_uint, @as(c_int, 2));
|
||||
,
|
||||
|
||||
\\pub const noreturn_2 = @compileError("unable to translate C expr: unexpected token .Keyword_noreturn");
|
||||
});
|
||||
|
||||
@ -2011,7 +2030,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ var p: c_int = @boolToInt(((c != null) and (td != 0)));
|
||||
\\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);
|
||||
\\}
|
||||
,
|
||||
,
|
||||
\\pub const Foo = enum_Foo;
|
||||
});
|
||||
|
||||
@ -2030,14 +2049,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ x: c_int,
|
||||
\\ y: c_int,
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\pub const enum_Bar = extern enum(c_int) {
|
||||
\\ A,
|
||||
\\ B,
|
||||
\\ _,
|
||||
\\};
|
||||
\\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void;
|
||||
,
|
||||
,
|
||||
\\pub const Foo = struct_Foo;
|
||||
\\pub const Bar = enum_Bar;
|
||||
});
|
||||
@ -2153,9 +2172,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ _ = a.b;
|
||||
\\ _ = c.*.b;
|
||||
\\}
|
||||
,
|
||||
,
|
||||
\\pub const DOT = a.b;
|
||||
,
|
||||
,
|
||||
\\pub const ARROW = a.*.b;
|
||||
});
|
||||
|
||||
@ -2171,7 +2190,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ var index = arg_index;
|
||||
\\ return array[@intCast(c_uint, index)];
|
||||
\\}
|
||||
,
|
||||
,
|
||||
\\pub const ACCESS = array[2];
|
||||
});
|
||||
|
||||
@ -2748,9 +2767,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define FOO_CHAR '\077'
|
||||
, &[_][]const u8{
|
||||
\\pub const FOO = "aoeu\x13 derp";
|
||||
,
|
||||
,
|
||||
\\pub const FOO2 = "aoeu\x134 derp";
|
||||
,
|
||||
,
|
||||
\\pub const FOO_CHAR = '\x3f';
|
||||
});
|
||||
|
||||
@ -2770,7 +2789,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ @"1" = 6,
|
||||
\\ _,
|
||||
\\};
|
||||
,
|
||||
,
|
||||
\\pub const Foo = enum_Foo;
|
||||
});
|
||||
|
||||
@ -2782,9 +2801,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub inline fn FOO(bar: anytype) @TypeOf(baz((@import("std").meta.cast(?*c_void, baz)))) {
|
||||
\\ return baz((@import("std").meta.cast(?*c_void, baz)));
|
||||
\\}
|
||||
,
|
||||
,
|
||||
\\pub const BAR = (@import("std").meta.cast(?*c_void, a));
|
||||
,
|
||||
,
|
||||
\\pub const BAZ = (@import("std").meta.cast(u32, 2));
|
||||
});
|
||||
|
||||
@ -2824,7 +2843,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub inline fn MIN(a: anytype, b: anytype) @TypeOf(if (b < a) b else a) {
|
||||
\\ return if (b < a) b else a;
|
||||
\\}
|
||||
,
|
||||
,
|
||||
\\pub inline fn MAX(a: anytype, b: anytype) @TypeOf(if (b > a) b else a) {
|
||||
\\ return if (b > a) b else a;
|
||||
\\}
|
||||
@ -2892,7 +2911,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ var bar_1 = arg_bar_1;
|
||||
\\ bar_1 = 2;
|
||||
\\}
|
||||
,
|
||||
,
|
||||
\\pub const bar = 4;
|
||||
});
|
||||
|
||||
@ -2964,9 +2983,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define BAZ "oh, " FOO
|
||||
, &[_][]const u8{
|
||||
\\pub const FOO = "hello";
|
||||
,
|
||||
,
|
||||
\\pub const BAR = FOO ++ " world";
|
||||
,
|
||||
,
|
||||
\\pub const BAZ = "oh, " ++ FOO;
|
||||
});
|
||||
|
||||
@ -2976,9 +2995,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define BAR FOO BAZ
|
||||
, &[_][]const u8{
|
||||
\\pub const FOO = "hello";
|
||||
,
|
||||
,
|
||||
\\pub const BAZ = " world";
|
||||
,
|
||||
,
|
||||
\\pub const BAR = FOO ++ BAZ;
|
||||
});
|
||||
|
||||
@ -2987,7 +3006,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define BAR FOO "c"
|
||||
, &[_][]const u8{
|
||||
\\pub const FOO = "a" ++ "b";
|
||||
,
|
||||
,
|
||||
\\pub const BAR = FOO ++ "c";
|
||||
});
|
||||
|
||||
@ -3023,7 +3042,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define FOO ((int)0x8000)
|
||||
, &[_][]const u8{
|
||||
\\pub const NULL = (@import("std").meta.cast(?*c_void, 0));
|
||||
,
|
||||
,
|
||||
\\pub const FOO = (@import("std").meta.cast(c_int, 0x8000));
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user