diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index e1b7c526b1..ea8f3a6cc6 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -879,4 +879,8 @@ pub const ZigClangVarDecl_TLSKind = extern enum { 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 50663537e2..757f07153c 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{ @@ -458,7 +460,14 @@ fn transImplicitCastExpr( scope: *Scope, expr: *const ZigClangImplicitCastExpr, ) !TransResult { - switch (ZigClangImplicitCastExpr_getCastKind(@ptrCast(*const ZigClangImplicitCastExpr, expr))) { + 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, @@ -469,6 +478,17 @@ fn transImplicitCastExpr( } } +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, @@ -499,6 +519,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 6077878b29..2edfda8efa 100644 --- a/src/zig_clang.cpp +++ b/src/zig_clang.cpp @@ -1920,7 +1920,22 @@ const struct ZigClangStringLiteral *ZigClangPredefinedExpr_getFunctionName( return reinterpret_cast(result); } +ZigClangSourceLocation ZigClangImplicitCastExpr_getBeginLoc(const struct ZigClangImplicitCastExpr *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getBeginLoc()); +} + enum ZigClangCK ZigClangImplicitCastExpr_getCastKind(const struct ZigClangImplicitCastExpr *self) { - auto casted = reinterpret_cast(self); + auto casted = reinterpret_cast(self); return (ZigClangCK)casted->getCastKind(); } + +const struct ZigClangExpr *ZigClangImplicitCastExpr_getSubExpr(const struct ZigClangImplicitCastExpr *self) { + auto casted = reinterpret_cast(self); + return reinterpret_cast(casted->getSubExpr()); +} + +struct ZigClangQualType ZigClangArrayType_getElementType(const struct ZigClangArrayType *self) { + auto casted = reinterpret_cast(self); + return bitcast(casted->getElementType()); +} diff --git a/src/zig_clang.h b/src/zig_clang.h index d6d193223b..0afe30c474 100644 --- a/src/zig_clang.h +++ b/src/zig_clang.h @@ -870,6 +870,10 @@ 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