Commit f845994839

hryx <codroid@gmail.com>
2019-06-24 02:17:21
transBinaryOperator: Add, Sub
1 parent 69b90e0
Changed files (4)
src/zig_clang.cpp
@@ -2042,3 +2042,8 @@ const struct ZigClangExpr *ZigClangBinaryOperator_getRHS(const struct ZigClangBi
     auto casted = reinterpret_cast<const clang::BinaryOperator *>(self);
     return reinterpret_cast<const struct ZigClangExpr *>(casted->getRHS());
 }
+
+struct ZigClangQualType ZigClangBinaryOperator_getType(const struct ZigClangBinaryOperator *self) {
+    auto casted = reinterpret_cast<const clang::BinaryOperator *>(self);
+    return bitcast(casted->getType());
+}
src/zig_clang.h
@@ -925,5 +925,6 @@ ZIG_EXTERN_C enum ZigClangBO ZigClangBinaryOperator_getOpcode(const struct ZigCl
 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 *);
+ZIG_EXTERN_C struct ZigClangQualType ZigClangBinaryOperator_getType(const struct ZigClangBinaryOperator *);
 
 #endif
src-self-hosted/clang.zig
@@ -965,6 +965,7 @@ pub extern fn ZigClangBinaryOperator_getOpcode(*const ZigClangBinaryOperator) Zi
 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;
+pub extern fn ZigClangBinaryOperator_getType(*const ZigClangBinaryOperator) ZigClangQualType;
 
 pub extern fn ZigClangStringLiteral_getKind(*const ZigClangStringLiteral) ZigClangStringLiteral_StringKind;
 pub extern fn ZigClangStringLiteral_getString_bytes_begin_size(*const ZigClangStringLiteral, *usize) [*c]const u8;
src-self-hosted/translate_c.zig
@@ -356,6 +356,7 @@ fn transBinaryOperator(
     result_used: ResultUsed,
 ) TransError!TransResult {
     const op = ZigClangBinaryOperator_getOpcode(stmt);
+    const qt = ZigClangBinaryOperator_getType(stmt);
     switch (op) {
         .PtrMemD, .PtrMemI, .Cmp => return revertAndWarn(
             rp,
@@ -369,11 +370,31 @@ fn transBinaryOperator(
             .child_scope = scope,
             .node_scope = scope,
         },
+        .Add => {
+            const node = if (cIsUnsignedInteger(qt))
+                try transCreateNodeInfixOp(rp, scope, stmt, .AddWrap, .PlusPercent, "+%")
+            else
+                try transCreateNodeInfixOp(rp, scope, stmt, .Add, .Plus, "+");
+            return maybeSuppressResult(rp, scope, result_used, TransResult{
+                .node = &node.base,
+                .child_scope = scope,
+                .node_scope = scope,
+            });
+        },
+        .Sub => {
+            const node = if (cIsUnsignedInteger(qt))
+                try transCreateNodeInfixOp(rp, scope, stmt, .SubWrap, .MinusPercent, "-%")
+            else
+                try transCreateNodeInfixOp(rp, scope, stmt, .Sub, .Minus, "-");
+            return maybeSuppressResult(rp, scope, result_used, TransResult{
+                .node = &node.base,
+                .child_scope = scope,
+                .node_scope = scope,
+            });
+        },
         .Mul,
         .Div,
         .Rem,
-        .Sub,
-        .Add,
         .Shl,
         .Shr,
         .LT,
@@ -660,7 +681,7 @@ fn transStringLiteral(
             var len: usize = undefined;
             const cstr = ZigClangStringLiteral_getString_bytes_begin_size(stmt, &len);
             const zstr = try rp.c.str(cstr);
-            const token = try appendToken(rp.c, .StringLiteral, zstr);
+            const token = try appendTokenFmt(rp.c, .StringLiteral, "c\"{}\"", zstr); // TODO: escape string
             const node = try rp.c.a().create(ast.Node.StringLiteral);
             node.* = ast.Node.StringLiteral{
                 .base = ast.Node{ .id = .StringLiteral },
@@ -792,6 +813,8 @@ fn maybeSuppressResult(
     result: TransResult,
 ) !TransResult {
     if (used == .used) return result;
+    // NOTE: This is backwards, but the semicolon must immediately follow the node.
+    _ = try appendToken(rp.c, .Semicolon, ";");
     const lhs = try appendIdentifier(rp.c, "_");
     const op_token = try appendToken(rp.c, .Equal, "=");
     const op_node = try rp.c.a().create(ast.Node.InfixOp);
@@ -985,6 +1008,28 @@ fn transCreateNodePrefixOp(
     return node;
 }
 
+fn transCreateNodeInfixOp(
+    rp: RestorePoint,
+    scope: *Scope,
+    stmt: *const ZigClangBinaryOperator,
+    op: ast.Node.InfixOp.Op,
+    op_tok_id: std.zig.Token.Id,
+    bytes: []const u8,
+) !*ast.Node.InfixOp {
+    const lhs = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value);
+    const op_token = try appendToken(rp.c, op_tok_id, bytes);
+    const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
+    const node = try rp.c.a().create(ast.Node.InfixOp);
+    node.* = ast.Node.InfixOp{
+        .base = ast.Node{ .id = .InfixOp },
+        .op_token = op_token,
+        .lhs = lhs.node,
+        .op = op,
+        .rhs = rhs.node,
+    };
+    return node;
+}
+
 fn transCreateNodePtrType(
     c: *Context,
     is_const: bool,