Created
January 12, 2020 23:37
-
-
Save LemonBoy/3e185207ab072fb52e0a8d6f1b75fbd2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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