Commit 3bbee1ba2e

hryx <codroid@gmail.com>
2019-05-27 23:38:09
expr: BitCast for ImplicitCastExpr
1 parent 9c437f9
Changed files (4)
src/zig_clang.cpp
@@ -1920,7 +1920,22 @@ const struct ZigClangStringLiteral *ZigClangPredefinedExpr_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::CastExpr *>(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());
+}
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
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;
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,