aboutsummaryrefslogtreecommitdiff
path: root/src-self-hosted
diff options
context:
space:
mode:
authorhryx <codroid@gmail.com>2019-06-22 17:29:36 -0700
committerhryx <codroid@gmail.com>2019-06-22 17:29:36 -0700
commit4ae95d7ffc6ce6b011d5e5c6ff747cd3a1aa59bb (patch)
treeae5f51402078cf034267cf7b7d27a802228f5ea8 /src-self-hosted
parent6325ffc3f1e5f61caab6d554a760c1b5d061b0d4 (diff)
downloadzig-4ae95d7ffc6ce6b011d5e5c6ff747cd3a1aa59bb.tar.gz
zig-4ae95d7ffc6ce6b011d5e5c6ff747cd3a1aa59bb.zip
Translate assignment BinaryOperator statements
Diffstat (limited to 'src-self-hosted')
-rw-r--r--src-self-hosted/clang.zig5
-rw-r--r--src-self-hosted/translate_c.zig98
2 files changed, 103 insertions, 0 deletions
diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig
index de3c538c4b..d48c57c0a4 100644
--- a/src-self-hosted/clang.zig
+++ b/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;
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index 4d339fe259..4673166450 100644
--- a/src-self-hosted/translate_c.zig
+++ b/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, "(");