authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-25 20:34:05-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-25 20:34:05-05:00
logdf0e875856023e38af8b88dd94ef97f347d0a5e3
tree438188177e92892feb2d5dc0a821aaf452cf866c
parenta2afcae9ff1f2eed5c6a19a2bd63af288b9171ad

translate-c: introduce the concept of scopes

in preparation to implement switch and solve variable name collisions

2 files changed, 452 insertions(+), 234 deletions(-)

src/translate_c.cpp+401-234
......@@ -23,6 +23,8 @@
2323
2424using namespace clang;
2525
26struct TransScope;
27
2628struct MacroSymbol {
2729 Buf *name;
2830 Buf *value;
......@@ -52,12 +54,59 @@ struct Context {
5254 ASTContext *ctx;
5355
5456 HashMap<Buf *, bool, buf_hash, buf_eql_buf> ptr_params;
57 TransScope *child_scope; // TODO refactor out
58};
59
60enum ResultUsed {
61 ResultUsedNo,
62 ResultUsedYes,
63};
64
65enum TransLRValue {
66 TransLValue,
67 TransRValue,
68};
69
70enum TransScopeId {
71 TransScopeIdSwitch,
72 TransScopeIdVar,
73 TransScopeIdBlock,
5574};
5675
76struct TransScope {
77 TransScopeId id;
78 TransScope *parent;
79};
80
81struct TransScopeSwitch {
82 TransScope base;
83 AstNode *switch_node;
84};
85
86struct TransScopeVar {
87 TransScope base;
88 Buf *c_name;
89 Buf *zig_name;
90};
91
92struct TransScopeBlock {
93 TransScope base;
94 AstNode *node;
95};
96
97static AstNode *const skip_add_to_block_node = (AstNode *) 0x2;
98
99static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope);
100static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name);
101//static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope);
102
57103static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);
58104static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
59105static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl);
60106
107static AstNode *trans_stmt(Context *c, ResultUsed result_used, TransScope *scope, const Stmt *stmt, TransLRValue lrval);
108static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
109
61110
62111ATTRIBUTE_PRINTF(3, 4)
63112static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) {
......@@ -165,8 +214,8 @@ static AstNode *trans_create_node_bin_op(Context *c, AstNode *lhs_node, BinOpTyp
165214 return node;
166215}
167216
168static AstNode *maybe_suppress_result(Context *c, bool result_used, AstNode *node) {
169 if (result_used) return node;
217static AstNode *maybe_suppress_result(Context *c, ResultUsed result_used, AstNode *node) {
218 if (result_used == ResultUsedYes) return node;
170219 return trans_create_node_bin_op(c,
171220 trans_create_node_symbol_str(c, "_"),
172221 BinOpTypeAssign,
......@@ -341,8 +390,6 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int)
341390
342391}
343392
344static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
345
346393static QualType get_expr_qual_type(Context *c, const Expr *expr) {
347394 // String literals in C are `char *` but they should really be `const char *`.
348395 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
......@@ -573,16 +620,8 @@ static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {
573620 }
574621}
575622
576enum TransLRValue {
577 TransLValue,
578 TransRValue,
579};
580
581static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrval);
582static AstNode *const skip_add_to_block_node = (AstNode *) 0x2;
583
584static AstNode *trans_expr(Context *c, bool result_used, AstNode *block, Expr *expr, TransLRValue lrval) {
585 return trans_stmt(c, result_used, block, expr, lrval);
623static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval) {
624 return trans_stmt(c, result_used, scope, expr, lrval);
586625}
587626
588627static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) {
......@@ -922,32 +961,33 @@ static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &s
922961 return trans_type(c, qt.getTypePtr(), source_loc);
923962}
924963
925static AstNode *trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) {
926 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
927 for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
928 AstNode *child_node = trans_stmt(c, false, child_block, *it, TransRValue);
964static AstNode *trans_compound_stmt(Context *c, TransScope *parent_scope, const CompoundStmt *stmt) {
965 TransScopeBlock *child_scope_block = trans_scope_block_create(c, parent_scope);
966 for (CompoundStmt::const_body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
967 AstNode *child_node = trans_stmt(c, ResultUsedNo, &child_scope_block->base, *it, TransRValue);
929968 if (child_node == nullptr)
930969 return nullptr;
931970 if (child_node != skip_add_to_block_node)
932 child_block->data.block.statements.append(child_node);
971 child_scope_block->node->data.block.statements.append(child_node);
933972 }
934 return child_block;
973 c->child_scope = &child_scope_block->base;
974 return child_scope_block->node;
935975}
936976
937static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt) {
938 Expr *value_expr = stmt->getRetValue();
977static AstNode *trans_return_stmt(Context *c, TransScope *scope, const ReturnStmt *stmt) {
978 const Expr *value_expr = stmt->getRetValue();
939979 if (value_expr == nullptr) {
940980 return trans_create_node(c, NodeTypeReturnExpr);
941981 } else {
942982 AstNode *return_node = trans_create_node(c, NodeTypeReturnExpr);
943 return_node->data.return_expr.expr = trans_expr(c, true, block, value_expr, TransRValue);
983 return_node->data.return_expr.expr = trans_expr(c, ResultUsedYes, scope, value_expr, TransRValue);
944984 if (return_node->data.return_expr.expr == nullptr)
945985 return nullptr;
946986 return return_node;
947987 }
948988}
949989
950static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) {
990static AstNode *trans_integer_literal(Context *c, const IntegerLiteral *stmt) {
951991 llvm::APSInt result;
952992 if (!stmt->EvaluateAsInt(result, *c->ctx)) {
953993 emit_warning(c, stmt->getLocStart(), "invalid integer literal");
......@@ -956,54 +996,56 @@ static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) {
956996 return trans_create_node_apint(c, result);
957997}
958998
959static AstNode *trans_conditional_operator(Context *c, bool result_used, AstNode *block, ConditionalOperator *stmt) {
999static AstNode *trans_conditional_operator(Context *c, ResultUsed result_used, TransScope *scope,
1000 const ConditionalOperator *stmt)
1001{
9601002 AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
9611003
9621004 Expr *cond_expr = stmt->getCond();
9631005 Expr *true_expr = stmt->getTrueExpr();
9641006 Expr *false_expr = stmt->getFalseExpr();
9651007
966 node->data.if_bool_expr.condition = trans_expr(c, true, block, cond_expr, TransRValue);
1008 node->data.if_bool_expr.condition = trans_expr(c, ResultUsedYes, scope, cond_expr, TransRValue);
9671009 if (node->data.if_bool_expr.condition == nullptr)
9681010 return nullptr;
9691011
970 node->data.if_bool_expr.then_block = trans_expr(c, result_used, block, true_expr, TransRValue);
1012 node->data.if_bool_expr.then_block = trans_expr(c, result_used, scope, true_expr, TransRValue);
9711013 if (node->data.if_bool_expr.then_block == nullptr)
9721014 return nullptr;
9731015
974 node->data.if_bool_expr.else_node = trans_expr(c, result_used, block, false_expr, TransRValue);
1016 node->data.if_bool_expr.else_node = trans_expr(c, result_used, scope, false_expr, TransRValue);
9751017 if (node->data.if_bool_expr.else_node == nullptr)
9761018 return nullptr;
9771019
9781020 return maybe_suppress_result(c, result_used, node);
9791021}
9801022
981static AstNode *trans_create_bin_op(Context *c, AstNode *block, Expr *lhs, BinOpType bin_op, Expr *rhs) {
1023static AstNode *trans_create_bin_op(Context *c, TransScope *scope, Expr *lhs, BinOpType bin_op, Expr *rhs) {
9821024 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
9831025 node->data.bin_op_expr.bin_op = bin_op;
9841026
985 node->data.bin_op_expr.op1 = trans_expr(c, true, block, lhs, TransRValue);
1027 node->data.bin_op_expr.op1 = trans_expr(c, ResultUsedYes, scope, lhs, TransRValue);
9861028 if (node->data.bin_op_expr.op1 == nullptr)
9871029 return nullptr;
9881030
989 node->data.bin_op_expr.op2 = trans_expr(c, true, block, rhs, TransRValue);
1031 node->data.bin_op_expr.op2 = trans_expr(c, ResultUsedYes, scope, rhs, TransRValue);
9901032 if (node->data.bin_op_expr.op2 == nullptr)
9911033 return nullptr;
9921034
9931035 return node;
9941036}
9951037
996static AstNode *trans_create_assign(Context *c, bool result_used, AstNode *block, Expr *lhs, Expr *rhs) {
997 if (!result_used) {
1038static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope, Expr *lhs, Expr *rhs) {
1039 if (result_used == ResultUsedNo) {
9981040 // common case
9991041 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
10001042 node->data.bin_op_expr.bin_op = BinOpTypeAssign;
10011043
1002 node->data.bin_op_expr.op1 = trans_expr(c, true, block, lhs, TransLValue);
1044 node->data.bin_op_expr.op1 = trans_expr(c, ResultUsedYes, scope, lhs, TransLValue);
10031045 if (node->data.bin_op_expr.op1 == nullptr)
10041046 return nullptr;
10051047
1006 node->data.bin_op_expr.op2 = trans_expr(c, true, block, rhs, TransRValue);
1048 node->data.bin_op_expr.op2 = trans_expr(c, ResultUsedYes, scope, rhs, TransRValue);
10071049 if (node->data.bin_op_expr.op2 == nullptr)
10081050 return nullptr;
10091051
......@@ -1017,47 +1059,49 @@ static AstNode *trans_create_assign(Context *c, bool result_used, AstNode *block
10171059 // zig: _tmp
10181060 // zig: }
10191061
1020 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
1062 TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
10211063
10221064 // const _tmp = rhs;
1023 AstNode *rhs_node = trans_expr(c, true, child_block, rhs, TransRValue);
1065 AstNode *rhs_node = trans_expr(c, ResultUsedYes, &child_scope->base, rhs, TransRValue);
10241066 if (rhs_node == nullptr) return nullptr;
10251067 // TODO: avoid name collisions with generated variable names
10261068 Buf* tmp_var_name = buf_create_from_str("_tmp");
10271069 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, rhs_node);
1028 child_block->data.block.statements.append(tmp_var_decl);
1070 child_scope->node->data.block.statements.append(tmp_var_decl);
10291071
10301072 // lhs = _tmp;
1031 AstNode *lhs_node = trans_expr(c, true, child_block, lhs, TransLValue);
1073 AstNode *lhs_node = trans_expr(c, ResultUsedYes, &child_scope->base, lhs, TransLValue);
10321074 if (lhs_node == nullptr) return nullptr;
1033 child_block->data.block.statements.append(
1075 child_scope->node->data.block.statements.append(
10341076 trans_create_node_bin_op(c, lhs_node, BinOpTypeAssign,
10351077 trans_create_node_symbol(c, tmp_var_name)));
10361078
10371079 // _tmp
1038 child_block->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name));
1039 child_block->data.block.last_statement_is_result_expression = true;
1080 child_scope->node->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name));
1081 child_scope->node->data.block.last_statement_is_result_expression = true;
10401082
1041 return child_block;
1083 return child_scope->node;
10421084 }
10431085}
10441086
1045static AstNode *trans_create_shift_op(Context *c, AstNode *block, QualType result_type, Expr *lhs_expr, BinOpType bin_op, Expr *rhs_expr) {
1087static AstNode *trans_create_shift_op(Context *c, TransScope *scope, QualType result_type,
1088 Expr *lhs_expr, BinOpType bin_op, Expr *rhs_expr)
1089{
10461090 const SourceLocation &rhs_location = rhs_expr->getLocStart();
10471091 AstNode *rhs_type = qual_type_to_log2_int_ref(c, result_type, rhs_location);
10481092 // lhs >> u5(rh)
10491093
1050 AstNode *lhs = trans_expr(c, true, block, lhs_expr, TransLValue);
1094 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, lhs_expr, TransLValue);
10511095 if (lhs == nullptr) return nullptr;
10521096
1053 AstNode *rhs = trans_expr(c, true, block, rhs_expr, TransRValue);
1097 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, rhs_expr, TransRValue);
10541098 if (rhs == nullptr) return nullptr;
10551099 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
10561100
10571101 return trans_create_node_bin_op(c, lhs, bin_op, coerced_rhs);
10581102}
10591103
1060static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *block, BinaryOperator *stmt) {
1104static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransScope *scope, const BinaryOperator *stmt) {
10611105 switch (stmt->getOpcode()) {
10621106 case BO_PtrMemD:
10631107 emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_PtrMemD");
......@@ -1066,20 +1110,20 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo
10661110 emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_PtrMemI");
10671111 return nullptr;
10681112 case BO_Mul:
1069 return trans_create_bin_op(c, block, stmt->getLHS(),
1113 return trans_create_bin_op(c, scope, stmt->getLHS(),
10701114 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult,
10711115 stmt->getRHS());
10721116 case BO_Div:
10731117 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
10741118 // unsigned/float division uses the operator
1075 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeDiv, stmt->getRHS());
1119 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeDiv, stmt->getRHS());
10761120 } else {
10771121 // signed integer division uses @divTrunc
10781122 AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "divTrunc");
1079 AstNode *lhs = trans_expr(c, true, block, stmt->getLHS(), TransLValue);
1123 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, stmt->getLHS(), TransLValue);
10801124 if (lhs == nullptr) return nullptr;
10811125 fn_call->data.fn_call_expr.params.append(lhs);
1082 AstNode *rhs = trans_expr(c, true, block, stmt->getRHS(), TransLValue);
1126 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue);
10831127 if (rhs == nullptr) return nullptr;
10841128 fn_call->data.fn_call_expr.params.append(rhs);
10851129 return fn_call;
......@@ -1087,66 +1131,70 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo
10871131 case BO_Rem:
10881132 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
10891133 // unsigned/float division uses the operator
1090 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeMod, stmt->getRHS());
1134 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeMod, stmt->getRHS());
10911135 } else {
10921136 // signed integer division uses @rem
10931137 AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "rem");
1094 AstNode *lhs = trans_expr(c, true, block, stmt->getLHS(), TransLValue);
1138 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, stmt->getLHS(), TransLValue);
10951139 if (lhs == nullptr) return nullptr;
10961140 fn_call->data.fn_call_expr.params.append(lhs);
1097 AstNode *rhs = trans_expr(c, true, block, stmt->getRHS(), TransLValue);
1141 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue);
10981142 if (rhs == nullptr) return nullptr;
10991143 fn_call->data.fn_call_expr.params.append(rhs);
11001144 return fn_call;
11011145 }
11021146 case BO_Add:
1103 return trans_create_bin_op(c, block, stmt->getLHS(),
1147 return trans_create_bin_op(c, scope, stmt->getLHS(),
11041148 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd,
11051149 stmt->getRHS());
11061150 case BO_Sub:
1107 return trans_create_bin_op(c, block, stmt->getLHS(),
1151 return trans_create_bin_op(c, scope, stmt->getLHS(),
11081152 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub,
11091153 stmt->getRHS());
11101154 case BO_Shl:
1111 return trans_create_shift_op(c, block, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS());
1155 return trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS());
11121156 case BO_Shr:
1113 return trans_create_shift_op(c, block, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS());
1157 return trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS());
11141158 case BO_LT:
1115 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS());
1159 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS());
11161160 case BO_GT:
1117 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS());
1161 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS());
11181162 case BO_LE:
1119 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS());
1163 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS());
11201164 case BO_GE:
1121 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS());
1165 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS());
11221166 case BO_EQ:
1123 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpEq, stmt->getRHS());
1167 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpEq, stmt->getRHS());
11241168 case BO_NE:
1125 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeCmpNotEq, stmt->getRHS());
1169 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpNotEq, stmt->getRHS());
11261170 case BO_And:
1127 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeBinAnd, stmt->getRHS());
1171 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinAnd, stmt->getRHS());
11281172 case BO_Xor:
1129 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeBinXor, stmt->getRHS());
1173 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinXor, stmt->getRHS());
11301174 case BO_Or:
1131 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS());
1175 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS());
11321176 case BO_LAnd:
1133 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS());
1177 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS());
11341178 case BO_LOr:
11351179 // TODO: int vs bool
1136 return trans_create_bin_op(c, block, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());
1180 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());
11371181 case BO_Assign:
1138 return trans_create_assign(c, result_used, block, stmt->getLHS(), stmt->getRHS());
1182 return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS());
11391183 case BO_Comma:
11401184 {
1141 block = trans_create_node(c, NodeTypeBlock);
1142 AstNode *lhs = trans_expr(c, false, block, stmt->getLHS(), TransRValue);
1143 if (lhs == nullptr) return nullptr;
1144 block->data.block.statements.append(maybe_suppress_result(c, false, lhs));
1145 AstNode *rhs = trans_expr(c, result_used, block, stmt->getRHS(), TransRValue);
1146 if (rhs == nullptr) return nullptr;
1147 block->data.block.statements.append(maybe_suppress_result(c, result_used, rhs));
1148 block->data.block.last_statement_is_result_expression = true;
1149 return block;
1185 TransScopeBlock *scope_block = trans_scope_block_create(c, scope);
1186 AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, stmt->getLHS(), TransRValue);
1187 if (lhs == nullptr)
1188 return nullptr;
1189 scope_block->node->data.block.statements.append(maybe_suppress_result(c, ResultUsedNo, lhs));
1190
1191 AstNode *rhs = trans_expr(c, result_used, &scope_block->base, stmt->getRHS(), TransRValue);
1192 if (rhs == nullptr)
1193 return nullptr;
1194 scope_block->node->data.block.statements.append(maybe_suppress_result(c, result_used, rhs));
1195
1196 scope_block->node->data.block.last_statement_is_result_expression = true;
1197 return scope_block->node;
11501198 }
11511199 case BO_MulAssign:
11521200 case BO_DivAssign:
......@@ -1164,18 +1212,20 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo
11641212 zig_unreachable();
11651213}
11661214
1167static AstNode *trans_create_compound_assign_shift(Context *c, bool result_used, AstNode *block, CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op) {
1215static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result_used, TransScope *scope,
1216 const CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
1217{
11681218 const SourceLocation &rhs_location = stmt->getRHS()->getLocStart();
11691219 AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location);
11701220
11711221 bool use_intermediate_casts = stmt->getComputationLHSType().getTypePtr() != stmt->getComputationResultType().getTypePtr();
1172 if (!use_intermediate_casts && !result_used) {
1222 if (!use_intermediate_casts && result_used == ResultUsedNo) {
11731223 // simple common case, where the C and Zig are identical:
11741224 // lhs >>= rhs
1175 AstNode *lhs = trans_expr(c, true, block, stmt->getLHS(), TransLValue);
1225 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, stmt->getLHS(), TransLValue);
11761226 if (lhs == nullptr) return nullptr;
11771227
1178 AstNode *rhs = trans_expr(c, true, block, stmt->getRHS(), TransRValue);
1228 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransRValue);
11791229 if (rhs == nullptr) return nullptr;
11801230 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
11811231
......@@ -1190,20 +1240,20 @@ static AstNode *trans_create_compound_assign_shift(Context *c, bool result_used,
11901240 // zig: }
11911241 // where u5 is the appropriate type
11921242
1193 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
1243 TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
11941244
11951245 // const _ref = &lhs;
1196 AstNode *lhs = trans_expr(c, true, child_block, stmt->getLHS(), TransLValue);
1246 AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getLHS(), TransLValue);
11971247 if (lhs == nullptr) return nullptr;
11981248 AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);
11991249 // TODO: avoid name collisions with generated variable names
12001250 Buf* tmp_var_name = buf_create_from_str("_ref");
12011251 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, addr_of_lhs);
1202 child_block->data.block.statements.append(tmp_var_decl);
1252 child_scope->node->data.block.statements.append(tmp_var_decl);
12031253
12041254 // *_ref = result_type(operation_type(*_ref) >> u5(rhs));
12051255
1206 AstNode *rhs = trans_expr(c, true, child_block, stmt->getRHS(), TransRValue);
1256 AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getRHS(), TransRValue);
12071257 if (rhs == nullptr) return nullptr;
12081258 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
12091259
......@@ -1220,27 +1270,29 @@ static AstNode *trans_create_compound_assign_shift(Context *c, bool result_used,
12201270 trans_create_node_symbol(c, tmp_var_name))),
12211271 bin_op,
12221272 coerced_rhs)));
1223 child_block->data.block.statements.append(assign_statement);
1273 child_scope->node->data.block.statements.append(assign_statement);
12241274
1225 if (result_used) {
1275 if (result_used == ResultUsedYes) {
12261276 // *_ref
1227 child_block->data.block.statements.append(
1277 child_scope->node->data.block.statements.append(
12281278 trans_create_node_prefix_op(c, PrefixOpDereference,
12291279 trans_create_node_symbol(c, tmp_var_name)));
1230 child_block->data.block.last_statement_is_result_expression = true;
1280 child_scope->node->data.block.last_statement_is_result_expression = true;
12311281 }
12321282
1233 return child_block;
1283 return child_scope->node;
12341284 }
12351285}
12361286
1237static AstNode *trans_create_compound_assign(Context *c, bool result_used, AstNode *block, CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op) {
1238 if (!result_used) {
1287static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used, TransScope *scope,
1288 const CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
1289{
1290 if (result_used == ResultUsedNo) {
12391291 // simple common case, where the C and Zig are identical:
12401292 // lhs += rhs
1241 AstNode *lhs = trans_expr(c, true, block, stmt->getLHS(), TransLValue);
1293 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, stmt->getLHS(), TransLValue);
12421294 if (lhs == nullptr) return nullptr;
1243 AstNode *rhs = trans_expr(c, true, block, stmt->getRHS(), TransRValue);
1295 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransRValue);
12441296 if (rhs == nullptr) return nullptr;
12451297 return trans_create_node_bin_op(c, lhs, assign_op, rhs);
12461298 } else {
......@@ -1252,20 +1304,20 @@ static AstNode *trans_create_compound_assign(Context *c, bool result_used, AstNo
12521304 // zig: *_ref
12531305 // zig: }
12541306
1255 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
1307 TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
12561308
12571309 // const _ref = &lhs;
1258 AstNode *lhs = trans_expr(c, true, child_block, stmt->getLHS(), TransLValue);
1310 AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getLHS(), TransLValue);
12591311 if (lhs == nullptr) return nullptr;
12601312 AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);
12611313 // TODO: avoid name collisions with generated variable names
12621314 Buf* tmp_var_name = buf_create_from_str("_ref");
12631315 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, addr_of_lhs);
1264 child_block->data.block.statements.append(tmp_var_decl);
1316 child_scope->node->data.block.statements.append(tmp_var_decl);
12651317
12661318 // *_ref = *_ref + rhs;
12671319
1268 AstNode *rhs = trans_expr(c, true, child_block, stmt->getRHS(), TransRValue);
1320 AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getRHS(), TransRValue);
12691321 if (rhs == nullptr) return nullptr;
12701322
12711323 AstNode *assign_statement = trans_create_node_bin_op(c,
......@@ -1277,26 +1329,28 @@ static AstNode *trans_create_compound_assign(Context *c, bool result_used, AstNo
12771329 trans_create_node_symbol(c, tmp_var_name)),
12781330 bin_op,
12791331 rhs));
1280 child_block->data.block.statements.append(assign_statement);
1332 child_scope->node->data.block.statements.append(assign_statement);
12811333
12821334 // *_ref
1283 child_block->data.block.statements.append(
1335 child_scope->node->data.block.statements.append(
12841336 trans_create_node_prefix_op(c, PrefixOpDereference,
12851337 trans_create_node_symbol(c, tmp_var_name)));
1286 child_block->data.block.last_statement_is_result_expression = true;
1338 child_scope->node->data.block.last_statement_is_result_expression = true;
12871339
1288 return child_block;
1340 return child_scope->node;
12891341 }
12901342}
12911343
12921344
1293static AstNode *trans_compound_assign_operator(Context *c, bool result_used, AstNode *block, CompoundAssignOperator *stmt) {
1345static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_used, TransScope *scope,
1346 const CompoundAssignOperator *stmt)
1347{
12941348 switch (stmt->getOpcode()) {
12951349 case BO_MulAssign:
12961350 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
1297 return trans_create_compound_assign(c, result_used, block, stmt, BinOpTypeAssignTimesWrap, BinOpTypeMultWrap);
1351 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimesWrap, BinOpTypeMultWrap);
12981352 else
1299 return trans_create_compound_assign(c, result_used, block, stmt, BinOpTypeAssignTimes, BinOpTypeMult);
1353 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimes, BinOpTypeMult);
13001354 case BO_DivAssign:
13011355 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_DivAssign");
13021356 return nullptr;
......@@ -1305,24 +1359,24 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast
13051359 return nullptr;
13061360 case BO_AddAssign:
13071361 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
1308 return trans_create_compound_assign(c, result_used, block, stmt, BinOpTypeAssignPlusWrap, BinOpTypeAddWrap);
1362 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap, BinOpTypeAddWrap);
13091363 else
1310 return trans_create_compound_assign(c, result_used, block, stmt, BinOpTypeAssignPlus, BinOpTypeAdd);
1364 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlus, BinOpTypeAdd);
13111365 case BO_SubAssign:
13121366 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
1313 return trans_create_compound_assign(c, result_used, block, stmt, BinOpTypeAssignMinusWrap, BinOpTypeSubWrap);
1367 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap, BinOpTypeSubWrap);
13141368 else
1315 return trans_create_compound_assign(c, result_used, block, stmt, BinOpTypeAssignMinus, BinOpTypeSub);
1369 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinus, BinOpTypeSub);
13161370 case BO_ShlAssign:
1317 return trans_create_compound_assign_shift(c, result_used, block, stmt, BinOpTypeAssignBitShiftLeft, BinOpTypeBitShiftLeft);
1371 return trans_create_compound_assign_shift(c, result_used, scope, stmt, BinOpTypeAssignBitShiftLeft, BinOpTypeBitShiftLeft);
13181372 case BO_ShrAssign:
1319 return trans_create_compound_assign_shift(c, result_used, block, stmt, BinOpTypeAssignBitShiftRight, BinOpTypeBitShiftRight);
1373 return trans_create_compound_assign_shift(c, result_used, scope, stmt, BinOpTypeAssignBitShiftRight, BinOpTypeBitShiftRight);
13201374 case BO_AndAssign:
1321 return trans_create_compound_assign(c, result_used, block, stmt, BinOpTypeAssignBitAnd, BinOpTypeBinAnd);
1375 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitAnd, BinOpTypeBinAnd);
13221376 case BO_XorAssign:
1323 return trans_create_compound_assign(c, result_used, block, stmt, BinOpTypeAssignBitXor, BinOpTypeBinXor);
1377 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitXor, BinOpTypeBinXor);
13241378 case BO_OrAssign:
1325 return trans_create_compound_assign(c, result_used, block, stmt, BinOpTypeAssignBitOr, BinOpTypeBinOr);
1379 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitOr, BinOpTypeBinOr);
13261380 case BO_PtrMemD:
13271381 case BO_PtrMemI:
13281382 case BO_Assign:
......@@ -1351,13 +1405,13 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast
13511405 zig_unreachable();
13521406}
13531407
1354static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCastExpr *stmt) {
1408static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const ImplicitCastExpr *stmt) {
13551409 switch (stmt->getCastKind()) {
13561410 case CK_LValueToRValue:
1357 return trans_expr(c, true, block, stmt->getSubExpr(), TransRValue);
1411 return trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
13581412 case CK_IntegralCast:
13591413 {
1360 AstNode *target_node = trans_expr(c, true, block, stmt->getSubExpr(), TransRValue);
1414 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
13611415 if (target_node == nullptr)
13621416 return nullptr;
13631417 return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), target_node);
......@@ -1365,14 +1419,14 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas
13651419 case CK_FunctionToPointerDecay:
13661420 case CK_ArrayToPointerDecay:
13671421 {
1368 AstNode *target_node = trans_expr(c, true, block, stmt->getSubExpr(), TransRValue);
1422 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
13691423 if (target_node == nullptr)
13701424 return nullptr;
13711425 return target_node;
13721426 }
13731427 case CK_BitCast:
13741428 {
1375 AstNode *target_node = trans_expr(c, true, block, stmt->getSubExpr(), TransRValue);
1429 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
13761430 if (target_node == nullptr)
13771431 return nullptr;
13781432
......@@ -1549,8 +1603,8 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas
15491603 zig_unreachable();
15501604}
15511605
1552static AstNode *trans_decl_ref_expr(Context *c, DeclRefExpr *stmt, TransLRValue lrval) {
1553 ValueDecl *value_decl = stmt->getDecl();
1606static AstNode *trans_decl_ref_expr(Context *c, const DeclRefExpr *stmt, TransLRValue lrval) {
1607 const ValueDecl *value_decl = stmt->getDecl();
15541608 Buf *symbol_name = buf_create_from_str(decl_name(value_decl));
15551609 if (lrval == TransLValue) {
15561610 c->ptr_params.put(symbol_name, true);
......@@ -1558,15 +1612,17 @@ static AstNode *trans_decl_ref_expr(Context *c, DeclRefExpr *stmt, TransLRValue
15581612 return trans_create_node_symbol(c, symbol_name);
15591613}
15601614
1561static AstNode *trans_create_post_crement(Context *c, bool result_used, AstNode *block, UnaryOperator *stmt, BinOpType assign_op) {
1615static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, TransScope *scope,
1616 const UnaryOperator *stmt, BinOpType assign_op)
1617{
15621618 Expr *op_expr = stmt->getSubExpr();
15631619
1564 if (!result_used) {
1620 if (result_used == ResultUsedNo) {
15651621 // common case
15661622 // c: expr++
15671623 // zig: expr += 1
15681624 return trans_create_node_bin_op(c,
1569 trans_expr(c, true, block, op_expr, TransLValue),
1625 trans_expr(c, ResultUsedYes, scope, op_expr, TransLValue),
15701626 assign_op,
15711627 trans_create_node_unsigned(c, 1));
15721628 }
......@@ -1578,23 +1634,23 @@ static AstNode *trans_create_post_crement(Context *c, bool result_used, AstNode
15781634 // zig: *_ref += 1;
15791635 // zig: _tmp
15801636 // zig: }
1581 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
1637 TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
15821638
15831639 // const _ref = &expr;
1584 AstNode *expr = trans_expr(c, true, child_block, op_expr, TransLValue);
1640 AstNode *expr = trans_expr(c, ResultUsedYes, &child_scope->base, op_expr, TransLValue);
15851641 if (expr == nullptr) return nullptr;
15861642 AstNode *addr_of_expr = trans_create_node_addr_of(c, false, false, expr);
15871643 // TODO: avoid name collisions with generated variable names
15881644 Buf* ref_var_name = buf_create_from_str("_ref");
15891645 AstNode *ref_var_decl = trans_create_node_var_decl_local(c, true, ref_var_name, nullptr, addr_of_expr);
1590 child_block->data.block.statements.append(ref_var_decl);
1646 child_scope->node->data.block.statements.append(ref_var_decl);
15911647
15921648 // const _tmp = *_ref;
15931649 Buf* tmp_var_name = buf_create_from_str("_tmp");
15941650 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr,
15951651 trans_create_node_prefix_op(c, PrefixOpDereference,
15961652 trans_create_node_symbol(c, ref_var_name)));
1597 child_block->data.block.statements.append(tmp_var_decl);
1653 child_scope->node->data.block.statements.append(tmp_var_decl);
15981654
15991655 // *_ref += 1;
16001656 AstNode *assign_statement = trans_create_node_bin_op(c,
......@@ -1602,24 +1658,26 @@ static AstNode *trans_create_post_crement(Context *c, bool result_used, AstNode
16021658 trans_create_node_symbol(c, ref_var_name)),
16031659 assign_op,
16041660 trans_create_node_unsigned(c, 1));
1605 child_block->data.block.statements.append(assign_statement);
1661 child_scope->node->data.block.statements.append(assign_statement);
16061662
16071663 // _tmp
1608 child_block->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name));
1609 child_block->data.block.last_statement_is_result_expression = true;
1664 child_scope->node->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name));
1665 child_scope->node->data.block.last_statement_is_result_expression = true;
16101666
1611 return child_block;
1667 return child_scope->node;
16121668}
16131669
1614static AstNode *trans_create_pre_crement(Context *c, bool result_used, AstNode *block, UnaryOperator *stmt, BinOpType assign_op) {
1670static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, TransScope *scope,
1671 const UnaryOperator *stmt, BinOpType assign_op)
1672{
16151673 Expr *op_expr = stmt->getSubExpr();
16161674
1617 if (!result_used) {
1675 if (result_used == ResultUsedNo) {
16181676 // common case
16191677 // c: ++expr
16201678 // zig: expr += 1
16211679 return trans_create_node_bin_op(c,
1622 trans_expr(c, true, block, op_expr, TransLValue),
1680 trans_expr(c, ResultUsedYes, scope, op_expr, TransLValue),
16231681 assign_op,
16241682 trans_create_node_unsigned(c, 1));
16251683 }
......@@ -1630,16 +1688,16 @@ static AstNode *trans_create_pre_crement(Context *c, bool result_used, AstNode *
16301688 // zig: *_ref += 1;
16311689 // zig: *_ref
16321690 // zig: }
1633 AstNode *child_block = trans_create_node(c, NodeTypeBlock);
1691 TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
16341692
16351693 // const _ref = &expr;
1636 AstNode *expr = trans_expr(c, true, child_block, op_expr, TransLValue);
1694 AstNode *expr = trans_expr(c, ResultUsedYes, &child_scope->base, op_expr, TransLValue);
16371695 if (expr == nullptr) return nullptr;
16381696 AstNode *addr_of_expr = trans_create_node_addr_of(c, false, false, expr);
16391697 // TODO: avoid name collisions with generated variable names
16401698 Buf* ref_var_name = buf_create_from_str("_ref");
16411699 AstNode *ref_var_decl = trans_create_node_var_decl_local(c, true, ref_var_name, nullptr, addr_of_expr);
1642 child_block->data.block.statements.append(ref_var_decl);
1700 child_scope->node->data.block.statements.append(ref_var_decl);
16431701
16441702 // *_ref += 1;
16451703 AstNode *assign_statement = trans_create_node_bin_op(c,
......@@ -1647,49 +1705,49 @@ static AstNode *trans_create_pre_crement(Context *c, bool result_used, AstNode *
16471705 trans_create_node_symbol(c, ref_var_name)),
16481706 assign_op,
16491707 trans_create_node_unsigned(c, 1));
1650 child_block->data.block.statements.append(assign_statement);
1708 child_scope->node->data.block.statements.append(assign_statement);
16511709
16521710 // *_ref
16531711 AstNode *deref_expr = trans_create_node_prefix_op(c, PrefixOpDereference,
16541712 trans_create_node_symbol(c, ref_var_name));
1655 child_block->data.block.statements.append(deref_expr);
1656 child_block->data.block.last_statement_is_result_expression = true;
1713 child_scope->node->data.block.statements.append(deref_expr);
1714 child_scope->node->data.block.last_statement_is_result_expression = true;
16571715
1658 return child_block;
1716 return child_scope->node;
16591717}
16601718
1661static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *block, UnaryOperator *stmt) {
1719static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransScope *scope, const UnaryOperator *stmt) {
16621720 switch (stmt->getOpcode()) {
16631721 case UO_PostInc:
16641722 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
1665 return trans_create_post_crement(c, result_used, block, stmt, BinOpTypeAssignPlusWrap);
1723 return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap);
16661724 else
1667 return trans_create_post_crement(c, result_used, block, stmt, BinOpTypeAssignPlus);
1725 return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus);
16681726 case UO_PostDec:
16691727 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
1670 return trans_create_post_crement(c, result_used, block, stmt, BinOpTypeAssignMinusWrap);
1728 return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap);
16711729 else
1672 return trans_create_post_crement(c, result_used, block, stmt, BinOpTypeAssignMinus);
1730 return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus);
16731731 case UO_PreInc:
16741732 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
1675 return trans_create_pre_crement(c, result_used, block, stmt, BinOpTypeAssignPlusWrap);
1733 return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap);
16761734 else
1677 return trans_create_pre_crement(c, result_used, block, stmt, BinOpTypeAssignPlus);
1735 return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus);
16781736 case UO_PreDec:
16791737 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
1680 return trans_create_pre_crement(c, result_used, block, stmt, BinOpTypeAssignMinusWrap);
1738 return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap);
16811739 else
1682 return trans_create_pre_crement(c, result_used, block, stmt, BinOpTypeAssignMinus);
1740 return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus);
16831741 case UO_AddrOf:
16841742 {
1685 AstNode *value_node = trans_expr(c, result_used, block, stmt->getSubExpr(), TransLValue);
1743 AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue);
16861744 if (value_node == nullptr)
16871745 return value_node;
16881746 return trans_create_node_addr_of(c, false, false, value_node);
16891747 }
16901748 case UO_Deref:
16911749 {
1692 AstNode *value_node = trans_expr(c, result_used, block, stmt->getSubExpr(), TransRValue);
1750 AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue);
16931751 if (value_node == nullptr)
16941752 return nullptr;
16951753 bool is_fn_ptr = qual_type_is_fn_ptr(c, stmt->getSubExpr()->getType());
......@@ -1708,7 +1766,7 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc
17081766 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
17091767 node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
17101768
1711 node->data.prefix_op_expr.primary_expr = trans_expr(c, true, block, op_expr, TransRValue);
1769 node->data.prefix_op_expr.primary_expr = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
17121770 if (node->data.prefix_op_expr.primary_expr == nullptr)
17131771 return nullptr;
17141772
......@@ -1718,7 +1776,7 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc
17181776 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
17191777 node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0);
17201778
1721 node->data.bin_op_expr.op2 = trans_expr(c, true, block, op_expr, TransRValue);
1779 node->data.bin_op_expr.op2 = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
17221780 if (node->data.bin_op_expr.op2 == nullptr)
17231781 return nullptr;
17241782
......@@ -1751,7 +1809,7 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc
17511809 zig_unreachable();
17521810}
17531811
1754static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *stmt) {
1812static AstNode *trans_local_declaration(Context *c, TransScope *scope, const DeclStmt *stmt) {
17551813 for (auto iter = stmt->decl_begin(); iter != stmt->decl_end(); iter++) {
17561814 Decl *decl = *iter;
17571815 switch (decl->getKind()) {
......@@ -1760,7 +1818,7 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st
17601818 QualType qual_type = var_decl->getTypeSourceInfo()->getType();
17611819 AstNode *init_node = nullptr;
17621820 if (var_decl->hasInit()) {
1763 init_node = trans_expr(c, true, block, var_decl->getInit(), TransRValue);
1821 init_node = trans_expr(c, ResultUsedYes, scope, var_decl->getInit(), TransRValue);
17641822 if (init_node == nullptr)
17651823 return nullptr;
17661824
......@@ -1773,7 +1831,10 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st
17731831
17741832 AstNode *node = trans_create_node_var_decl_local(c, qual_type.isConstQualified(),
17751833 symbol_name, type_node, init_node);
1776 block->data.block.statements.append(node);
1834
1835 assert(scope->id == TransScopeIdBlock);
1836 TransScopeBlock *scope_block = (TransScopeBlock *)scope;
1837 scope_block->node->data.block.statements.append(node);
17771838 continue;
17781839 }
17791840 case Decl::AccessSpec:
......@@ -2000,37 +2061,37 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st
20002061 return skip_add_to_block_node;
20012062}
20022063
2003static AstNode *trans_while_loop(Context *c, AstNode *block, WhileStmt *stmt) {
2064static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt *stmt) {
20042065 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
20052066
2006 while_node->data.while_expr.condition = trans_expr(c, true, block, stmt->getCond(), TransRValue);
2067 while_node->data.while_expr.condition = trans_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
20072068 if (while_node->data.while_expr.condition == nullptr)
20082069 return nullptr;
20092070
2010 while_node->data.while_expr.body = trans_stmt(c, false, block, stmt->getBody(), TransRValue);
2071 while_node->data.while_expr.body = trans_stmt(c, ResultUsedNo, scope, stmt->getBody(), TransRValue);
20112072 if (while_node->data.while_expr.body == nullptr)
20122073 return nullptr;
20132074
20142075 return while_node;
20152076}
20162077
2017static AstNode *trans_if_statement(Context *c, AstNode *block, IfStmt *stmt) {
2078static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt *stmt) {
20182079 // if (c) t
20192080 // if (c) t else e
20202081 AstNode *if_node = trans_create_node(c, NodeTypeIfBoolExpr);
20212082
20222083 // TODO: condition != 0
2023 AstNode *condition_node = trans_expr(c, true, block, stmt->getCond(), TransRValue);
2084 AstNode *condition_node = trans_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
20242085 if (condition_node == nullptr)
20252086 return nullptr;
20262087 if_node->data.if_bool_expr.condition = condition_node;
20272088
2028 if_node->data.if_bool_expr.then_block = trans_stmt(c, false, block, stmt->getThen(), TransRValue);
2089 if_node->data.if_bool_expr.then_block = trans_stmt(c, ResultUsedNo, scope, stmt->getThen(), TransRValue);
20292090 if (if_node->data.if_bool_expr.then_block == nullptr)
20302091 return nullptr;
20312092
20322093 if (stmt->getElse() != nullptr) {
2033 if_node->data.if_bool_expr.else_node = trans_stmt(c, false, block, stmt->getElse(), TransRValue);
2094 if_node->data.if_bool_expr.else_node = trans_stmt(c, ResultUsedNo, scope, stmt->getElse(), TransRValue);
20342095 if (if_node->data.if_bool_expr.else_node == nullptr)
20352096 return nullptr;
20362097 }
......@@ -2038,10 +2099,10 @@ static AstNode *trans_if_statement(Context *c, AstNode *block, IfStmt *stmt) {
20382099 return if_node;
20392100}
20402101
2041static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, CallExpr *stmt) {
2102static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *scope, const CallExpr *stmt) {
20422103 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
20432104
2044 AstNode *callee_raw_node = trans_expr(c, true, block, stmt->getCallee(), TransRValue);
2105 AstNode *callee_raw_node = trans_expr(c, ResultUsedYes, scope, stmt->getCallee(), TransRValue);
20452106 if (callee_raw_node == nullptr)
20462107 return nullptr;
20472108
......@@ -2055,9 +2116,9 @@ static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, Ca
20552116 node->data.fn_call_expr.fn_ref_expr = callee_node;
20562117
20572118 unsigned num_args = stmt->getNumArgs();
2058 Expr **args = stmt->getArgs();
2119 const Expr * const* args = stmt->getArgs();
20592120 for (unsigned i = 0; i < num_args; i += 1) {
2060 AstNode *arg_node = trans_expr(c, true, block, args[i], TransRValue);
2121 AstNode *arg_node = trans_expr(c, ResultUsedYes, scope, args[i], TransRValue);
20612122 if (arg_node == nullptr)
20622123 return nullptr;
20632124
......@@ -2067,8 +2128,8 @@ static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, Ca
20672128 return node;
20682129}
20692130
2070static AstNode *trans_member_expr(Context *c, AstNode *block, MemberExpr *stmt) {
2071 AstNode *container_node = trans_expr(c, true, block, stmt->getBase(), TransRValue);
2131static AstNode *trans_member_expr(Context *c, TransScope *scope, const MemberExpr *stmt) {
2132 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);
20722133 if (container_node == nullptr)
20732134 return nullptr;
20742135
......@@ -2082,12 +2143,12 @@ static AstNode *trans_member_expr(Context *c, AstNode *block, MemberExpr *stmt)
20822143 return node;
20832144}
20842145
2085static AstNode *trans_array_subscript_expr(Context *c, AstNode *block, ArraySubscriptExpr *stmt) {
2086 AstNode *container_node = trans_expr(c, true, block, stmt->getBase(), TransRValue);
2146static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const ArraySubscriptExpr *stmt) {
2147 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);
20872148 if (container_node == nullptr)
20882149 return nullptr;
20892150
2090 AstNode *idx_node = trans_expr(c, true, block, stmt->getIdx(), TransRValue);
2151 AstNode *idx_node = trans_expr(c, ResultUsedYes, scope, stmt->getIdx(), TransRValue);
20912152 if (idx_node == nullptr)
20922153 return nullptr;
20932154
......@@ -2098,17 +2159,19 @@ static AstNode *trans_array_subscript_expr(Context *c, AstNode *block, ArraySubs
20982159 return node;
20992160}
21002161
2101static AstNode *trans_c_style_cast_expr(Context *c, bool result_used, AstNode *block,
2102 CStyleCastExpr *stmt, TransLRValue lrvalue)
2162static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, TransScope *scope,
2163 const CStyleCastExpr *stmt, TransLRValue lrvalue)
21032164{
2104 AstNode *sub_expr_node = trans_expr(c, result_used, block, stmt->getSubExpr(), lrvalue);
2165 AstNode *sub_expr_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), lrvalue);
21052166 if (sub_expr_node == nullptr)
21062167 return nullptr;
21072168
21082169 return trans_c_cast(c, stmt->getLocStart(), stmt->getType(), sub_expr_node);
21092170}
21102171
2111static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, AstNode *block, UnaryExprOrTypeTraitExpr *stmt) {
2172static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scope,
2173 const UnaryExprOrTypeTraitExpr *stmt)
2174{
21122175 AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getLocStart());
21132176 if (type_node == nullptr)
21142177 return nullptr;
......@@ -2118,7 +2181,7 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, AstNode *block,
21182181 return node;
21192182}
21202183
2121static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) {
2184static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt *stmt) {
21222185 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
21232186
21242187 AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral);
......@@ -2126,6 +2189,7 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) {
21262189 while_node->data.while_expr.condition = true_node;
21272190
21282191 AstNode *body_node;
2192 TransScope *child_scope;
21292193 if (stmt->getBody()->getStmtClass() == Stmt::CompoundStmtClass) {
21302194 // there's already a block in C, so we'll append our condition to it.
21312195 // c: do {
......@@ -2137,9 +2201,10 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) {
21372201 // zig: b;
21382202 // zig: if (!cond) break;
21392203 // zig: }
2140 body_node = trans_stmt(c, false, block, stmt->getBody(), TransRValue);
2204 body_node = trans_stmt(c, ResultUsedNo, parent_scope, stmt->getBody(), TransRValue);
21412205 if (body_node == nullptr) return nullptr;
21422206 assert(body_node->type == NodeTypeBlock);
2207 child_scope = c->child_scope;
21432208 } else {
21442209 // the C statement is without a block, so we need to create a block to contain it.
21452210 // c: do
......@@ -2149,63 +2214,103 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) {
21492214 // zig: a;
21502215 // zig: if (!cond) break;
21512216 // zig: }
2152 body_node = trans_create_node(c, NodeTypeBlock);
2153 AstNode *child_statement = trans_stmt(c, false, body_node, stmt->getBody(), TransRValue);
2217 TransScopeBlock *child_block_scope = trans_scope_block_create(c, parent_scope);
2218 body_node = child_block_scope->node;
2219 child_scope = &child_block_scope->base;
2220 AstNode *child_statement = trans_stmt(c, ResultUsedNo, child_scope, stmt->getBody(), TransRValue);
21542221 if (child_statement == nullptr) return nullptr;
2155 body_node->data.block.statements.append(child_statement);
2222 child_block_scope->node->data.block.statements.append(child_statement);
21562223 }
21572224
21582225 // if (!cond) break;
2159 AstNode *condition_node = trans_expr(c, true, body_node, stmt->getCond(), TransRValue);
2226 AstNode *condition_node = trans_expr(c, ResultUsedYes, child_scope, stmt->getCond(), TransRValue);
21602227 if (condition_node == nullptr) return nullptr;
21612228 AstNode *terminator_node = trans_create_node(c, NodeTypeIfBoolExpr);
21622229 terminator_node->data.if_bool_expr.condition = trans_create_node_prefix_op(c, PrefixOpBoolNot, condition_node);
21632230 terminator_node->data.if_bool_expr.then_block = trans_create_node(c, NodeTypeBreak);
2164 body_node->data.block.statements.append(terminator_node);
2231
2232 assert(child_scope->id == TransScopeIdBlock);
2233 TransScopeBlock *child_block_scope = (TransScopeBlock *)child_scope;
2234
2235 child_block_scope->node->data.block.statements.append(terminator_node);
21652236
21662237 while_node->data.while_expr.body = body_node;
21672238
21682239 return while_node;
21692240}
21702241
2171static AstNode *trans_for_loop(Context *c, AstNode *block, ForStmt *stmt) {
2242//static AstNode *trans_switch_stmt(Context *c, TransScope *scope, const SwitchStmt *stmt) {
2243// AstNode *switch_block_node = trans_create_node(c, NodeTypeBlock);
2244// AstNode *switch_node = trans_create_node(c, NodeTypeSwitchExpr);
2245// const DeclStmt *var_decl_stmt = stmt->getConditionVariableDeclStmt();
2246// if (var_decl_stmt != nullptr) {
2247// AstNode *vars_node = trans_stmt(c, ResultUsedNo, switch_block_node, var_decl_stmt, TransRValue);
2248// if (vars_node == nullptr)
2249// return nullptr;
2250// if (vars_node != skip_add_to_block_node)
2251// switch_block_node->data.block.statements.append(vars_node);
2252// }
2253// switch_block_node->data.block.statements.append(switch_node);
2254//
2255// const Expr *cond_expr = stmt->getCond();
2256// assert(cond_expr != nullptr);
2257//
2258// AstNode *expr_node = trans_expr(c, ResultUsedYes, switch_block_node, cond_expr, TransRValue);
2259// if (expr_node == nullptr)
2260// return nullptr;
2261// switch_node->data.switch_expr.expr = expr_node;
2262//
2263// AstNode *body_node = trans_stmt(c, ResultUsedNo, switch_block_node, stmt->getBody(), TransRValue);
2264// if (body_node == nullptr)
2265// return nullptr;
2266// if (body_node != skip_add_to_block_node)
2267// switch_block_node->data.block.statements.append(body_node);
2268//
2269// return switch_block_node;
2270//}
2271
2272static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForStmt *stmt) {
21722273 AstNode *loop_block_node;
2274 TransScope *condition_scope;
21732275 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
2174 Stmt *init_stmt = stmt->getInit();
2276 const Stmt *init_stmt = stmt->getInit();
21752277 if (init_stmt == nullptr) {
21762278 loop_block_node = while_node;
2279 condition_scope = parent_scope;
21772280 } else {
2178 loop_block_node = trans_create_node(c, NodeTypeBlock);
2281 TransScopeBlock *child_scope = trans_scope_block_create(c, parent_scope);
2282 loop_block_node = child_scope->node;
2283 condition_scope = &child_scope->base;
21792284
2180 AstNode *vars_node = trans_stmt(c, false, loop_block_node, init_stmt, TransRValue);
2285 AstNode *vars_node = trans_stmt(c, ResultUsedNo, &child_scope->base, init_stmt, TransRValue);
21812286 if (vars_node == nullptr)
21822287 return nullptr;
21832288 if (vars_node != skip_add_to_block_node)
2184 loop_block_node->data.block.statements.append(vars_node);
2289 child_scope->node->data.block.statements.append(vars_node);
21852290
2186 loop_block_node->data.block.statements.append(while_node);
2291 child_scope->node->data.block.statements.append(while_node);
21872292 }
21882293
2189 Stmt *cond_stmt = stmt->getCond();
2294 const Stmt *cond_stmt = stmt->getCond();
21902295 if (cond_stmt == nullptr) {
21912296 AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral);
21922297 true_node->data.bool_literal.value = true;
21932298 while_node->data.while_expr.condition = true_node;
21942299 } else {
2195 while_node->data.while_expr.condition = trans_stmt(c, false, loop_block_node, cond_stmt, TransRValue);
2300 while_node->data.while_expr.condition = trans_stmt(c, ResultUsedNo, condition_scope, cond_stmt, TransRValue);
21962301 if (while_node->data.while_expr.condition == nullptr)
21972302 return nullptr;
21982303 }
21992304
2200 Stmt *inc_stmt = stmt->getInc();
2305 const Stmt *inc_stmt = stmt->getInc();
22012306 if (inc_stmt != nullptr) {
2202 AstNode *inc_node = trans_stmt(c, false, loop_block_node, inc_stmt, TransRValue);
2307 AstNode *inc_node = trans_stmt(c, ResultUsedNo, condition_scope, inc_stmt, TransRValue);
22032308 if (inc_node == nullptr)
22042309 return nullptr;
22052310 while_node->data.while_expr.continue_expr = inc_node;
22062311 }
22072312
2208 AstNode *child_statement = trans_stmt(c, false, loop_block_node, stmt->getBody(), TransRValue);
2313 AstNode *child_statement = trans_stmt(c, ResultUsedNo, condition_scope, stmt->getBody(), TransRValue);
22092314 if (child_statement == nullptr)
22102315 return nullptr;
22112316 while_node->data.while_expr.body = child_statement;
......@@ -2213,7 +2318,7 @@ static AstNode *trans_for_loop(Context *c, AstNode *block, ForStmt *stmt) {
22132318 return loop_block_node;
22142319}
22152320
2216static AstNode *trans_string_literal(Context *c, AstNode *block, StringLiteral *stmt) {
2321static AstNode *trans_string_literal(Context *c, TransScope *scope, const StringLiteral *stmt) {
22172322 switch (stmt->getKind()) {
22182323 case StringLiteral::Ascii:
22192324 case StringLiteral::UTF8:
......@@ -2231,72 +2336,75 @@ static AstNode *trans_string_literal(Context *c, AstNode *block, StringLiteral *
22312336 zig_unreachable();
22322337}
22332338
2234static AstNode *trans_break_stmt(Context *c, AstNode *block, BreakStmt *stmt) {
2339static AstNode *trans_break_stmt(Context *c, TransScope *scope, const BreakStmt *stmt) {
22352340 return trans_create_node(c, NodeTypeBreak);
22362341}
22372342
2238static AstNode *trans_continue_stmt(Context *c, AstNode *block, ContinueStmt *stmt) {
2343static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const ContinueStmt *stmt) {
22392344 return trans_create_node(c, NodeTypeContinue);
22402345}
22412346
2242static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) {
2347static AstNode *trans_stmt(Context *c, ResultUsed result_used, TransScope *scope, const Stmt *stmt, TransLRValue lrvalue) {
2348 c->child_scope = scope; // TODO refactor out
22432349 Stmt::StmtClass sc = stmt->getStmtClass();
22442350 switch (sc) {
22452351 case Stmt::ReturnStmtClass:
2246 return trans_return_stmt(c, block, (ReturnStmt *)stmt);
2352 return trans_return_stmt(c, scope, (const ReturnStmt *)stmt);
22472353 case Stmt::CompoundStmtClass:
2248 return trans_compound_stmt(c, block, (CompoundStmt *)stmt);
2354 return trans_compound_stmt(c, scope, (const CompoundStmt *)stmt);
22492355 case Stmt::IntegerLiteralClass:
2250 return trans_integer_literal(c, (IntegerLiteral *)stmt);
2356 return trans_integer_literal(c, (const IntegerLiteral *)stmt);
22512357 case Stmt::ConditionalOperatorClass:
2252 return trans_conditional_operator(c, result_used, block, (ConditionalOperator *)stmt);
2358 return trans_conditional_operator(c, result_used, scope, (const ConditionalOperator *)stmt);
22532359 case Stmt::BinaryOperatorClass:
2254 return trans_binary_operator(c, result_used, block, (BinaryOperator *)stmt);
2360 return trans_binary_operator(c, result_used, scope, (const BinaryOperator *)stmt);
22552361 case Stmt::CompoundAssignOperatorClass:
2256 return trans_compound_assign_operator(c, result_used, block, (CompoundAssignOperator *)stmt);
2362 return trans_compound_assign_operator(c, result_used, scope, (const CompoundAssignOperator *)stmt);
22572363 case Stmt::ImplicitCastExprClass:
2258 return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt);
2364 return trans_implicit_cast_expr(c, scope, (const ImplicitCastExpr *)stmt);
22592365 case Stmt::DeclRefExprClass:
2260 return trans_decl_ref_expr(c, (DeclRefExpr *)stmt, lrvalue);
2366 return trans_decl_ref_expr(c, (const DeclRefExpr *)stmt, lrvalue);
22612367 case Stmt::UnaryOperatorClass:
2262 return trans_unary_operator(c, result_used, block, (UnaryOperator *)stmt);
2368 return trans_unary_operator(c, result_used, scope, (const UnaryOperator *)stmt);
22632369 case Stmt::DeclStmtClass:
2264 return trans_local_declaration(c, block, (DeclStmt *)stmt);
2370 return trans_local_declaration(c, scope, (const DeclStmt *)stmt);
22652371 case Stmt::WhileStmtClass:
2266 return trans_while_loop(c, block, (WhileStmt *)stmt);
2372 return trans_while_loop(c, scope, (const WhileStmt *)stmt);
22672373 case Stmt::IfStmtClass:
2268 return trans_if_statement(c, block, (IfStmt *)stmt);
2374 return trans_if_statement(c, scope, (const IfStmt *)stmt);
22692375 case Stmt::CallExprClass:
2270 return trans_call_expr(c, result_used, block, (CallExpr *)stmt);
2376 return trans_call_expr(c, result_used, scope, (const CallExpr *)stmt);
22712377 case Stmt::NullStmtClass:
22722378 return skip_add_to_block_node;
22732379 case Stmt::MemberExprClass:
2274 return trans_member_expr(c, block, (MemberExpr *)stmt);
2380 return trans_member_expr(c, scope, (const MemberExpr *)stmt);
22752381 case Stmt::ArraySubscriptExprClass:
2276 return trans_array_subscript_expr(c, block, (ArraySubscriptExpr *)stmt);
2382 return trans_array_subscript_expr(c, scope, (const ArraySubscriptExpr *)stmt);
22772383 case Stmt::CStyleCastExprClass:
2278 return trans_c_style_cast_expr(c, result_used, block, (CStyleCastExpr *)stmt, lrvalue);
2384 return trans_c_style_cast_expr(c, result_used, scope, (const CStyleCastExpr *)stmt, lrvalue);
22792385 case Stmt::UnaryExprOrTypeTraitExprClass:
2280 return trans_unary_expr_or_type_trait_expr(c, block, (UnaryExprOrTypeTraitExpr *)stmt);
2386 return trans_unary_expr_or_type_trait_expr(c, scope, (const UnaryExprOrTypeTraitExpr *)stmt);
22812387 case Stmt::DoStmtClass:
2282 return trans_do_loop(c, block, (DoStmt *)stmt);
2388 return trans_do_loop(c, scope, (const DoStmt *)stmt);
22832389 case Stmt::ForStmtClass:
2284 return trans_for_loop(c, block, (ForStmt *)stmt);
2390 return trans_for_loop(c, scope, (const ForStmt *)stmt);
22852391 case Stmt::StringLiteralClass:
2286 return trans_string_literal(c, block, (StringLiteral *)stmt);
2392 return trans_string_literal(c, scope, (const StringLiteral *)stmt);
22872393 case Stmt::BreakStmtClass:
2288 return trans_break_stmt(c, block, (BreakStmt *)stmt);
2394 return trans_break_stmt(c, scope, (const BreakStmt *)stmt);
22892395 case Stmt::ContinueStmtClass:
2290 return trans_continue_stmt(c, block, (ContinueStmt *)stmt);
2396 return trans_continue_stmt(c, scope, (const ContinueStmt *)stmt);
2397// case Stmt::SwitchStmtClass:
2398// return trans_switch_stmt(c, scope, (const SwitchStmt *)stmt);
2399 case Stmt::SwitchStmtClass:
2400 emit_warning(c, stmt->getLocStart(), "TODO handle C SwitchStmtClass");
2401 return nullptr;
22912402 case Stmt::CaseStmtClass:
22922403 emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass");
22932404 return nullptr;
22942405 case Stmt::DefaultStmtClass:
22952406 emit_warning(c, stmt->getLocStart(), "TODO handle C DefaultStmtClass");
22962407 return nullptr;
2297 case Stmt::SwitchStmtClass:
2298 emit_warning(c, stmt->getLocStart(), "TODO handle C SwitchStmtClass");
2299 return nullptr;
23002408 case Stmt::NoStmtClass:
23012409 emit_warning(c, stmt->getLocStart(), "TODO handle C NoStmtClass");
23022410 return nullptr;
......@@ -2584,7 +2692,7 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s
25842692 emit_warning(c, stmt->getLocStart(), "TODO handle C PackExpansionExprClass");
25852693 return nullptr;
25862694 case Stmt::ParenExprClass:
2587 return trans_expr(c, result_used, block, ((ParenExpr*)stmt)->getSubExpr(), lrvalue);
2695 return trans_expr(c, result_used, scope, ((const ParenExpr*)stmt)->getSubExpr(), lrvalue);
25882696 case Stmt::ParenListExprClass:
25892697 emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass");
25902698 return nullptr;
......@@ -2838,10 +2946,13 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
28382946 return;
28392947 }
28402948
2949 TransScope *scope = nullptr;
2950
28412951 for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
28422952 AstNode *param_node = proto_node->data.fn_proto.params.at(i);
28432953 const ParmVarDecl *param = fn_decl->getParamDecl(i);
28442954 const char *name = decl_name(param);
2955
28452956 Buf *proto_param_name;
28462957 if (strlen(name) != 0) {
28472958 proto_param_name = buf_create_from_str(name);
......@@ -2851,7 +2962,11 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
28512962 proto_param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
28522963 }
28532964 }
2854 param_node->data.param_decl.name = proto_param_name;
2965
2966 TransScopeVar *scope_var = trans_scope_var_create(c, scope, proto_param_name);
2967 scope = &scope_var->base;
2968
2969 param_node->data.param_decl.name = scope_var->zig_name;
28552970 }
28562971
28572972 if (!fn_decl->hasBody()) {
......@@ -2863,7 +2978,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
28632978 // actual function definition with body
28642979 c->ptr_params.clear();
28652980 Stmt *body = fn_decl->getBody();
2866 AstNode *actual_body_node = trans_stmt(c, false, nullptr, body, TransRValue);
2981 AstNode *actual_body_node = trans_stmt(c, ResultUsedNo, scope, body, TransRValue);
28672982 assert(actual_body_node != skip_add_to_block_node);
28682983 if (actual_body_node == nullptr) {
28692984 emit_warning(c, fn_decl->getLocation(), "unable to translate function");
......@@ -3301,14 +3416,66 @@ static bool decl_visitor(void *context, const Decl *decl) {
33013416 return true;
33023417}
33033418
3304static bool name_exists(Context *c, Buf *name) {
3419static bool name_exists_global(Context *c, Buf *name) {
33053420 return get_global(c, name) != nullptr;
33063421}
33073422
3423static bool name_exists_scope(Context *c, Buf *name, TransScope *scope) {
3424 while (scope != nullptr) {
3425 if (scope->id == TransScopeIdVar) {
3426 TransScopeVar *var_scope = (TransScopeVar *)scope;
3427 if (buf_eql_buf(name, var_scope->zig_name)) {
3428 return true;
3429 }
3430 }
3431 scope = scope->parent;
3432 }
3433 return name_exists_global(c, name);
3434}
3435
3436static Buf *get_unique_name(Context *c, Buf *name, TransScope *scope) {
3437 Buf *proposed_name = name;
3438 int count = 0;
3439 while (name_exists_scope(c, proposed_name, scope)) {
3440 if (proposed_name == name) {
3441 proposed_name = buf_alloc();
3442 }
3443 buf_resize(proposed_name, 0);
3444 buf_appendf(proposed_name, "%s_%d", buf_ptr(name), count);
3445 count += 1;
3446 }
3447 return proposed_name;
3448}
3449
3450static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope) {
3451 TransScopeBlock *result = allocate<TransScopeBlock>(1);
3452 result->base.id = TransScopeIdBlock;
3453 result->base.parent = parent_scope;
3454 result->node = trans_create_node(c, NodeTypeBlock);
3455 return result;
3456}
3457
3458static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name) {
3459 TransScopeVar *result = allocate<TransScopeVar>(1);
3460 result->base.id = TransScopeIdVar;
3461 result->base.parent = parent_scope;
3462 result->c_name = wanted_name;
3463 result->zig_name = get_unique_name(c, wanted_name, parent_scope);
3464 return result;
3465}
3466
3467//static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope) {
3468// TransScopeSwitch *result = allocate<TransScopeSwitch>(1);
3469// result->base.id = TransScopeIdSwitch;
3470// result->base.parent = parent_scope;
3471// result->switch_node = trans_create_node(c, NodeTypeSwitchExpr);
3472// return result;
3473//}
3474
33083475static void render_aliases(Context *c) {
33093476 for (size_t i = 0; i < c->aliases.length; i += 1) {
33103477 Alias *alias = &c->aliases.at(i);
3311 if (name_exists(c, alias->new_name))
3478 if (name_exists_global(c, alias->new_name))
33123479 continue;
33133480
33143481 add_global_var(c, alias->new_name, trans_create_node_symbol(c, alias->canon_name));
......@@ -3438,7 +3605,7 @@ static void process_symbol_macros(Context *c) {
34383605
34393606 // Check if this macro aliases another top level declaration
34403607 AstNode *existing_node = get_global(c, ms.value);
3441 if (!existing_node || name_exists(c, ms.name))
3608 if (!existing_node || name_exists_global(c, ms.name))
34423609 continue;
34433610
34443611 // If a macro aliases a global variable which is a function pointer, we conclude that
......@@ -3487,7 +3654,7 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) {
34873654 continue;
34883655 }
34893656 Buf *name = buf_create_from_str(raw_name);
3490 if (name_exists(c, name)) {
3657 if (name_exists_global(c, name)) {
34913658 continue;
34923659 }
34933660
test/translate_c.zig+51
......@@ -963,6 +963,16 @@ pub fn addCases(cases: &tests.TranslateCContext) {
963963 \\}
964964 );
965965
966 cases.add("empty for loop",
967 \\void foo(void) {
968 \\ for (;;) { }
969 \\}
970 ,
971 \\pub fn foo() {
972 \\ while (true) {};
973 \\}
974 );
975
966976 cases.add("break statement",
967977 \\void foo(void) {
968978 \\ for (;;) {
......@@ -990,6 +1000,47 @@ pub fn addCases(cases: &tests.TranslateCContext) {
9901000 \\ };
9911001 \\}
9921002 );
1003
1004 //cases.add("switch statement",
1005 // \\int foo(int x) {
1006 // \\ switch (x) {
1007 // \\ case 1:
1008 // \\ x += 1;
1009 // \\ case 2:
1010 // \\ break;
1011 // \\ case 3:
1012 // \\ case 4:
1013 // \\ return x + 1;
1014 // \\ default:
1015 // \\ return 10;
1016 // \\ }
1017 // \\ return x + 13;
1018 // \\}
1019 //,
1020 // \\fn foo(_x: i32) -> i32 {
1021 // \\ var x = _x;
1022 // \\ switch (x) {
1023 // \\ 1 => goto switch_case_1;
1024 // \\ 2 => goto switch_case_2;
1025 // \\ 3 => goto switch_case_3;
1026 // \\ 4 => goto switch_case_4;
1027 // \\ else => goto switch_default;
1028 // \\ }
1029 // \\switch_case_1:
1030 // \\ x += 1;
1031 // \\ goto switch_case_2;
1032 // \\switch_case_2:
1033 // \\ goto switch_end;
1034 // \\switch_case_3:
1035 // \\ goto switch_case_4;
1036 // \\switch_case_4:
1037 // \\ return x += 1;
1038 // \\switch_default:
1039 // \\ return 10;
1040 // \\switch_end:
1041 // \\ return x + 13;
1042 // \\}
1043 //);
9931044}
9941045
9951046