Skip to content

Instantly share code, notes, and snippets.

@LemonBoy
Created January 12, 2020 23:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LemonBoy/3e185207ab072fb52e0a8d6f1b75fbd2 to your computer and use it in GitHub Desktop.
Save LemonBoy/3e185207ab072fb52e0a8d6f1b75fbd2 to your computer and use it in GitHub Desktop.
diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig
index b98fa785d..ddd64a3ef 100644
--- a/src-self-hosted/clang.zig
+++ b/src-self-hosted/clang.zig
@@ -4,6 +4,7 @@ pub const struct_ZigClangAPInt = @OpaqueType();
pub const struct_ZigClangAPSInt = @OpaqueType();
pub const struct_ZigClangAPFloat = @OpaqueType();
pub const struct_ZigClangASTContext = @OpaqueType();
+pub const struct_ZigClangASTRecordLayout = @OpaqueType();
pub const struct_ZigClangASTUnit = @OpaqueType();
pub const struct_ZigClangArraySubscriptExpr = @OpaqueType();
pub const struct_ZigClangArrayType = @OpaqueType();
@@ -754,6 +755,10 @@ pub extern fn ZigClangSourceManager_getSpellingLineNumber(self: ?*const struct_Z
pub extern fn ZigClangSourceManager_getSpellingColumnNumber(self: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint;
pub extern fn ZigClangSourceManager_getCharacterData(self: ?*const struct_ZigClangSourceManager, SL: struct_ZigClangSourceLocation) [*:0]const u8;
pub extern fn ZigClangASTContext_getPointerType(self: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType;
+pub extern fn ZigClangASTContext_getASTRecordLayout(self: ?*const struct_ZigClangASTContext, D: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangASTRecordLayout;
+pub extern fn ZigClangASTContext_getTypeSize(self: ?*const struct_ZigClangASTContext, T: ?*const ZigClangType) u64;
+pub extern fn ZigClangASTRecordLayout_getFieldCount(self: ?*const struct_ZigClangASTRecordLayout) c_uint;
+pub extern fn ZigClangASTRecordLayout_getFieldOffset(self: ?*const struct_ZigClangASTRecordLayout, field_no: c_uint) u64;
pub extern fn ZigClangASTUnit_getASTContext(self: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext;
pub extern fn ZigClangASTUnit_getSourceManager(self: *struct_ZigClangASTUnit) *struct_ZigClangSourceManager;
pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?extern fn (?*c_void, *const struct_ZigClangDecl) bool) bool;
@@ -1054,6 +1059,8 @@ pub extern fn ZigClangStringLiteral_getString_bytes_begin_size(*const ZigClangSt
pub extern fn ZigClangParenExpr_getSubExpr(*const ZigClangParenExpr) *const ZigClangExpr;
pub extern fn ZigClangFieldDecl_isBitField(*const struct_ZigClangFieldDecl) bool;
+pub extern fn ZigClangFieldDecl_getFieldIndex(*const struct_ZigClangFieldDecl) c_uint;
+pub extern fn ZigClangFieldDecl_getBitWidthValue(*const struct_ZigClangFieldDecl, *const struct_ZigClangASTContext) c_uint;
pub extern fn ZigClangFieldDecl_getType(*const struct_ZigClangFieldDecl) struct_ZigClangQualType;
pub extern fn ZigClangFieldDecl_getLocation(*const struct_ZigClangFieldDecl) struct_ZigClangSourceLocation;
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index 0b8fabc6c..1b011b204 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -747,28 +747,39 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
.rbrace_token = undefined,
};
+ const layout = ZigClangASTContext_getASTRecordLayout(c.clang_context, record_def);
var it = ZigClangRecordDecl_field_begin(record_def);
const end_it = ZigClangRecordDecl_field_end(record_def);
while (ZigClangRecordDecl_field_iterator_neq(it, end_it)) : (it = ZigClangRecordDecl_field_iterator_next(it)) {
const field_decl = ZigClangRecordDecl_field_iterator_deref(it);
const field_loc = ZigClangFieldDecl_getLocation(field_decl);
- if (ZigClangFieldDecl_isBitField(field_decl)) {
- const opaque = try transCreateNodeOpaqueType(c);
- semicolon = try appendToken(c, .Semicolon, ";");
- try emitWarning(c, field_loc, "{} demoted to opaque type - has bitfield", .{container_kind_name});
- break :blk opaque;
- }
+ const is_bitfield = ZigClangFieldDecl_isBitField(field_decl);
+ const offset = ZigClangASTRecordLayout_getFieldOffset(layout, ZigClangFieldDecl_getFieldIndex(field_decl));
+
+ // if (ZigClangFieldDecl_isBitField(field_decl)) {
+ // const opaque = try transCreateNodeOpaqueType(c);
+ // semicolon = try appendToken(c, .Semicolon, ";");
+ // try emitWarning(c, field_loc, "to offset {}", .{offset});
+ // // 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?
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) {
- error.UnsupportedType => {
- try failDecl(c, record_loc, name, "unable to translate {} member type", .{container_kind_name});
- return null;
- },
- else => |e| return e,
+ const field_type = if (is_bitfield) ty: {
+ const bit_width = ZigClangFieldDecl_getBitWidthValue(field_decl, c.clang_context);
+ const type_name = try std.fmt.allocPrint(c.a(), "u{}", .{bit_width});
+ break :ty try transCreateNodeIdentifier(c, type_name);
+ } else ty: {
+ break :ty transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc) catch |err| switch (err) {
+ error.UnsupportedType => {
+ try failDecl(c, record_loc, name, "unable to translate {} member type", .{container_kind_name});
+ return null;
+ },
+ else => |e| return e,
+ };
};
const field_node = try c.a().create(ast.Node.ContainerField);
@@ -3180,9 +3191,9 @@ fn typeIsOpaque(c: *Context, ty: *const ZigClangType, loc: ZigClangSourceLocatio
while (ZigClangRecordDecl_field_iterator_neq(it, end_it)) : (it = ZigClangRecordDecl_field_iterator_next(it)) {
const field_decl = ZigClangRecordDecl_field_iterator_deref(it);
- if (ZigClangFieldDecl_isBitField(field_decl)) {
- return true;
- }
+ // if (ZigClangFieldDecl_isBitField(field_decl)) {
+ // return true;
+ // }
}
return false;
},
diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp
index 6217e1780..58ff01417 100644
--- a/src/zig_clang.cpp
+++ b/src/zig_clang.cpp
@@ -24,6 +24,7 @@
#include <clang/Frontend/CompilerInstance.h>
#include <clang/AST/APValue.h>
#include <clang/AST/Expr.h>
+#include <clang/AST/RecordLayout.h>
#if __GNUC__ >= 8
#pragma GCC diagnostic pop
@@ -1504,6 +1505,24 @@ ZigClangQualType ZigClangASTContext_getPointerType(const ZigClangASTContext* sel
return bitcast(reinterpret_cast<const clang::ASTContext *>(self)->getPointerType(bitcast(T)));
}
+const ZigClangASTRecordLayout *ZigClangASTContext_getASTRecordLayout(const ZigClangASTContext* self, const ZigClangRecordDecl *D) {
+ const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(D);
+ const clang::ASTRecordLayout *result = &reinterpret_cast<const clang::ASTContext *>(self)->getASTRecordLayout(record_decl);
+ return reinterpret_cast<const ZigClangASTRecordLayout *>(result);
+}
+
+// uint64_t ZigClangASTContext_getTypeSize(const ZigClangASTContext* self, const ZigClangType* T) {
+// return reinterpret_cast<const clang::ASTContext *>(self)->getTypeSize(T);
+// }
+
+unsigned ZigClangASTRecordLayout_getFieldCount(const struct ZigClangASTRecordLayout *self) {
+ return reinterpret_cast<const clang::ASTRecordLayout *>(self)->getFieldCount();
+}
+
+uint64_t ZigClangASTRecordLayout_getFieldOffset(const ZigClangASTRecordLayout *self, unsigned field_no) {
+ return reinterpret_cast<const clang::ASTRecordLayout *>(self)->getFieldOffset(field_no);
+}
+
unsigned ZigClangASTContext_getTypeAlign(const ZigClangASTContext* self, ZigClangQualType T) {
return reinterpret_cast<const clang::ASTContext *>(self)->getTypeAlign(bitcast(T));
}
@@ -2669,6 +2688,17 @@ bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *self) {
return casted->isBitField();
}
+unsigned ZigClangFieldDecl_getFieldIndex(const struct ZigClangFieldDecl *self) {
+ auto casted = reinterpret_cast<const clang::FieldDecl *>(self);
+ return casted->getFieldIndex();
+}
+
+unsigned ZigClangFieldDecl_getBitWidthValue(const struct ZigClangFieldDecl *self, const struct ZigClangASTContext *ctx) {
+ auto casted = reinterpret_cast<const clang::FieldDecl *>(self);
+ auto casted_ctx = reinterpret_cast<const clang::ASTContext *>(ctx);
+ return casted->getBitWidthValue(*casted_ctx);
+}
+
ZigClangSourceLocation ZigClangFieldDecl_getLocation(const struct ZigClangFieldDecl *self) {
auto casted = reinterpret_cast<const clang::FieldDecl *>(self);
return bitcast(casted->getLocation());
diff --git a/src/zig_clang.h b/src/zig_clang.h
index 0b248a812..c1045423e 100644
--- a/src/zig_clang.h
+++ b/src/zig_clang.h
@@ -69,6 +69,7 @@ struct ZigClangAPInt;
struct ZigClangAPSInt;
struct ZigClangAPValue;
struct ZigClangASTContext;
+struct ZigClangASTRecordLayout;
struct ZigClangASTUnit;
struct ZigClangArraySubscriptExpr;
struct ZigClangArrayType;
@@ -830,7 +831,11 @@ ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const struct Zig
struct ZigClangSourceLocation SL);
ZIG_EXTERN_C struct ZigClangQualType ZigClangASTContext_getPointerType(const struct ZigClangASTContext*, struct ZigClangQualType T);
+ZIG_EXTERN_C const ZigClangASTRecordLayout *ZigClangASTContext_getASTRecordLayout(const struct ZigClangASTContext* self, const ZigClangRecordDecl *D);
+// ZIG_EXTERN_C uint64_t ZigClangASTContext_getTypeSize(const ZigClangASTContext* self, const ZigClangType* T);
+ZIG_EXTERN_C unsigned ZigClangASTRecordLayout_getFieldCount(const ZigClangASTRecordLayout *self);
+ZIG_EXTERN_C uint64_t ZigClangASTRecordLayout_getFieldOffset(const ZigClangASTRecordLayout *self, unsigned field_no);
// Can return null.
ZIG_EXTERN_C struct ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char **args_end,
@@ -1115,6 +1120,8 @@ ZIG_EXTERN_C const char *ZigClangMacroDefinitionRecord_getName_getNameStart(cons
ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSourceRange_getBegin(const struct ZigClangMacroDefinitionRecord *);
ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSourceRange_getEnd(const struct ZigClangMacroDefinitionRecord *);
+ZIG_EXTERN_C unsigned ZigClangFieldDecl_getFieldIndex(const struct ZigClangFieldDecl *self);
+ZIG_EXTERN_C unsigned ZigClangFieldDecl_getBitWidthValue(const struct ZigClangFieldDecl *self, const struct ZigClangASTContext *ctx);
ZIG_EXTERN_C bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *);
ZIG_EXTERN_C struct ZigClangQualType ZigClangFieldDecl_getType(const struct ZigClangFieldDecl *);
ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFieldDecl_getLocation(const struct ZigClangFieldDecl *);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment