diff options
| -rw-r--r-- | src-self-hosted/clang.zig | 20 | ||||
| -rw-r--r-- | src-self-hosted/translate_c.zig | 151 | ||||
| -rw-r--r-- | src/zig_clang.cpp | 53 | ||||
| -rw-r--r-- | src/zig_clang.h | 23 |
4 files changed, 245 insertions, 2 deletions
diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 92fe7b7cd3..ea8f3a6cc6 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -864,3 +864,23 @@ pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangS pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator; pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator; + +pub const ZigClangDeclStmt_const_decl_iterator = [*c]const *struct_ZigClangDecl; + +pub extern fn ZigClangDeclStmt_decl_begin(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator; +pub extern fn ZigClangDeclStmt_decl_end(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator; + +pub extern fn ZigClangVarDecl_getType(self: ?*const struct_ZigClangVarDecl) struct_ZigClangQualType; +pub extern fn ZigClangVarDecl_getInit(*const ZigClangVarDecl) ?*const ZigClangExpr; +pub extern fn ZigClangVarDecl_getTLSKind(self: ?*const struct_ZigClangVarDecl) ZigClangVarDecl_TLSKind; +pub const ZigClangVarDecl_TLSKind = extern enum { + None, + Static, + Dynamic, +}; + +pub extern fn ZigClangImplicitCastExpr_getBeginLoc(*const ZigClangImplicitCastExpr) ZigClangSourceLocation; +pub extern fn ZigClangImplicitCastExpr_getCastKind(*const ZigClangImplicitCastExpr) ZigClangCK; +pub extern fn ZigClangImplicitCastExpr_getSubExpr(*const ZigClangImplicitCastExpr) *const ZigClangExpr; + +pub extern fn ZigClangArrayType_getElementType(*const ZigClangArrayType) ZigClangQualType; diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index dac4c2b1ca..3b60e65753 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -107,6 +107,7 @@ const Context = struct { decl_table: DeclTable, global_scope: *Scope.Root, mode: Mode, + clang_context: *ZigClangASTContext, fn a(c: *Context) *std.mem.Allocator { return &c.tree.arena_allocator.allocator; @@ -183,6 +184,7 @@ pub fn translate( .decl_table = DeclTable.init(arena), .global_scope = try arena.create(Scope.Root), .mode = mode, + .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?, }; context.global_scope.* = Scope.Root{ .base = Scope{ @@ -323,6 +325,8 @@ fn transStmt( const sc = ZigClangStmt_getStmtClass(stmt); switch (sc) { .CompoundStmtClass => return transCompoundStmt(rp, scope, @ptrCast(*const ZigClangCompoundStmt, stmt)), + .DeclStmtClass => return transDeclStmt(rp, scope, @ptrCast(*const ZigClangDeclStmt, stmt)), + .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt)), else => { return revertAndWarn( rp, @@ -368,6 +372,136 @@ fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompo }; } +fn transDeclStmt(rp: RestorePoint, parent_scope: *Scope, stmt: *const ZigClangDeclStmt) !TransResult { + const c = rp.c; + const block_scope = findBlockScope(parent_scope); + var scope = parent_scope; + + var it = ZigClangDeclStmt_decl_begin(stmt); + const end_it = ZigClangDeclStmt_decl_end(stmt); + while (it != end_it) : (it += 1) { + switch (ZigClangDecl_getKind(it.*)) { + .Var => { + const var_decl = @ptrCast(*const ZigClangVarDecl, it.*); + + const thread_local_token = if (ZigClangVarDecl_getTLSKind(var_decl) == .None) + null + else + try appendToken(c, .Keyword_threadlocal, "threadlocal"); + const qual_type = ZigClangVarDecl_getType(var_decl); + const mut_token = if (ZigClangQualType_isConstQualified(qual_type)) + try appendToken(c, .Keyword_const, "const") + else + try appendToken(c, .Keyword_var, "var"); + const c_name = try c.str(ZigClangDecl_getName_bytes_begin( + @ptrCast(*const ZigClangDecl, var_decl), + )); + const name_token = try appendToken(c, .Identifier, c_name); + + const var_scope = try c.a().create(Scope.Var); + var_scope.* = Scope.Var{ + .base = Scope{ .id = .Var, .parent = parent_scope }, + .c_name = c_name, + .zig_name = c_name, // TODO: getWantedName + }; + scope = &var_scope.base; + + const eq_token = try appendToken(c, .Equal, "="); + const init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr| + (try transExpr(rp, scope, expr, .used, .r_value)).node + else + null; + const semicolon_token = try appendToken(c, .Semicolon, ";"); + + const node = try c.a().create(ast.Node.VarDecl); + node.* = ast.Node.VarDecl{ + .base = ast.Node{ .id = .VarDecl }, + .doc_comments = null, + .visib_token = null, + .thread_local_token = thread_local_token, + .name_token = name_token, + .eq_token = eq_token, + .mut_token = mut_token, + .comptime_token = null, + .extern_export_token = null, // TODO ?TokenIndex, + .lib_name = null, // TODO ?*Node, + .type_node = null, // TODO ?*Node, + .align_node = null, // TODO ?*Node, + .section_node = null, // TODO ?*Node, + .init_node = init_node, + .semicolon_token = semicolon_token, + }; + try block_scope.block_node.statements.push(&node.base); + }, + + else => |kind| return revertAndWarn( + rp, + error.UnsupportedTranslation, + ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)), + "TODO implement translation of DeclStmt kind {}", + @tagName(kind), + ), + } + } + + return TransResult{ + .node = &block_scope.block_node.base, + .node_scope = scope, + .child_scope = scope, + }; +} + +fn transImplicitCastExpr( + rp: RestorePoint, + scope: *Scope, + expr: *const ZigClangImplicitCastExpr, +) !TransResult { + const c = rp.c; + switch (ZigClangImplicitCastExpr_getCastKind(expr)) { + .BitCast => { + const node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, expr), .used, .r_value); + const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr)); + const src_type = getExprQualType(c, ZigClangImplicitCastExpr_getSubExpr(expr)); + return try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, node.node); + }, + else => |kind| return revertAndWarn( + rp, + error.UnsupportedTranslation, + ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, expr)), + "TODO implement translation of CastKind {}", + @tagName(kind), + ), + } +} + +fn transCCast( + rp: RestorePoint, + scope: *Scope, + loc: ZigClangSourceLocation, + dst_type: ZigClangQualType, + src_type: ZigClangQualType, + target_node: *ast.Node, +) !TransResult { + return revertAndWarn(rp, error.UnsupportedTranslation, loc, "TODO implement translation of C cast"); +} + +fn transExpr( + rp: RestorePoint, + scope: *Scope, + expr: *const ZigClangExpr, + used: ResultUsed, + lrvalue: LRValue, +) TransError!TransResult { + return transStmt(rp, scope, @ptrCast(*const ZigClangStmt, expr), used, lrvalue); +} + +fn findBlockScope(inner: *Scope) *Scope.Block { + var scope = inner; + while (true) : (scope = scope.parent orelse unreachable) { + if (scope.id == .Block) return @fieldParentPtr(Scope.Block, "base", scope); + } +} + fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void { try c.tree.root_node.decls.push(decl_node); } @@ -381,6 +515,23 @@ fn qualTypeCanon(qt: ZigClangQualType) *const ZigClangType { return ZigClangQualType_getTypePtr(canon); } +fn getExprQualType(c: *Context, expr: *const ZigClangExpr) ZigClangQualType { + blk: { + // If this is a C `char *`, turn it into a `const char *` + if (ZigClangExpr_getStmtClass(expr) != .ImplicitCastExprClass) break :blk; + const cast_expr = @ptrCast(*const ZigClangImplicitCastExpr, expr); + if (ZigClangImplicitCastExpr_getCastKind(cast_expr) != .ArrayToPointerDecay) break :blk; + const sub_expr = ZigClangImplicitCastExpr_getSubExpr(cast_expr); + if (ZigClangExpr_getStmtClass(sub_expr) != .StringLiteralClass) break :blk; + const array_qt = ZigClangExpr_getType(sub_expr); + const array_type = @ptrCast(*const ZigClangArrayType, ZigClangQualType_getTypePtr(array_qt)); + var pointee_qt = ZigClangArrayType_getElementType(array_type); + ZigClangQualType_addConst(&pointee_qt); + return ZigClangASTContext_getPointerType(c.clang_context, pointee_qt); + } + return ZigClangExpr_getType(expr); +} + const RestorePoint = struct { c: *Context, token_index: ast.TokenIndex, diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp index 28062ea69f..2edfda8efa 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1331,6 +1331,12 @@ static ZigClangCompoundStmt_const_body_iterator bitcast(clang::CompoundStmt::con return dest; } +static_assert(sizeof(ZigClangDeclStmt_const_decl_iterator) == sizeof(clang::DeclStmt::const_decl_iterator), ""); +static ZigClangDeclStmt_const_decl_iterator bitcast(clang::DeclStmt::const_decl_iterator src) { + ZigClangDeclStmt_const_decl_iterator dest; + memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangDeclStmt_const_decl_iterator)); + return dest; +} ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *self, ZigClangSourceLocation Loc) @@ -1381,7 +1387,7 @@ ZigClangSourceManager *ZigClangASTUnit_getSourceManager(ZigClangASTUnit *self) { return reinterpret_cast<ZigClangSourceManager *>(result); } -bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *self, void *context, +bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *self, void *context, bool (*Fn)(void *context, const ZigClangDecl *decl)) { return reinterpret_cast<clang::ASTUnit *>(self)->visitLocalTopLevelDecls(context, @@ -1815,6 +1821,21 @@ void ZigClangASTUnit_delete(struct ZigClangASTUnit *self) { delete reinterpret_cast<clang::ASTUnit *>(self); } +struct ZigClangQualType ZigClangVarDecl_getType(const struct ZigClangVarDecl *self) { + auto casted = reinterpret_cast<const clang::VarDecl *>(self); + return bitcast(casted->getType()); +} + +const struct ZigClangExpr *ZigClangVarDecl_getInit(const struct ZigClangVarDecl *self) { + auto casted = reinterpret_cast<const clang::VarDecl *>(self); + return reinterpret_cast<const ZigClangExpr *>(casted->getInit()); +} + +enum ZigClangVarDecl_TLSKind ZigClangVarDecl_getTLSKind(const ZigClangVarDecl *self) { + auto casted = reinterpret_cast<const clang::VarDecl *>(self); + return (ZigClangVarDecl_TLSKind)casted->getTLSKind(); +} + enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self) { auto casted = reinterpret_cast<const clang::BuiltinType *>(self); return (ZigClangBuiltinTypeKind)casted->getKind(); @@ -1862,6 +1883,16 @@ ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const str return bitcast(casted->body_end()); } +ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_begin(const struct ZigClangDeclStmt *self) { + auto casted = reinterpret_cast<const clang::DeclStmt *>(self); + return bitcast(casted->decl_begin()); +} + +ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_end(const struct ZigClangDeclStmt *self) { + auto casted = reinterpret_cast<const clang::DeclStmt *>(self); + return bitcast(casted->decl_end()); +} + unsigned ZigClangAPFloat_convertToHexString(const ZigClangAPFloat *self, char *DST, unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM) { @@ -1888,3 +1919,23 @@ const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName( const clang::StringLiteral *result = casted->getFunctionName(); return reinterpret_cast<const struct ZigClangStringLiteral *>(result); } + +ZigClangSourceLocation ZigClangImplicitCastExpr_getBeginLoc(const struct ZigClangImplicitCastExpr *self) { + auto casted = reinterpret_cast<const clang::ImplicitCastExpr *>(self); + return bitcast(casted->getBeginLoc()); +} + +enum ZigClangCK ZigClangImplicitCastExpr_getCastKind(const struct ZigClangImplicitCastExpr *self) { + auto casted = reinterpret_cast<const clang::ImplicitCastExpr *>(self); + return (ZigClangCK)casted->getCastKind(); +} + +const struct ZigClangExpr *ZigClangImplicitCastExpr_getSubExpr(const struct ZigClangImplicitCastExpr *self) { + auto casted = reinterpret_cast<const clang::ImplicitCastExpr *>(self); + return reinterpret_cast<const struct ZigClangExpr *>(casted->getSubExpr()); +} + +struct ZigClangQualType ZigClangArrayType_getElementType(const struct ZigClangArrayType *self) { + auto casted = reinterpret_cast<const clang::ArrayType *>(self); + return bitcast(casted->getElementType()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index 1bdf34fc2f..0afe30c474 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -105,6 +105,7 @@ struct ZigClangFunctionType; struct ZigClangPredefinedExpr; typedef struct ZigClangStmt *const * ZigClangCompoundStmt_const_body_iterator; +typedef struct ZigClangDecl *const * ZigClangDeclStmt_const_decl_iterator; enum ZigClangBO { ZigClangBO_PtrMemD, @@ -732,6 +733,12 @@ enum ZigClangStringLiteral_StringKind { ZigClangStringLiteral_StringKind_UTF32, }; +enum ZigClangVarDecl_TLSKind { + ZigClangVarDecl_TLSKind_None, + ZigClangVarDecl_TLSKind_Static, + ZigClangVarDecl_TLSKind_Dynamic, +}; + ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const struct ZigClangSourceManager *, struct ZigClangSourceLocation Loc); ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const struct ZigClangSourceManager *, @@ -754,7 +761,7 @@ ZIG_EXTERN_C void ZigClangErrorMsg_delete(struct Stage2ErrorMsg *ptr, size_t len ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *); ZIG_EXTERN_C struct ZigClangSourceManager *ZigClangASTUnit_getSourceManager(struct ZigClangASTUnit *); -ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context, +ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context, bool (*Fn)(void *context, const struct ZigClangDecl *decl)); ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordType_getDecl(const struct ZigClangRecordType *record_ty); @@ -789,6 +796,10 @@ ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const struct ZigClangD ZIG_EXTERN_C enum ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *decl); ZIG_EXTERN_C const char *ZigClangDecl_getDeclKindName(const struct ZigClangDecl *decl); +ZIG_EXTERN_C struct ZigClangQualType ZigClangVarDecl_getType(const struct ZigClangVarDecl *); +ZIG_EXTERN_C const struct ZigClangExpr *ZigClangVarDecl_getInit(const struct ZigClangVarDecl *var_decl); +ZIG_EXTERN_C enum ZigClangVarDecl_TLSKind ZigClangVarDecl_getTLSKind(const struct ZigClangVarDecl *var_decl); + ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b); ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const struct ZigClangTypedefType *); @@ -846,6 +857,9 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionProtoType_getParamType(cons ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_begin(const struct ZigClangCompoundStmt *self); ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const struct ZigClangCompoundStmt *self); +ZIG_EXTERN_C ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_begin(const struct ZigClangDeclStmt *self); +ZIG_EXTERN_C ZigClangDeclStmt_const_decl_iterator ZigClangDeclStmt_decl_end(const struct ZigClangDeclStmt *self); + ZIG_EXTERN_C unsigned ZigClangAPFloat_convertToHexString(const struct ZigClangAPFloat *self, char *DST, unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM); @@ -855,4 +869,11 @@ ZIG_EXTERN_C const char *ZigClangStringLiteral_getString_bytes_begin_size(const ZIG_EXTERN_C const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName( const struct ZigClangPredefinedExpr *self); + +ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangImplicitCastExpr_getBeginLoc(const struct ZigClangImplicitCastExpr *); +ZIG_EXTERN_C enum ZigClangCK ZigClangImplicitCastExpr_getCastKind(const struct ZigClangImplicitCastExpr *); +ZIG_EXTERN_C const struct ZigClangExpr *ZigClangImplicitCastExpr_getSubExpr(const struct ZigClangImplicitCastExpr *); + +ZIG_EXTERN_C struct ZigClangQualType ZigClangArrayType_getElementType(const struct ZigClangArrayType *); + #endif |
