Commit 84e479d94f

hryx <codroid@gmail.com>
2019-06-10 08:35:48
(broken) local var decls, integer literals (part)
1 parent 586c36d
Changed files (4)
src/zig_clang.cpp
@@ -21,6 +21,7 @@
 
 #include <clang/Frontend/ASTUnit.h>
 #include <clang/Frontend/CompilerInstance.h>
+#include <clang/AST/APValue.h>
 #include <clang/AST/Expr.h>
 
 #if __GNUC__ >= 8
@@ -1287,6 +1288,20 @@ static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind
 static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF16 == clang::StringLiteral::UTF16, "");
 static_assert((clang::StringLiteral::StringKind)ZigClangStringLiteral_StringKind_UTF32 == clang::StringLiteral::UTF32, "");
 
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Uninitialized == clang::APValue::ValueKind::Uninitialized, "");
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Int == clang::APValue::ValueKind::Int, "");
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Float == clang::APValue::ValueKind::Float, "");
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_ComplexInt == clang::APValue::ValueKind::ComplexInt, "");
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_ComplexFloat == clang::APValue::ValueKind::ComplexFloat, "");
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_LValue == clang::APValue::ValueKind::LValue, "");
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Vector == clang::APValue::ValueKind::Vector, "");
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Array == clang::APValue::ValueKind::Array, "");
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Struct == clang::APValue::ValueKind::Struct, "");
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_Union == clang::APValue::ValueKind::Union, "");
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_MemberPointer == clang::APValue::ValueKind::MemberPointer, "");
+static_assert((clang::APValue::ValueKind)ZigClangAPValue_ValueKind_AddrLabelDiff == clang::APValue::ValueKind::AddrLabelDiff, "");
+
+static_assert(sizeof(ZigClangAPValue) == sizeof(clang::APValue), "");
 
 static_assert(sizeof(ZigClangSourceLocation) == sizeof(clang::SourceLocation), "");
 static ZigClangSourceLocation bitcast(clang::SourceLocation src) {
@@ -1312,6 +1327,13 @@ static clang::QualType bitcast(ZigClangQualType src) {
     return dest;
 }
 
+static_assert(sizeof(ZigClangExprEvalResult) == sizeof(clang::Expr::EvalResult), "");
+static ZigClangExprEvalResult bitcast(clang::Expr::EvalResult src) {
+    ZigClangExprEvalResult dest;
+    memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangExprEvalResult));
+    return dest;
+}
+
 static_assert(sizeof(ZigClangAPValueLValueBase) == sizeof(clang::APValue::LValueBase), "");
 static ZigClangAPValueLValueBase bitcast(clang::APValue::LValueBase src) {
     ZigClangAPValueLValueBase dest;
@@ -1979,3 +2001,19 @@ struct ZigClangQualType ZigClangCStyleCastExpr_getType(const struct ZigClangCSty
     auto casted = reinterpret_cast<const clang::CStyleCastExpr *>(self);
     return bitcast(casted->getType());
 }
+
+bool ZigClangIntegerLiteral_EvaluateAsInt(const struct ZigClangIntegerLiteral *self, struct ZigClangExprEvalResult *result, const struct ZigClangASTContext *ctx) {
+    auto casted_self = reinterpret_cast<const clang::IntegerLiteral *>(self);
+    auto casted_ctx = reinterpret_cast<const clang::ASTContext *>(ctx);
+    clang::Expr::EvalResult eval_result;
+    if (!casted_self->EvaluateAsInt(eval_result, *casted_ctx)) {
+        return false;
+    }
+    *result = bitcast(eval_result);
+    return true;
+}
+
+struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(const struct ZigClangIntegerLiteral *self) {
+    auto casted = reinterpret_cast<const clang::IntegerLiteral *>(self);
+    return bitcast(casted->getBeginLoc());
+}
src/zig_clang.h
@@ -30,6 +30,33 @@ struct ZigClangAPValueLValueBase {
     unsigned Version;
 };
 
+enum ZigClangAPValue_ValueKind {
+    ZigClangAPValue_ValueKind_Uninitialized,
+    ZigClangAPValue_ValueKind_Int,
+    ZigClangAPValue_ValueKind_Float,
+    ZigClangAPValue_ValueKind_ComplexInt,
+    ZigClangAPValue_ValueKind_ComplexFloat,
+    ZigClangAPValue_ValueKind_LValue,
+    ZigClangAPValue_ValueKind_Vector,
+    ZigClangAPValue_ValueKind_Array,
+    ZigClangAPValue_ValueKind_Struct,
+    ZigClangAPValue_ValueKind_Union,
+    ZigClangAPValue_ValueKind_MemberPointer,
+    ZigClangAPValue_ValueKind_AddrLabelDiff
+};
+
+struct ZigClangAPValue {
+    enum ZigClangAPValue_ValueKind Kind;
+    char Data[68]; // experimentally-derived size of clang::APValue::DataType
+};
+
+struct ZigClangExprEvalResult {
+    bool HasSideEffects;
+    bool HasUndefinedBehavior;
+    void *SmallVectorImpl;
+    ZigClangAPValue Val;
+};
+
 struct ZigClangAPValue;
 struct ZigClangAPSInt;
 struct ZigClangAPFloat;
@@ -889,4 +916,7 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangCStyleCastExpr_getBeginLoc(co
 ZIG_EXTERN_C const struct ZigClangExpr *ZigClangCStyleCastExpr_getSubExpr(const struct ZigClangCStyleCastExpr *);
 ZIG_EXTERN_C struct ZigClangQualType ZigClangCStyleCastExpr_getType(const struct ZigClangCStyleCastExpr *);
 
+ZIG_EXTERN_C bool ZigClangIntegerLiteral_EvaluateAsInt(const struct ZigClangIntegerLiteral *, struct ZigClangExprEvalResult *, const struct ZigClangASTContext *);
+ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(const struct ZigClangIntegerLiteral *);
+
 #endif
src-self-hosted/clang.zig
@@ -1,4 +1,3 @@
-pub const struct_ZigClangAPValue = @OpaqueType();
 pub const struct_ZigClangAPSInt = @OpaqueType();
 pub const struct_ZigClangAPFloat = @OpaqueType();
 pub const struct_ZigClangASTContext = @OpaqueType();
@@ -928,3 +927,34 @@ pub extern fn ZigClangAttributedType_getEquivalentType(*const ZigClangAttributed
 pub extern fn ZigClangCStyleCastExpr_getBeginLoc(*const ZigClangCStyleCastExpr) ZigClangSourceLocation;
 pub extern fn ZigClangCStyleCastExpr_getSubExpr(*const ZigClangCStyleCastExpr) *const ZigClangExpr;
 pub extern fn ZigClangCStyleCastExpr_getType(*const ZigClangCStyleCastExpr) ZigClangQualType;
+
+pub const ZigClangExprEvalResult = struct_ZigClangExprEvalResult;
+pub const struct_ZigClangExprEvalResult = extern struct {
+    HasSideEffects: bool,
+    HasUndefinedBehavior: bool,
+    SmallVectorImpl: ?*c_void,
+    Val: ZigClangAPValue,
+};
+
+pub const struct_ZigClangAPValue = extern struct {
+    Kind: ZigClangAPValue_ValueKind,
+    Data: [68]u8, // TODO: is there a way to statically assert that this matches the .h?
+};
+
+pub const ZigClangAPValue_ValueKind = extern enum {
+    ZigClangAPValue_ValueKind_Uninitialized,
+    ZigClangAPValue_ValueKind_Int,
+    ZigClangAPValue_ValueKind_Float,
+    ZigClangAPValue_ValueKind_ComplexInt,
+    ZigClangAPValue_ValueKind_ComplexFloat,
+    ZigClangAPValue_ValueKind_LValue,
+    ZigClangAPValue_ValueKind_Vector,
+    ZigClangAPValue_ValueKind_Array,
+    ZigClangAPValue_ValueKind_Struct,
+    ZigClangAPValue_ValueKind_Union,
+    ZigClangAPValue_ValueKind_MemberPointer,
+    ZigClangAPValue_ValueKind_AddrLabelDiff,
+};
+
+pub extern fn ZigClangIntegerLiteral_EvaluateAsInt(*const ZigClangIntegerLiteral, *ZigClangExprEvalResult, *const ZigClangASTContext) bool;
+pub extern fn ZigClangIntegerLiteral_getBeginLoc(*const ZigClangIntegerLiteral) ZigClangSourceLocation;
src-self-hosted/translate_c.zig
@@ -333,6 +333,7 @@ fn transStmt(
         .DeclStmtClass => return transDeclStmt(rp, scope, @ptrCast(*const ZigClangDeclStmt, stmt)),
         .DeclRefExprClass => return transDeclRefExpr(rp, scope, @ptrCast(*const ZigClangDeclRefExpr, stmt), lrvalue),
         .ImplicitCastExprClass => return transImplicitCastExpr(rp, scope, @ptrCast(*const ZigClangImplicitCastExpr, stmt), result_used),
+        .IntegerLiteralClass => return transIntegerLiteral(rp, scope, @ptrCast(*const ZigClangIntegerLiteral, stmt), result_used),
         else => {
             return revertAndWarn(
                 rp,
@@ -534,6 +535,26 @@ fn transImplicitCastExpr(
     }
 }
 
+fn transIntegerLiteral(
+    rp: RestorePoint,
+    scope: *Scope,
+    expr: *const ZigClangIntegerLiteral,
+    result_used: ResultUsed,
+) !TransResult {
+    var eval_result: ZigClangExprEvalResult = undefined;
+    if (!ZigClangIntegerLiteral_EvaluateAsInt(expr, &eval_result, rp.c.clang_context)) {
+        const loc = ZigClangIntegerLiteral_getBeginLoc(expr);
+        return revertAndWarn(rp, error.UnsupportedTranslation, loc, "invalid integer literal");
+    }
+    const node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val));
+    const res = TransResult{
+        .node = node,
+        .child_scope = scope,
+        .node_scope = scope,
+    };
+    return maybeSuppressResult(rp, scope, result_used, res);
+}
+
 fn transCCast(
     rp: RestorePoint,
     scope: *Scope,
@@ -547,14 +568,17 @@ fn transCCast(
     if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type))
         return transCPtrCast(rp, loc, dst_type, src_type, expr);
     if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) {
-        const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "ptrToInt");
+        const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
         try builtin_node.params.push(expr);
+        builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
         return &(try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc), &builtin_node.base)).base;
     }
     if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) {
-        const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "intToPtr");
+        const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr");
         try builtin_node.params.push(try transQualType(rp, dst_type, loc));
+        _ = try appendToken(rp.c, .Comma, ",");
         try builtin_node.params.push(expr);
+        builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
         return &builtin_node.base;
     }
     // TODO: maybe widen to increase size
@@ -599,25 +623,28 @@ fn transCPtrCast(
 ) !*ast.Node {
     const ty = ZigClangQualType_getTypePtr(dst_type);
     const child_type = ZigClangType_getPointeeType(ty);
-    const dst_type_node = try transType(rp, ty, loc);
-    const child_type_node = try transQualType(rp, child_type, loc);
 
     // Implicit downcasting from higher to lower alignment values is forbidden,
     // use @alignCast to side-step this problem
-    const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "ptrCast");
+    const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrCast");
+    const dst_type_node = try transType(rp, ty, loc);
     try ptrcast_node.params.push(dst_type_node);
+    _ = try appendToken(rp.c, .Comma, ",");
 
     if (ZigClangType_isVoidType(qualTypeCanon(child_type))) {
         // void has 1-byte alignment, so @alignCast is not needed
         try ptrcast_node.params.push(expr);
     } else {
-        const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "alignOf");
+        const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf");
+        const child_type_node = try transQualType(rp, child_type, loc);
         try alignof_node.params.push(child_type_node);
-        const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "alignCast");
+        const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast");
         try aligncast_node.params.push(&alignof_node.base);
+        _ = try appendToken(rp.c, .Comma, ",");
         try aligncast_node.params.push(expr);
         try ptrcast_node.params.push(&aligncast_node.base);
     }
+    ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
 
     return &ptrcast_node.base;
 }
@@ -740,17 +767,20 @@ fn cIsUnsignedInteger(qt: ZigClangQualType) bool {
 }
 
 fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.BuiltinCall {
+    const builtin_token = try appendToken(c, .Builtin, name);
+    _ = try appendToken(c, .LParen, "(");
     const node = try c.a().create(ast.Node.BuiltinCall);
     node.* = ast.Node.BuiltinCall{
         .base = ast.Node{ .id = .BuiltinCall },
-        .builtin_token = try appendToken(c, .Builtin, name),
+        .builtin_token = builtin_token,
         .params = ast.Node.BuiltinCall.ParamList.init(c.a()),
-        .rparen_token = undefined, // TODO TokenIndex,
+        .rparen_token = undefined, // set after appending args
     };
     return node;
 }
 
 fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node) !*ast.Node.SuffixOp {
+    _ = try appendToken(c, .LParen, "(");
     const node = try c.a().create(ast.Node.SuffixOp);
     node.* = ast.Node.SuffixOp{
         .base = ast.Node{ .id = .SuffixOp },
@@ -761,16 +791,23 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node, first_arg: *ast.Node)
                 .async_attr = null,
             },
         },
-        .rtoken = undefined, // TODO TokenIndex
+        .rtoken = try appendToken(c, .RParen, ")"),
     };
+    try node.op.Call.params.push(first_arg);
     return node;
 }
 
-fn transCreateNodePrefixOp(c: *Context, op: ast.Node.PrefixOp.Op, rhs: *ast.Node) !*ast.Node {
+fn transCreateNodePrefixOp(
+    c: *Context,
+    op: ast.Node.PrefixOp.Op,
+    rhs: *ast.Node,
+    op_tok_id: std.zig.Token.Id,
+    bytes: []const u8,
+) !*ast.Node {
     const node = try c.a().create(ast.Node.PrefixOp);
     node.* = ast.Node.PrefixOp{
         .base = ast.Node{ .id = .PrefixOp },
-        .op_token = undefined, // TODO TokenIndex,
+        .op_token = try appendToken(c, op_tok_id, bytes),
         .op = op,
         .rhs = rhs,
     };
@@ -783,11 +820,12 @@ fn transCreateNodePtrType(
     is_volatile: bool,
     rhs: *ast.Node,
     op_tok_id: std.zig.Token.Id,
+    bytes: []const u8,
 ) !*ast.Node {
     const node = try c.a().create(ast.Node.PrefixOp);
     node.* = ast.Node.PrefixOp{
         .base = ast.Node{ .id = .PrefixOp },
-        .op_token = try appendToken(c, op_tok_id, ""), // TODO TokenIndex,
+        .op_token = try appendToken(c, op_tok_id, bytes),
         .op = ast.Node.PrefixOp.Op{
             .PtrType = ast.Node.PrefixOp.PtrInfo{
                 .allowzero_token = null,
@@ -801,6 +839,15 @@ fn transCreateNodePtrType(
     return &node.base;
 }
 
+fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node {
+    const node = try c.a().create(ast.Node.IntegerLiteral);
+    node.* = ast.Node.IntegerLiteral{
+        .base = ast.Node{ .id = .IntegerLiteral },
+        .token = try appendToken(c, .IntegerLiteral, "3333333"), // TODO
+    };
+    return &node.base;
+}
+
 const RestorePoint = struct {
     c: *Context,
     token_index: ast.TokenIndex,
@@ -860,7 +907,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
             const child_qt = ZigClangType_getPointeeType(ty);
             const child_node = try transQualType(rp, child_qt, source_loc);
             if (qualTypeChildIsFnProto(child_qt))
-                return transCreateNodePrefixOp(rp.c, .OptionalType, child_node);
+                return transCreateNodePrefixOp(rp.c, .OptionalType, child_node, .QuestionMark, "?");
             if (typeIsOpaque(rp.c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
                 const pointer_node = try transCreateNodePtrType(
                     rp.c,
@@ -868,8 +915,9 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
                     ZigClangQualType_isVolatileQualified(child_qt),
                     child_node,
                     .Asterisk,
+                    "*",
                 );
-                return transCreateNodePrefixOp(rp.c, .OptionalType, pointer_node);
+                return transCreateNodePrefixOp(rp.c, .OptionalType, pointer_node, .QuestionMark, "?");
             }
             return transCreateNodePtrType(
                 rp.c,
@@ -877,6 +925,7 @@ fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSour
                 ZigClangQualType_isVolatileQualified(child_qt),
                 child_node,
                 .BracketStarCBracket,
+                "[*c]",
             );
         },
         else => {