diff options
| author | hryx <codroid@gmail.com> | 2019-06-22 17:29:36 -0700 |
|---|---|---|
| committer | hryx <codroid@gmail.com> | 2019-06-22 17:29:36 -0700 |
| commit | 4ae95d7ffc6ce6b011d5e5c6ff747cd3a1aa59bb (patch) | |
| tree | ae5f51402078cf034267cf7b7d27a802228f5ea8 /src-self-hosted | |
| parent | 6325ffc3f1e5f61caab6d554a760c1b5d061b0d4 (diff) | |
| download | zig-4ae95d7ffc6ce6b011d5e5c6ff747cd3a1aa59bb.tar.gz zig-4ae95d7ffc6ce6b011d5e5c6ff747cd3a1aa59bb.zip | |
Translate assignment BinaryOperator statements
Diffstat (limited to 'src-self-hosted')
| -rw-r--r-- | src-self-hosted/clang.zig | 5 | ||||
| -rw-r--r-- | src-self-hosted/translate_c.zig | 98 |
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, "("); |
