Commit 4ae95d7ffc

hryx <codroid@gmail.com>
2019-06-23 02:29:36
Translate assignment BinaryOperator statements
1 parent 6325ffc
Changed files (4)
src/zig_clang.cpp
@@ -2022,3 +2022,23 @@ const struct ZigClangExpr *ZigClangReturnStmt_getRetValue(const struct ZigClangR
     auto casted = reinterpret_cast<const clang::ReturnStmt *>(self);
     return reinterpret_cast<const struct ZigClangExpr *>(casted->getRetValue());
 }
+
+enum ZigClangBO ZigClangBinaryOperator_getOpcode(const struct ZigClangBinaryOperator *self) {
+    auto casted = reinterpret_cast<const clang::BinaryOperator *>(self);
+    return (ZigClangBO)casted->getOpcode();
+}
+
+struct ZigClangSourceLocation ZigClangBinaryOperator_getBeginLoc(const struct ZigClangBinaryOperator *self) {
+    auto casted = reinterpret_cast<const clang::BinaryOperator *>(self);
+    return bitcast(casted->getBeginLoc());
+}
+
+const struct ZigClangExpr *ZigClangBinaryOperator_getLHS(const struct ZigClangBinaryOperator *self) {
+    auto casted = reinterpret_cast<const clang::BinaryOperator *>(self);
+    return reinterpret_cast<const struct ZigClangExpr *>(casted->getLHS());
+}
+
+const struct ZigClangExpr *ZigClangBinaryOperator_getRHS(const struct ZigClangBinaryOperator *self) {
+    auto casted = reinterpret_cast<const clang::BinaryOperator *>(self);
+    return reinterpret_cast<const struct ZigClangExpr *>(casted->getRHS());
+}
src/zig_clang.h
@@ -921,4 +921,9 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangIntegerLiteral_getBeginLoc(co
 
 ZIG_EXTERN_C const struct ZigClangExpr *ZigClangReturnStmt_getRetValue(const struct ZigClangReturnStmt *);
 
+ZIG_EXTERN_C enum ZigClangBO ZigClangBinaryOperator_getOpcode(const struct ZigClangBinaryOperator *);
+ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangBinaryOperator_getBeginLoc(const struct ZigClangBinaryOperator *);
+ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getLHS(const struct ZigClangBinaryOperator *);
+ZIG_EXTERN_C const struct ZigClangExpr *ZigClangBinaryOperator_getRHS(const struct ZigClangBinaryOperator *);
+
 #endif
src-self-hosted/clang.zig
@@ -960,3 +960,8 @@ pub extern fn ZigClangIntegerLiteral_EvaluateAsInt(*const ZigClangIntegerLiteral
 pub extern fn ZigClangIntegerLiteral_getBeginLoc(*const ZigClangIntegerLiteral) ZigClangSourceLocation;
 
 pub extern fn ZigClangReturnStmt_getRetValue(*const ZigClangReturnStmt) ?*const ZigClangExpr;
+
+pub extern fn ZigClangBinaryOperator_getOpcode(*const ZigClangBinaryOperator) ZigClangBO;
+pub extern fn ZigClangBinaryOperator_getBeginLoc(*const ZigClangBinaryOperator) ZigClangSourceLocation;
+pub extern fn ZigClangBinaryOperator_getLHS(*const ZigClangBinaryOperator) *const ZigClangExpr;
+pub extern fn ZigClangBinaryOperator_getRHS(*const ZigClangBinaryOperator) *const ZigClangExpr;
src-self-hosted/translate_c.zig
@@ -328,6 +328,7 @@ fn transStmt(
 ) !TransResult {
     const sc = ZigClangStmt_getStmtClass(stmt);
     switch (sc) {
+        .BinaryOperatorClass => return transBinaryOperator(rp, scope, @ptrCast(*const ZigClangBinaryOperator, stmt), result_used),
         .CompoundStmtClass => return transCompoundStmt(rp, scope, @ptrCast(*const ZigClangCompoundStmt, stmt)),
         .CStyleCastExprClass => return transCStyleCastExprClass(rp, scope, @ptrCast(*const ZigClangCStyleCastExpr, stmt), result_used, lrvalue),
         .DeclStmtClass => return transDeclStmt(rp, scope, @ptrCast(*const ZigClangDeclStmt, stmt)),
@@ -347,6 +348,66 @@ fn transStmt(
     }
 }
 
+fn transBinaryOperator(
+    rp: RestorePoint,
+    scope: *Scope,
+    stmt: *const ZigClangBinaryOperator,
+    result_used: ResultUsed,
+) TransError!TransResult {
+    const op = ZigClangBinaryOperator_getOpcode(stmt);
+    switch (op) {
+        .PtrMemD, .PtrMemI, .Cmp => return revertAndWarn(
+            rp,
+            error.UnsupportedTranslation,
+            ZigClangBinaryOperator_getBeginLoc(stmt),
+            "TODO: handle more C binary operators: {}",
+            op,
+        ),
+        .Assign => return TransResult{
+            .node = &(try transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt))).base,
+            .child_scope = scope,
+            .node_scope = scope,
+        },
+        .Mul,
+        .Div,
+        .Rem,
+        .Sub,
+        .Add,
+        .Shl,
+        .Shr,
+        .LT,
+        .GT,
+        .LE,
+        .GE,
+        .EQ,
+        .NE,
+        .And,
+        .Xor,
+        .Or,
+        .LAnd,
+        .LOr,
+        .Comma,
+        => return revertAndWarn(
+            rp,
+            error.UnsupportedTranslation,
+            ZigClangBinaryOperator_getBeginLoc(stmt),
+            "TODO: handle more C binary operators: {}",
+            op,
+        ),
+        .MulAssign,
+        .DivAssign,
+        .RemAssign,
+        .AddAssign,
+        .SubAssign,
+        .ShlAssign,
+        .ShrAssign,
+        .AndAssign,
+        .XorAssign,
+        .OrAssign,
+        => unreachable,
+    }
+}
+
 fn transCompoundStmtInline(
     rp: RestorePoint,
     parent_scope: *Scope,
@@ -796,6 +857,43 @@ fn cIsUnsignedInteger(qt: ZigClangQualType) bool {
     };
 }
 
+fn transCreateNodeAssign(
+    rp: RestorePoint,
+    scope: *Scope,
+    result_used: ResultUsed,
+    lhs: *const ZigClangExpr,
+    rhs: *const ZigClangExpr,
+) !*ast.Node.InfixOp {
+    // common case
+    // c:   lhs = rhs
+    // zig: lhs = rhs
+    if (result_used == .unused) {
+        const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
+        const eq_token = try appendToken(rp.c, .Equal, "=");
+        const rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
+        _ = try appendToken(rp.c, .Semicolon, ";");
+
+        const node = try rp.c.a().create(ast.Node.InfixOp);
+        node.* = ast.Node.InfixOp{
+            .base = ast.Node{ .id = .InfixOp },
+            .op_token = eq_token,
+            .lhs = lhs_node.node,
+            .op = .Assign,
+            .rhs = rhs_node.node,
+        };
+        return node;
+    }
+
+    // worst case
+    // c:   lhs = rhs
+    // zig: (x: {
+    // zig:     const _tmp = rhs;
+    // zig:     lhs = _tmp;
+    // zig:     break :x _tmp
+    // zig: })
+    return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangExpr_getBeginLoc(lhs), "TODO: worst case assign op expr");
+}
+
 fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.BuiltinCall {
     const builtin_token = try appendToken(c, .Builtin, name);
     _ = try appendToken(c, .LParen, "(");