Translate anonymous union/struct
This commit is contained in:
parent
f83b02a581
commit
1dc25d7550
@ -760,6 +760,7 @@ pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTU
|
||||
pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) *const struct_ZigClangRecordDecl;
|
||||
pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) *const struct_ZigClangEnumDecl;
|
||||
pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl;
|
||||
pub extern fn ZigClangFieldDecl_getCanonicalDecl(field_decl: ?*const struct_ZigClangFieldDecl) ?*const struct_ZigClangFieldDecl;
|
||||
pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl;
|
||||
pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;
|
||||
pub extern fn ZigClangFunctionDecl_getCanonicalDecl(self: ?*const struct_ZigClangFunctionDecl) ?*const struct_ZigClangFunctionDecl;
|
||||
@ -1055,6 +1056,7 @@ pub extern fn ZigClangStringLiteral_getString_bytes_begin_size(*const ZigClangSt
|
||||
|
||||
pub extern fn ZigClangParenExpr_getSubExpr(*const ZigClangParenExpr) *const ZigClangExpr;
|
||||
|
||||
pub extern fn ZigClangFieldDecl_isAnonymousStructOrUnion(*const struct_ZigClangFieldDecl) bool;
|
||||
pub extern fn ZigClangFieldDecl_isBitField(*const struct_ZigClangFieldDecl) bool;
|
||||
pub extern fn ZigClangFieldDecl_getType(*const struct_ZigClangFieldDecl) struct_ZigClangQualType;
|
||||
pub extern fn ZigClangFieldDecl_getLocation(*const struct_ZigClangFieldDecl) struct_ZigClangSourceLocation;
|
||||
|
@ -759,8 +759,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
|
||||
try emitWarning(c, field_loc, "{} demoted to opaque type - has bitfield", .{container_kind_name});
|
||||
break :blk opaque;
|
||||
}
|
||||
const raw_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl)));
|
||||
if (raw_name.len < 1) continue; // fix weird windows bug?
|
||||
|
||||
var is_anon = false;
|
||||
var raw_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl)));
|
||||
if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl) or raw_name.len == 0) {
|
||||
raw_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()});
|
||||
is_anon = true;
|
||||
}
|
||||
const field_name = try appendIdentifier(c, raw_name);
|
||||
_ = try appendToken(c, .Colon, ":");
|
||||
const field_type = transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc) catch |err| switch (err) {
|
||||
@ -781,6 +786,13 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
|
||||
.align_expr = null,
|
||||
};
|
||||
|
||||
if (is_anon) {
|
||||
_ = try c.decl_table.put(
|
||||
@ptrToInt(ZigClangFieldDecl_getCanonicalDecl(field_decl)),
|
||||
raw_name,
|
||||
);
|
||||
}
|
||||
|
||||
try container_node.fields_and_decls.push(&field_node.base);
|
||||
_ = try appendToken(c, .Comma, ",");
|
||||
}
|
||||
@ -2417,10 +2429,22 @@ fn transMemberExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangMemberE
|
||||
container_node = try transCreateNodePtrDeref(rp.c, container_node);
|
||||
}
|
||||
|
||||
const name = try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, ZigClangMemberExpr_getMemberDecl(stmt))));
|
||||
if (name.len == 0) {
|
||||
return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)), "TODO access of anonymous field", .{});
|
||||
}
|
||||
const member_decl = ZigClangMemberExpr_getMemberDecl(stmt);
|
||||
const name = blk: {
|
||||
const decl_kind = ZigClangDecl_getKind(@ptrCast(*const ZigClangDecl, member_decl));
|
||||
// If we're referring to a anonymous struct/enum find the bogus name
|
||||
// we've assigned to it during the RecordDecl translation
|
||||
if (decl_kind == .Field) {
|
||||
const field_decl = @ptrCast(*const struct_ZigClangFieldDecl, member_decl);
|
||||
if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) {
|
||||
const name = rp.c.decl_table.get(@ptrToInt(ZigClangFieldDecl_getCanonicalDecl(field_decl))).?;
|
||||
break :blk try mem.dupe(rp.c.a(), u8, name.value);
|
||||
}
|
||||
}
|
||||
const decl = @ptrCast(*const ZigClangDecl, member_decl);
|
||||
break :blk try rp.c.str(ZigClangDecl_getName_bytes_begin(decl));
|
||||
};
|
||||
|
||||
const node = try transCreateNodeFieldAccess(rp.c, container_node, name);
|
||||
return maybeSuppressResult(rp, scope, result_used, node);
|
||||
}
|
||||
|
@ -1562,6 +1562,11 @@ const ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const ZigClangRecordD
|
||||
return reinterpret_cast<const ZigClangTagDecl *>(tag_decl);
|
||||
}
|
||||
|
||||
const ZigClangFieldDecl *ZigClangFieldDecl_getCanonicalDecl(const ZigClangFieldDecl *field_decl) {
|
||||
const clang::FieldDecl *canon_decl = reinterpret_cast<const clang::FieldDecl*>(field_decl)->getCanonicalDecl();
|
||||
return reinterpret_cast<const ZigClangFieldDecl *>(canon_decl);
|
||||
}
|
||||
|
||||
const ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const ZigClangEnumDecl *enum_decl) {
|
||||
const clang::TagDecl *tag_decl = reinterpret_cast<const clang::EnumDecl*>(enum_decl)->getCanonicalDecl();
|
||||
return reinterpret_cast<const ZigClangTagDecl *>(tag_decl);
|
||||
@ -2679,6 +2684,10 @@ bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *self) {
|
||||
return casted->isBitField();
|
||||
}
|
||||
|
||||
bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *field_decl) {
|
||||
return reinterpret_cast<const clang::FieldDecl*>(field_decl)->isAnonymousStructOrUnion();
|
||||
}
|
||||
|
||||
ZigClangSourceLocation ZigClangFieldDecl_getLocation(const struct ZigClangFieldDecl *self) {
|
||||
auto casted = reinterpret_cast<const clang::FieldDecl *>(self);
|
||||
return bitcast(casted->getLocation());
|
||||
|
@ -855,6 +855,7 @@ ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumType_getDecl(const struc
|
||||
|
||||
ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const struct ZigClangRecordDecl *record_decl);
|
||||
ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const struct ZigClangEnumDecl *);
|
||||
ZIG_EXTERN_C const struct ZigClangFieldDecl *ZigClangFieldDecl_getCanonicalDecl(const ZigClangFieldDecl *);
|
||||
ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *);
|
||||
ZIG_EXTERN_C const struct ZigClangFunctionDecl *ZigClangFunctionDecl_getCanonicalDecl(const ZigClangFunctionDecl *self);
|
||||
ZIG_EXTERN_C const struct ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *self);
|
||||
@ -1118,6 +1119,7 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSour
|
||||
ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSourceRange_getEnd(const struct ZigClangMacroDefinitionRecord *);
|
||||
|
||||
ZIG_EXTERN_C bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *);
|
||||
ZIG_EXTERN_C bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *);
|
||||
ZIG_EXTERN_C struct ZigClangQualType ZigClangFieldDecl_getType(const struct ZigClangFieldDecl *);
|
||||
ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFieldDecl_getLocation(const struct ZigClangFieldDecl *);
|
||||
|
||||
|
@ -8,6 +8,32 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub const VAL = 0xF00D;
|
||||
});
|
||||
|
||||
cases.add("anonymous struct & unions",
|
||||
\\typedef struct {
|
||||
\\ union {
|
||||
\\ char x;
|
||||
\\ struct { int y; };
|
||||
\\ };
|
||||
\\} outer;
|
||||
\\void foo(outer *x) { x->y = x->x; }
|
||||
, &[_][]const u8{
|
||||
\\const struct_unnamed_5 = extern struct {
|
||||
\\ y: c_int,
|
||||
\\};
|
||||
\\const union_unnamed_3 = extern union {
|
||||
\\ x: u8,
|
||||
\\ unnamed_4: struct_unnamed_5,
|
||||
\\};
|
||||
\\const struct_unnamed_1 = extern struct {
|
||||
\\ unnamed_2: union_unnamed_3,
|
||||
\\};
|
||||
\\pub const outer = struct_unnamed_1;
|
||||
\\pub export fn foo(arg_x: [*c]outer) void {
|
||||
\\ var x = arg_x;
|
||||
\\ x.*.unnamed_2.unnamed_4.y = @bitCast(c_int, @as(c_uint, x.*.unnamed_2.x));
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("union initializer",
|
||||
\\union { int x; char c[4]; }
|
||||
\\ ua = {1},
|
||||
|
Loading…
x
Reference in New Issue
Block a user