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 @@...@@ -23,6 +23,8 @@
2323
24using namespace clang;24using namespace clang;
2525
26struct TransScope;
27
26struct MacroSymbol {28struct MacroSymbol {
27 Buf *name;29 Buf *name;
28 Buf *value;30 Buf *value;
...@@ -52,12 +54,59 @@ struct Context {...@@ -52,12 +54,59 @@ struct Context {
52 ASTContext *ctx;54 ASTContext *ctx;
5355
54 HashMap<Buf *, bool, buf_hash, buf_eql_buf> ptr_params;56 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,
55};74};
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
57static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);103static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);
58static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);104static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
59static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl);105static 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
62ATTRIBUTE_PRINTF(3, 4)111ATTRIBUTE_PRINTF(3, 4)
63static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) {112static 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...@@ -165,8 +214,8 @@ static AstNode *trans_create_node_bin_op(Context *c, AstNode *lhs_node, BinOpTyp
165 return node;214 return node;
166}215}
167216
168static AstNode *maybe_suppress_result(Context *c, bool result_used, AstNode *node) {217static AstNode *maybe_suppress_result(Context *c, ResultUsed result_used, AstNode *node) {
169 if (result_used) return node;218 if (result_used == ResultUsedYes) return node;
170 return trans_create_node_bin_op(c,219 return trans_create_node_bin_op(c,
171 trans_create_node_symbol_str(c, "_"),220 trans_create_node_symbol_str(c, "_"),
172 BinOpTypeAssign,221 BinOpTypeAssign,
...@@ -341,8 +390,6 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int)...@@ -341,8 +390,6 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int)
341390
342}391}
343392
344static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
345
346static QualType get_expr_qual_type(Context *c, const Expr *expr) {393static QualType get_expr_qual_type(Context *c, const Expr *expr) {
347 // String literals in C are `char *` but they should really be `const char *`.394 // String literals in C are `char *` but they should really be `const char *`.
348 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {395 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
...@@ -573,16 +620,8 @@ static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {...@@ -573,16 +620,8 @@ static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {
573 }620 }
574}621}
575622
576enum TransLRValue {623static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval) {
577 TransLValue,624 return trans_stmt(c, result_used, scope, expr, lrval);
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);
586}625}
587626
588static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) {627static 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...@@ -922,32 +961,33 @@ static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &s
922 return trans_type(c, qt.getTypePtr(), source_loc);961 return trans_type(c, qt.getTypePtr(), source_loc);
923}962}
924963
925static AstNode *trans_compound_stmt(Context *c, AstNode *parent, CompoundStmt *stmt) {964static AstNode *trans_compound_stmt(Context *c, TransScope *parent_scope, const CompoundStmt *stmt) {
926 AstNode *child_block = trans_create_node(c, NodeTypeBlock);965 TransScopeBlock *child_scope_block = trans_scope_block_create(c, parent_scope);
927 for (CompoundStmt::body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {966 for (CompoundStmt::const_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);967 AstNode *child_node = trans_stmt(c, ResultUsedNo, &child_scope_block->base, *it, TransRValue);
929 if (child_node == nullptr)968 if (child_node == nullptr)
930 return nullptr;969 return nullptr;
931 if (child_node != skip_add_to_block_node)970 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);
933 }972 }
934 return child_block;973 c->child_scope = &child_scope_block->base;
974 return child_scope_block->node;
935}975}
936976
937static AstNode *trans_return_stmt(Context *c, AstNode *block, ReturnStmt *stmt) {977static AstNode *trans_return_stmt(Context *c, TransScope *scope, const ReturnStmt *stmt) {
938 Expr *value_expr = stmt->getRetValue();978 const Expr *value_expr = stmt->getRetValue();
939 if (value_expr == nullptr) {979 if (value_expr == nullptr) {
940 return trans_create_node(c, NodeTypeReturnExpr);980 return trans_create_node(c, NodeTypeReturnExpr);
941 } else {981 } else {
942 AstNode *return_node = trans_create_node(c, NodeTypeReturnExpr);982 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);
944 if (return_node->data.return_expr.expr == nullptr)984 if (return_node->data.return_expr.expr == nullptr)
945 return nullptr;985 return nullptr;
946 return return_node;986 return return_node;
947 }987 }
948}988}
949989
950static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) {990static AstNode *trans_integer_literal(Context *c, const IntegerLiteral *stmt) {
951 llvm::APSInt result;991 llvm::APSInt result;
952 if (!stmt->EvaluateAsInt(result, *c->ctx)) {992 if (!stmt->EvaluateAsInt(result, *c->ctx)) {
953 emit_warning(c, stmt->getLocStart(), "invalid integer literal");993 emit_warning(c, stmt->getLocStart(), "invalid integer literal");
...@@ -956,54 +996,56 @@ static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) {...@@ -956,54 +996,56 @@ static AstNode *trans_integer_literal(Context *c, IntegerLiteral *stmt) {
956 return trans_create_node_apint(c, result);996 return trans_create_node_apint(c, result);
957}997}
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{
960 AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);1002 AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
9611003
962 Expr *cond_expr = stmt->getCond();1004 Expr *cond_expr = stmt->getCond();
963 Expr *true_expr = stmt->getTrueExpr();1005 Expr *true_expr = stmt->getTrueExpr();
964 Expr *false_expr = stmt->getFalseExpr();1006 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);
967 if (node->data.if_bool_expr.condition == nullptr)1009 if (node->data.if_bool_expr.condition == nullptr)
968 return nullptr;1010 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);
971 if (node->data.if_bool_expr.then_block == nullptr)1013 if (node->data.if_bool_expr.then_block == nullptr)
972 return nullptr;1014 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);
975 if (node->data.if_bool_expr.else_node == nullptr)1017 if (node->data.if_bool_expr.else_node == nullptr)
976 return nullptr;1018 return nullptr;
9771019
978 return maybe_suppress_result(c, result_used, node);1020 return maybe_suppress_result(c, result_used, node);
979}1021}
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) {
982 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);1024 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
983 node->data.bin_op_expr.bin_op = bin_op;1025 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);
986 if (node->data.bin_op_expr.op1 == nullptr)1028 if (node->data.bin_op_expr.op1 == nullptr)
987 return nullptr;1029 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);
990 if (node->data.bin_op_expr.op2 == nullptr)1032 if (node->data.bin_op_expr.op2 == nullptr)
991 return nullptr;1033 return nullptr;
9921034
993 return node;1035 return node;
994}1036}
9951037
996static AstNode *trans_create_assign(Context *c, bool result_used, AstNode *block, Expr *lhs, Expr *rhs) {1038static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope, Expr *lhs, Expr *rhs) {
997 if (!result_used) {1039 if (result_used == ResultUsedNo) {
998 // common case1040 // common case
999 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);1041 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
1000 node->data.bin_op_expr.bin_op = BinOpTypeAssign;1042 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);
1003 if (node->data.bin_op_expr.op1 == nullptr)1045 if (node->data.bin_op_expr.op1 == nullptr)
1004 return nullptr;1046 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);
1007 if (node->data.bin_op_expr.op2 == nullptr)1049 if (node->data.bin_op_expr.op2 == nullptr)
1008 return nullptr;1050 return nullptr;
10091051
...@@ -1017,47 +1059,49 @@ static AstNode *trans_create_assign(Context *c, bool result_used, AstNode *block...@@ -1017,47 +1059,49 @@ static AstNode *trans_create_assign(Context *c, bool result_used, AstNode *block
1017 // zig: _tmp1059 // zig: _tmp
1018 // zig: }1060 // zig: }
10191061
1020 AstNode *child_block = trans_create_node(c, NodeTypeBlock);1062 TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
10211063
1022 // const _tmp = rhs;1064 // 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);
1024 if (rhs_node == nullptr) return nullptr;1066 if (rhs_node == nullptr) return nullptr;
1025 // TODO: avoid name collisions with generated variable names1067 // TODO: avoid name collisions with generated variable names
1026 Buf* tmp_var_name = buf_create_from_str("_tmp");1068 Buf* tmp_var_name = buf_create_from_str("_tmp");
1027 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, rhs_node);1069 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
1030 // lhs = _tmp;1072 // 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);
1032 if (lhs_node == nullptr) return nullptr;1074 if (lhs_node == nullptr) return nullptr;
1033 child_block->data.block.statements.append(1075 child_scope->node->data.block.statements.append(
1034 trans_create_node_bin_op(c, lhs_node, BinOpTypeAssign,1076 trans_create_node_bin_op(c, lhs_node, BinOpTypeAssign,
1035 trans_create_node_symbol(c, tmp_var_name)));1077 trans_create_node_symbol(c, tmp_var_name)));
10361078
1037 // _tmp1079 // _tmp
1038 child_block->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name));1080 child_scope->node->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name));
1039 child_block->data.block.last_statement_is_result_expression = true;1081 child_scope->node->data.block.last_statement_is_result_expression = true;
10401082
1041 return child_block;1083 return child_scope->node;
1042 }1084 }
1043}1085}
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{
1046 const SourceLocation &rhs_location = rhs_expr->getLocStart();1090 const SourceLocation &rhs_location = rhs_expr->getLocStart();
1047 AstNode *rhs_type = qual_type_to_log2_int_ref(c, result_type, rhs_location);1091 AstNode *rhs_type = qual_type_to_log2_int_ref(c, result_type, rhs_location);
1048 // lhs >> u5(rh)1092 // 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);
1051 if (lhs == nullptr) return nullptr;1095 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);
1054 if (rhs == nullptr) return nullptr;1098 if (rhs == nullptr) return nullptr;
1055 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);1099 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
10561100
1057 return trans_create_node_bin_op(c, lhs, bin_op, coerced_rhs);1101 return trans_create_node_bin_op(c, lhs, bin_op, coerced_rhs);
1058}1102}
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) {
1061 switch (stmt->getOpcode()) {1105 switch (stmt->getOpcode()) {
1062 case BO_PtrMemD:1106 case BO_PtrMemD:
1063 emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_PtrMemD");1107 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...@@ -1066,20 +1110,20 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo
1066 emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_PtrMemI");1110 emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_PtrMemI");
1067 return nullptr;1111 return nullptr;
1068 case BO_Mul:1112 case BO_Mul:
1069 return trans_create_bin_op(c, block, stmt->getLHS(),1113 return trans_create_bin_op(c, scope, stmt->getLHS(),
1070 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult,1114 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult,
1071 stmt->getRHS());1115 stmt->getRHS());
1072 case BO_Div:1116 case BO_Div:
1073 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {1117 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
1074 // unsigned/float division uses the operator1118 // 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());
1076 } else {1120 } else {
1077 // signed integer division uses @divTrunc1121 // signed integer division uses @divTrunc
1078 AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "divTrunc");1122 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);
1080 if (lhs == nullptr) return nullptr;1124 if (lhs == nullptr) return nullptr;
1081 fn_call->data.fn_call_expr.params.append(lhs);1125 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);
1083 if (rhs == nullptr) return nullptr;1127 if (rhs == nullptr) return nullptr;
1084 fn_call->data.fn_call_expr.params.append(rhs);1128 fn_call->data.fn_call_expr.params.append(rhs);
1085 return fn_call;1129 return fn_call;
...@@ -1087,66 +1131,70 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo...@@ -1087,66 +1131,70 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo
1087 case BO_Rem:1131 case BO_Rem:
1088 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {1132 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
1089 // unsigned/float division uses the operator1133 // 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());
1091 } else {1135 } else {
1092 // signed integer division uses @rem1136 // signed integer division uses @rem
1093 AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "rem");1137 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);
1095 if (lhs == nullptr) return nullptr;1139 if (lhs == nullptr) return nullptr;
1096 fn_call->data.fn_call_expr.params.append(lhs);1140 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);
1098 if (rhs == nullptr) return nullptr;1142 if (rhs == nullptr) return nullptr;
1099 fn_call->data.fn_call_expr.params.append(rhs);1143 fn_call->data.fn_call_expr.params.append(rhs);
1100 return fn_call;1144 return fn_call;
1101 }1145 }
1102 case BO_Add:1146 case BO_Add:
1103 return trans_create_bin_op(c, block, stmt->getLHS(),1147 return trans_create_bin_op(c, scope, stmt->getLHS(),
1104 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd,1148 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd,
1105 stmt->getRHS());1149 stmt->getRHS());
1106 case BO_Sub:1150 case BO_Sub:
1107 return trans_create_bin_op(c, block, stmt->getLHS(),1151 return trans_create_bin_op(c, scope, stmt->getLHS(),
1108 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub,1152 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub,
1109 stmt->getRHS());1153 stmt->getRHS());
1110 case BO_Shl:1154 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());
1112 case BO_Shr:1156 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());
1114 case BO_LT:1158 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());
1116 case BO_GT:1160 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());
1118 case BO_LE:1162 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());
1120 case BO_GE:1164 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());
1122 case BO_EQ:1166 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());
1124 case BO_NE:1168 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());
1126 case BO_And:1170 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());
1128 case BO_Xor:1172 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());
1130 case BO_Or:1174 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());
1132 case BO_LAnd:1176 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());
1134 case BO_LOr:1178 case BO_LOr:
1135 // TODO: int vs bool1179 // 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());
1137 case BO_Assign:1181 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());
1139 case BO_Comma:1183 case BO_Comma:
1140 {1184 {
1141 block = trans_create_node(c, NodeTypeBlock);1185 TransScopeBlock *scope_block = trans_scope_block_create(c, scope);
1142 AstNode *lhs = trans_expr(c, false, block, stmt->getLHS(), TransRValue);1186 AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, stmt->getLHS(), TransRValue);
1143 if (lhs == nullptr) return nullptr;1187 if (lhs == nullptr)
1144 block->data.block.statements.append(maybe_suppress_result(c, false, lhs));1188 return nullptr;
1145 AstNode *rhs = trans_expr(c, result_used, block, stmt->getRHS(), TransRValue);1189 scope_block->node->data.block.statements.append(maybe_suppress_result(c, ResultUsedNo, lhs));
1146 if (rhs == nullptr) return nullptr;1190
1147 block->data.block.statements.append(maybe_suppress_result(c, result_used, rhs));1191 AstNode *rhs = trans_expr(c, result_used, &scope_block->base, stmt->getRHS(), TransRValue);
1148 block->data.block.last_statement_is_result_expression = true;1192 if (rhs == nullptr)
1149 return block;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;
1150 }1198 }
1151 case BO_MulAssign:1199 case BO_MulAssign:
1152 case BO_DivAssign:1200 case BO_DivAssign:
...@@ -1164,18 +1212,20 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo...@@ -1164,18 +1212,20 @@ static AstNode *trans_binary_operator(Context *c, bool result_used, AstNode *blo
1164 zig_unreachable();1212 zig_unreachable();
1165}1213}
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{
1168 const SourceLocation &rhs_location = stmt->getRHS()->getLocStart();1218 const SourceLocation &rhs_location = stmt->getRHS()->getLocStart();
1169 AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location);1219 AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location);
11701220
1171 bool use_intermediate_casts = stmt->getComputationLHSType().getTypePtr() != stmt->getComputationResultType().getTypePtr();1221 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) {
1173 // simple common case, where the C and Zig are identical:1223 // simple common case, where the C and Zig are identical:
1174 // lhs >>= rhs1224 // lhs >>= rhs
1175 AstNode *lhs = trans_expr(c, true, block, stmt->getLHS(), TransLValue);1225 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, stmt->getLHS(), TransLValue);
1176 if (lhs == nullptr) return nullptr;1226 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);
1179 if (rhs == nullptr) return nullptr;1229 if (rhs == nullptr) return nullptr;
1180 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);1230 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,...@@ -1190,20 +1240,20 @@ static AstNode *trans_create_compound_assign_shift(Context *c, bool result_used,
1190 // zig: }1240 // zig: }
1191 // where u5 is the appropriate type1241 // 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
1195 // const _ref = &lhs;1245 // 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);
1197 if (lhs == nullptr) return nullptr;1247 if (lhs == nullptr) return nullptr;
1198 AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);1248 AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);
1199 // TODO: avoid name collisions with generated variable names1249 // TODO: avoid name collisions with generated variable names
1200 Buf* tmp_var_name = buf_create_from_str("_ref");1250 Buf* tmp_var_name = buf_create_from_str("_ref");
1201 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, addr_of_lhs);1251 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
1204 // *_ref = result_type(operation_type(*_ref) >> u5(rhs));1254 // *_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);
1207 if (rhs == nullptr) return nullptr;1257 if (rhs == nullptr) return nullptr;
1208 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);1258 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,...@@ -1220,27 +1270,29 @@ static AstNode *trans_create_compound_assign_shift(Context *c, bool result_used,
1220 trans_create_node_symbol(c, tmp_var_name))),1270 trans_create_node_symbol(c, tmp_var_name))),
1221 bin_op,1271 bin_op,
1222 coerced_rhs)));1272 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) {
1226 // *_ref1276 // *_ref
1227 child_block->data.block.statements.append(1277 child_scope->node->data.block.statements.append(
1228 trans_create_node_prefix_op(c, PrefixOpDereference,1278 trans_create_node_prefix_op(c, PrefixOpDereference,
1229 trans_create_node_symbol(c, tmp_var_name)));1279 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;
1231 }1281 }
12321282
1233 return child_block;1283 return child_scope->node;
1234 }1284 }
1235}1285}
12361286
1237static AstNode *trans_create_compound_assign(Context *c, bool result_used, AstNode *block, CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op) {1287static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used, TransScope *scope,
1238 if (!result_used) {1288 const CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
1289{
1290 if (result_used == ResultUsedNo) {
1239 // simple common case, where the C and Zig are identical:1291 // simple common case, where the C and Zig are identical:
1240 // lhs += rhs1292 // lhs += rhs
1241 AstNode *lhs = trans_expr(c, true, block, stmt->getLHS(), TransLValue);1293 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, stmt->getLHS(), TransLValue);
1242 if (lhs == nullptr) return nullptr;1294 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);
1244 if (rhs == nullptr) return nullptr;1296 if (rhs == nullptr) return nullptr;
1245 return trans_create_node_bin_op(c, lhs, assign_op, rhs);1297 return trans_create_node_bin_op(c, lhs, assign_op, rhs);
1246 } else {1298 } else {
...@@ -1252,20 +1304,20 @@ static AstNode *trans_create_compound_assign(Context *c, bool result_used, AstNo...@@ -1252,20 +1304,20 @@ static AstNode *trans_create_compound_assign(Context *c, bool result_used, AstNo
1252 // zig: *_ref1304 // zig: *_ref
1253 // zig: }1305 // zig: }
12541306
1255 AstNode *child_block = trans_create_node(c, NodeTypeBlock);1307 TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
12561308
1257 // const _ref = &lhs;1309 // 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);
1259 if (lhs == nullptr) return nullptr;1311 if (lhs == nullptr) return nullptr;
1260 AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);1312 AstNode *addr_of_lhs = trans_create_node_addr_of(c, false, false, lhs);
1261 // TODO: avoid name collisions with generated variable names1313 // TODO: avoid name collisions with generated variable names
1262 Buf* tmp_var_name = buf_create_from_str("_ref");1314 Buf* tmp_var_name = buf_create_from_str("_ref");
1263 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, addr_of_lhs);1315 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
1266 // *_ref = *_ref + rhs;1318 // *_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);
1269 if (rhs == nullptr) return nullptr;1321 if (rhs == nullptr) return nullptr;
12701322
1271 AstNode *assign_statement = trans_create_node_bin_op(c,1323 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...@@ -1277,26 +1329,28 @@ static AstNode *trans_create_compound_assign(Context *c, bool result_used, AstNo
1277 trans_create_node_symbol(c, tmp_var_name)),1329 trans_create_node_symbol(c, tmp_var_name)),
1278 bin_op,1330 bin_op,
1279 rhs));1331 rhs));
1280 child_block->data.block.statements.append(assign_statement);1332 child_scope->node->data.block.statements.append(assign_statement);
12811333
1282 // *_ref1334 // *_ref
1283 child_block->data.block.statements.append(1335 child_scope->node->data.block.statements.append(
1284 trans_create_node_prefix_op(c, PrefixOpDereference,1336 trans_create_node_prefix_op(c, PrefixOpDereference,
1285 trans_create_node_symbol(c, tmp_var_name)));1337 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;
1289 }1341 }
1290}1342}
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{
1294 switch (stmt->getOpcode()) {1348 switch (stmt->getOpcode()) {
1295 case BO_MulAssign:1349 case BO_MulAssign:
1296 if (qual_type_has_wrapping_overflow(c, stmt->getType()))1350 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);
1298 else1352 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);
1300 case BO_DivAssign:1354 case BO_DivAssign:
1301 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_DivAssign");1355 emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_DivAssign");
1302 return nullptr;1356 return nullptr;
...@@ -1305,24 +1359,24 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast...@@ -1305,24 +1359,24 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast
1305 return nullptr;1359 return nullptr;
1306 case BO_AddAssign:1360 case BO_AddAssign:
1307 if (qual_type_has_wrapping_overflow(c, stmt->getType()))1361 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);
1309 else1363 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);
1311 case BO_SubAssign:1365 case BO_SubAssign:
1312 if (qual_type_has_wrapping_overflow(c, stmt->getType()))1366 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);
1314 else1368 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);
1316 case BO_ShlAssign:1370 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);
1318 case BO_ShrAssign:1372 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);
1320 case BO_AndAssign:1374 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);
1322 case BO_XorAssign:1376 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);
1324 case BO_OrAssign:1378 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);
1326 case BO_PtrMemD:1380 case BO_PtrMemD:
1327 case BO_PtrMemI:1381 case BO_PtrMemI:
1328 case BO_Assign:1382 case BO_Assign:
...@@ -1351,13 +1405,13 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast...@@ -1351,13 +1405,13 @@ static AstNode *trans_compound_assign_operator(Context *c, bool result_used, Ast
1351 zig_unreachable();1405 zig_unreachable();
1352}1406}
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) {
1355 switch (stmt->getCastKind()) {1409 switch (stmt->getCastKind()) {
1356 case CK_LValueToRValue:1410 case CK_LValueToRValue:
1357 return trans_expr(c, true, block, stmt->getSubExpr(), TransRValue);1411 return trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1358 case CK_IntegralCast:1412 case CK_IntegralCast:
1359 {1413 {
1360 AstNode *target_node = trans_expr(c, true, block, stmt->getSubExpr(), TransRValue);1414 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1361 if (target_node == nullptr)1415 if (target_node == nullptr)
1362 return nullptr;1416 return nullptr;
1363 return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), target_node);1417 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...@@ -1365,14 +1419,14 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas
1365 case CK_FunctionToPointerDecay:1419 case CK_FunctionToPointerDecay:
1366 case CK_ArrayToPointerDecay:1420 case CK_ArrayToPointerDecay:
1367 {1421 {
1368 AstNode *target_node = trans_expr(c, true, block, stmt->getSubExpr(), TransRValue);1422 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1369 if (target_node == nullptr)1423 if (target_node == nullptr)
1370 return nullptr;1424 return nullptr;
1371 return target_node;1425 return target_node;
1372 }1426 }
1373 case CK_BitCast:1427 case CK_BitCast:
1374 {1428 {
1375 AstNode *target_node = trans_expr(c, true, block, stmt->getSubExpr(), TransRValue);1429 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1376 if (target_node == nullptr)1430 if (target_node == nullptr)
1377 return nullptr;1431 return nullptr;
13781432
...@@ -1549,8 +1603,8 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas...@@ -1549,8 +1603,8 @@ static AstNode *trans_implicit_cast_expr(Context *c, AstNode *block, ImplicitCas
1549 zig_unreachable();1603 zig_unreachable();
1550}1604}
15511605
1552static AstNode *trans_decl_ref_expr(Context *c, DeclRefExpr *stmt, TransLRValue lrval) {1606static AstNode *trans_decl_ref_expr(Context *c, const DeclRefExpr *stmt, TransLRValue lrval) {
1553 ValueDecl *value_decl = stmt->getDecl();1607 const ValueDecl *value_decl = stmt->getDecl();
1554 Buf *symbol_name = buf_create_from_str(decl_name(value_decl));1608 Buf *symbol_name = buf_create_from_str(decl_name(value_decl));
1555 if (lrval == TransLValue) {1609 if (lrval == TransLValue) {
1556 c->ptr_params.put(symbol_name, true);1610 c->ptr_params.put(symbol_name, true);
...@@ -1558,15 +1612,17 @@ static AstNode *trans_decl_ref_expr(Context *c, DeclRefExpr *stmt, TransLRValue...@@ -1558,15 +1612,17 @@ static AstNode *trans_decl_ref_expr(Context *c, DeclRefExpr *stmt, TransLRValue
1558 return trans_create_node_symbol(c, symbol_name);1612 return trans_create_node_symbol(c, symbol_name);
1559}1613}
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{
1562 Expr *op_expr = stmt->getSubExpr();1618 Expr *op_expr = stmt->getSubExpr();
15631619
1564 if (!result_used) {1620 if (result_used == ResultUsedNo) {
1565 // common case1621 // common case
1566 // c: expr++1622 // c: expr++
1567 // zig: expr += 11623 // zig: expr += 1
1568 return trans_create_node_bin_op(c,1624 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),
1570 assign_op,1626 assign_op,
1571 trans_create_node_unsigned(c, 1));1627 trans_create_node_unsigned(c, 1));
1572 }1628 }
...@@ -1578,23 +1634,23 @@ static AstNode *trans_create_post_crement(Context *c, bool result_used, AstNode...@@ -1578,23 +1634,23 @@ static AstNode *trans_create_post_crement(Context *c, bool result_used, AstNode
1578 // zig: *_ref += 1;1634 // zig: *_ref += 1;
1579 // zig: _tmp1635 // zig: _tmp
1580 // zig: }1636 // zig: }
1581 AstNode *child_block = trans_create_node(c, NodeTypeBlock);1637 TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
15821638
1583 // const _ref = &expr;1639 // 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);
1585 if (expr == nullptr) return nullptr;1641 if (expr == nullptr) return nullptr;
1586 AstNode *addr_of_expr = trans_create_node_addr_of(c, false, false, expr);1642 AstNode *addr_of_expr = trans_create_node_addr_of(c, false, false, expr);
1587 // TODO: avoid name collisions with generated variable names1643 // TODO: avoid name collisions with generated variable names
1588 Buf* ref_var_name = buf_create_from_str("_ref");1644 Buf* ref_var_name = buf_create_from_str("_ref");
1589 AstNode *ref_var_decl = trans_create_node_var_decl_local(c, true, ref_var_name, nullptr, addr_of_expr);1645 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
1592 // const _tmp = *_ref;1648 // const _tmp = *_ref;
1593 Buf* tmp_var_name = buf_create_from_str("_tmp");1649 Buf* tmp_var_name = buf_create_from_str("_tmp");
1594 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr,1650 AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr,
1595 trans_create_node_prefix_op(c, PrefixOpDereference,1651 trans_create_node_prefix_op(c, PrefixOpDereference,
1596 trans_create_node_symbol(c, ref_var_name)));1652 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
1599 // *_ref += 1;1655 // *_ref += 1;
1600 AstNode *assign_statement = trans_create_node_bin_op(c,1656 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...@@ -1602,24 +1658,26 @@ static AstNode *trans_create_post_crement(Context *c, bool result_used, AstNode
1602 trans_create_node_symbol(c, ref_var_name)),1658 trans_create_node_symbol(c, ref_var_name)),
1603 assign_op,1659 assign_op,
1604 trans_create_node_unsigned(c, 1));1660 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
1607 // _tmp1663 // _tmp
1608 child_block->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name));1664 child_scope->node->data.block.statements.append(trans_create_node_symbol(c, tmp_var_name));
1609 child_block->data.block.last_statement_is_result_expression = true;1665 child_scope->node->data.block.last_statement_is_result_expression = true;
16101666
1611 return child_block;1667 return child_scope->node;
1612}1668}
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{
1615 Expr *op_expr = stmt->getSubExpr();1673 Expr *op_expr = stmt->getSubExpr();
16161674
1617 if (!result_used) {1675 if (result_used == ResultUsedNo) {
1618 // common case1676 // common case
1619 // c: ++expr1677 // c: ++expr
1620 // zig: expr += 11678 // zig: expr += 1
1621 return trans_create_node_bin_op(c,1679 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),
1623 assign_op,1681 assign_op,
1624 trans_create_node_unsigned(c, 1));1682 trans_create_node_unsigned(c, 1));
1625 }1683 }
...@@ -1630,16 +1688,16 @@ static AstNode *trans_create_pre_crement(Context *c, bool result_used, AstNode *...@@ -1630,16 +1688,16 @@ static AstNode *trans_create_pre_crement(Context *c, bool result_used, AstNode *
1630 // zig: *_ref += 1;1688 // zig: *_ref += 1;
1631 // zig: *_ref1689 // zig: *_ref
1632 // zig: }1690 // zig: }
1633 AstNode *child_block = trans_create_node(c, NodeTypeBlock);1691 TransScopeBlock *child_scope = trans_scope_block_create(c, scope);
16341692
1635 // const _ref = &expr;1693 // 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);
1637 if (expr == nullptr) return nullptr;1695 if (expr == nullptr) return nullptr;
1638 AstNode *addr_of_expr = trans_create_node_addr_of(c, false, false, expr);1696 AstNode *addr_of_expr = trans_create_node_addr_of(c, false, false, expr);
1639 // TODO: avoid name collisions with generated variable names1697 // TODO: avoid name collisions with generated variable names
1640 Buf* ref_var_name = buf_create_from_str("_ref");1698 Buf* ref_var_name = buf_create_from_str("_ref");
1641 AstNode *ref_var_decl = trans_create_node_var_decl_local(c, true, ref_var_name, nullptr, addr_of_expr);1699 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
1644 // *_ref += 1;1702 // *_ref += 1;
1645 AstNode *assign_statement = trans_create_node_bin_op(c,1703 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 *...@@ -1647,49 +1705,49 @@ static AstNode *trans_create_pre_crement(Context *c, bool result_used, AstNode *
1647 trans_create_node_symbol(c, ref_var_name)),1705 trans_create_node_symbol(c, ref_var_name)),
1648 assign_op,1706 assign_op,
1649 trans_create_node_unsigned(c, 1));1707 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
1652 // *_ref1710 // *_ref
1653 AstNode *deref_expr = trans_create_node_prefix_op(c, PrefixOpDereference,1711 AstNode *deref_expr = trans_create_node_prefix_op(c, PrefixOpDereference,
1654 trans_create_node_symbol(c, ref_var_name));1712 trans_create_node_symbol(c, ref_var_name));
1655 child_block->data.block.statements.append(deref_expr);1713 child_scope->node->data.block.statements.append(deref_expr);
1656 child_block->data.block.last_statement_is_result_expression = true;1714 child_scope->node->data.block.last_statement_is_result_expression = true;
16571715
1658 return child_block;1716 return child_scope->node;
1659}1717}
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) {
1662 switch (stmt->getOpcode()) {1720 switch (stmt->getOpcode()) {
1663 case UO_PostInc:1721 case UO_PostInc:
1664 if (qual_type_has_wrapping_overflow(c, stmt->getType()))1722 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);
1666 else1724 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);
1668 case UO_PostDec:1726 case UO_PostDec:
1669 if (qual_type_has_wrapping_overflow(c, stmt->getType()))1727 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);
1671 else1729 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);
1673 case UO_PreInc:1731 case UO_PreInc:
1674 if (qual_type_has_wrapping_overflow(c, stmt->getType()))1732 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);
1676 else1734 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);
1678 case UO_PreDec:1736 case UO_PreDec:
1679 if (qual_type_has_wrapping_overflow(c, stmt->getType()))1737 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);
1681 else1739 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);
1683 case UO_AddrOf:1741 case UO_AddrOf:
1684 {1742 {
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);
1686 if (value_node == nullptr)1744 if (value_node == nullptr)
1687 return value_node;1745 return value_node;
1688 return trans_create_node_addr_of(c, false, false, value_node);1746 return trans_create_node_addr_of(c, false, false, value_node);
1689 }1747 }
1690 case UO_Deref:1748 case UO_Deref:
1691 {1749 {
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);
1693 if (value_node == nullptr)1751 if (value_node == nullptr)
1694 return nullptr;1752 return nullptr;
1695 bool is_fn_ptr = qual_type_is_fn_ptr(c, stmt->getSubExpr()->getType());1753 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...@@ -1708,7 +1766,7 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc
1708 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);1766 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
1709 node->data.prefix_op_expr.prefix_op = PrefixOpNegation;1767 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);
1712 if (node->data.prefix_op_expr.primary_expr == nullptr)1770 if (node->data.prefix_op_expr.primary_expr == nullptr)
1713 return nullptr;1771 return nullptr;
17141772
...@@ -1718,7 +1776,7 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc...@@ -1718,7 +1776,7 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc
1718 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);1776 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
1719 node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0);1777 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);
1722 if (node->data.bin_op_expr.op2 == nullptr)1780 if (node->data.bin_op_expr.op2 == nullptr)
1723 return nullptr;1781 return nullptr;
17241782
...@@ -1751,7 +1809,7 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc...@@ -1751,7 +1809,7 @@ static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *bloc
1751 zig_unreachable();1809 zig_unreachable();
1752}1810}
17531811
1754static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *stmt) {1812static AstNode *trans_local_declaration(Context *c, TransScope *scope, const DeclStmt *stmt) {
1755 for (auto iter = stmt->decl_begin(); iter != stmt->decl_end(); iter++) {1813 for (auto iter = stmt->decl_begin(); iter != stmt->decl_end(); iter++) {
1756 Decl *decl = *iter;1814 Decl *decl = *iter;
1757 switch (decl->getKind()) {1815 switch (decl->getKind()) {
...@@ -1760,7 +1818,7 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st...@@ -1760,7 +1818,7 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st
1760 QualType qual_type = var_decl->getTypeSourceInfo()->getType();1818 QualType qual_type = var_decl->getTypeSourceInfo()->getType();
1761 AstNode *init_node = nullptr;1819 AstNode *init_node = nullptr;
1762 if (var_decl->hasInit()) {1820 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);
1764 if (init_node == nullptr)1822 if (init_node == nullptr)
1765 return nullptr;1823 return nullptr;
17661824
...@@ -1773,7 +1831,10 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st...@@ -1773,7 +1831,10 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st
17731831
1774 AstNode *node = trans_create_node_var_decl_local(c, qual_type.isConstQualified(),1832 AstNode *node = trans_create_node_var_decl_local(c, qual_type.isConstQualified(),
1775 symbol_name, type_node, init_node);1833 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);
1777 continue;1838 continue;
1778 }1839 }
1779 case Decl::AccessSpec:1840 case Decl::AccessSpec:
...@@ -2000,37 +2061,37 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st...@@ -2000,37 +2061,37 @@ static AstNode *trans_local_declaration(Context *c, AstNode *block, DeclStmt *st
2000 return skip_add_to_block_node;2061 return skip_add_to_block_node;
2001}2062}
20022063
2003static AstNode *trans_while_loop(Context *c, AstNode *block, WhileStmt *stmt) {2064static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt *stmt) {
2004 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);2065 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);
2007 if (while_node->data.while_expr.condition == nullptr)2068 if (while_node->data.while_expr.condition == nullptr)
2008 return nullptr;2069 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);
2011 if (while_node->data.while_expr.body == nullptr)2072 if (while_node->data.while_expr.body == nullptr)
2012 return nullptr;2073 return nullptr;
20132074
2014 return while_node;2075 return while_node;
2015}2076}
20162077
2017static AstNode *trans_if_statement(Context *c, AstNode *block, IfStmt *stmt) {2078static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt *stmt) {
2018 // if (c) t2079 // if (c) t
2019 // if (c) t else e2080 // if (c) t else e
2020 AstNode *if_node = trans_create_node(c, NodeTypeIfBoolExpr);2081 AstNode *if_node = trans_create_node(c, NodeTypeIfBoolExpr);
20212082
2022 // TODO: condition != 02083 // 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);
2024 if (condition_node == nullptr)2085 if (condition_node == nullptr)
2025 return nullptr;2086 return nullptr;
2026 if_node->data.if_bool_expr.condition = condition_node;2087 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);
2029 if (if_node->data.if_bool_expr.then_block == nullptr)2090 if (if_node->data.if_bool_expr.then_block == nullptr)
2030 return nullptr;2091 return nullptr;
20312092
2032 if (stmt->getElse() != nullptr) {2093 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);
2034 if (if_node->data.if_bool_expr.else_node == nullptr)2095 if (if_node->data.if_bool_expr.else_node == nullptr)
2035 return nullptr;2096 return nullptr;
2036 }2097 }
...@@ -2038,10 +2099,10 @@ static AstNode *trans_if_statement(Context *c, AstNode *block, IfStmt *stmt) {...@@ -2038,10 +2099,10 @@ static AstNode *trans_if_statement(Context *c, AstNode *block, IfStmt *stmt) {
2038 return if_node;2099 return if_node;
2039}2100}
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) {
2042 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);2103 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);
2045 if (callee_raw_node == nullptr)2106 if (callee_raw_node == nullptr)
2046 return nullptr;2107 return nullptr;
20472108
...@@ -2055,9 +2116,9 @@ static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, Ca...@@ -2055,9 +2116,9 @@ static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, Ca
2055 node->data.fn_call_expr.fn_ref_expr = callee_node;2116 node->data.fn_call_expr.fn_ref_expr = callee_node;
20562117
2057 unsigned num_args = stmt->getNumArgs();2118 unsigned num_args = stmt->getNumArgs();
2058 Expr **args = stmt->getArgs();2119 const Expr * const* args = stmt->getArgs();
2059 for (unsigned i = 0; i < num_args; i += 1) {2120 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);
2061 if (arg_node == nullptr)2122 if (arg_node == nullptr)
2062 return nullptr;2123 return nullptr;
20632124
...@@ -2067,8 +2128,8 @@ static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, Ca...@@ -2067,8 +2128,8 @@ static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, Ca
2067 return node;2128 return node;
2068}2129}
20692130
2070static AstNode *trans_member_expr(Context *c, AstNode *block, MemberExpr *stmt) {2131static AstNode *trans_member_expr(Context *c, TransScope *scope, const MemberExpr *stmt) {
2071 AstNode *container_node = trans_expr(c, true, block, stmt->getBase(), TransRValue);2132 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);
2072 if (container_node == nullptr)2133 if (container_node == nullptr)
2073 return nullptr;2134 return nullptr;
20742135
...@@ -2082,12 +2143,12 @@ static AstNode *trans_member_expr(Context *c, AstNode *block, MemberExpr *stmt)...@@ -2082,12 +2143,12 @@ static AstNode *trans_member_expr(Context *c, AstNode *block, MemberExpr *stmt)
2082 return node;2143 return node;
2083}2144}
20842145
2085static AstNode *trans_array_subscript_expr(Context *c, AstNode *block, ArraySubscriptExpr *stmt) {2146static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const ArraySubscriptExpr *stmt) {
2086 AstNode *container_node = trans_expr(c, true, block, stmt->getBase(), TransRValue);2147 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);
2087 if (container_node == nullptr)2148 if (container_node == nullptr)
2088 return nullptr;2149 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);
2091 if (idx_node == nullptr)2152 if (idx_node == nullptr)
2092 return nullptr;2153 return nullptr;
20932154
...@@ -2098,17 +2159,19 @@ static AstNode *trans_array_subscript_expr(Context *c, AstNode *block, ArraySubs...@@ -2098,17 +2159,19 @@ static AstNode *trans_array_subscript_expr(Context *c, AstNode *block, ArraySubs
2098 return node;2159 return node;
2099}2160}
21002161
2101static AstNode *trans_c_style_cast_expr(Context *c, bool result_used, AstNode *block,2162static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, TransScope *scope,
2102 CStyleCastExpr *stmt, TransLRValue lrvalue)2163 const CStyleCastExpr *stmt, TransLRValue lrvalue)
2103{2164{
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);
2105 if (sub_expr_node == nullptr)2166 if (sub_expr_node == nullptr)
2106 return nullptr;2167 return nullptr;
21072168
2108 return trans_c_cast(c, stmt->getLocStart(), stmt->getType(), sub_expr_node);2169 return trans_c_cast(c, stmt->getLocStart(), stmt->getType(), sub_expr_node);
2109}2170}
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{
2112 AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getLocStart());2175 AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getLocStart());
2113 if (type_node == nullptr)2176 if (type_node == nullptr)
2114 return nullptr;2177 return nullptr;
...@@ -2118,7 +2181,7 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, AstNode *block,...@@ -2118,7 +2181,7 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, AstNode *block,
2118 return node;2181 return node;
2119}2182}
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) {
2122 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);2185 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
21232186
2124 AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral);2187 AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral);
...@@ -2126,6 +2189,7 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) {...@@ -2126,6 +2189,7 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) {
2126 while_node->data.while_expr.condition = true_node;2189 while_node->data.while_expr.condition = true_node;
21272190
2128 AstNode *body_node;2191 AstNode *body_node;
2192 TransScope *child_scope;
2129 if (stmt->getBody()->getStmtClass() == Stmt::CompoundStmtClass) {2193 if (stmt->getBody()->getStmtClass() == Stmt::CompoundStmtClass) {
2130 // there's already a block in C, so we'll append our condition to it.2194 // there's already a block in C, so we'll append our condition to it.
2131 // c: do {2195 // c: do {
...@@ -2137,9 +2201,10 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) {...@@ -2137,9 +2201,10 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) {
2137 // zig: b;2201 // zig: b;
2138 // zig: if (!cond) break;2202 // zig: if (!cond) break;
2139 // zig: }2203 // zig: }
2140 body_node = trans_stmt(c, false, block, stmt->getBody(), TransRValue);2204 body_node = trans_stmt(c, ResultUsedNo, parent_scope, stmt->getBody(), TransRValue);
2141 if (body_node == nullptr) return nullptr;2205 if (body_node == nullptr) return nullptr;
2142 assert(body_node->type == NodeTypeBlock);2206 assert(body_node->type == NodeTypeBlock);
2207 child_scope = c->child_scope;
2143 } else {2208 } else {
2144 // the C statement is without a block, so we need to create a block to contain it.2209 // the C statement is without a block, so we need to create a block to contain it.
2145 // c: do2210 // c: do
...@@ -2149,63 +2214,103 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) {...@@ -2149,63 +2214,103 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) {
2149 // zig: a;2214 // zig: a;
2150 // zig: if (!cond) break;2215 // zig: if (!cond) break;
2151 // zig: }2216 // zig: }
2152 body_node = trans_create_node(c, NodeTypeBlock);2217 TransScopeBlock *child_block_scope = trans_scope_block_create(c, parent_scope);
2153 AstNode *child_statement = trans_stmt(c, false, body_node, stmt->getBody(), TransRValue);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);
2154 if (child_statement == nullptr) return nullptr;2221 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);
2156 }2223 }
21572224
2158 // if (!cond) break;2225 // 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);
2160 if (condition_node == nullptr) return nullptr;2227 if (condition_node == nullptr) return nullptr;
2161 AstNode *terminator_node = trans_create_node(c, NodeTypeIfBoolExpr);2228 AstNode *terminator_node = trans_create_node(c, NodeTypeIfBoolExpr);
2162 terminator_node->data.if_bool_expr.condition = trans_create_node_prefix_op(c, PrefixOpBoolNot, condition_node);2229 terminator_node->data.if_bool_expr.condition = trans_create_node_prefix_op(c, PrefixOpBoolNot, condition_node);
2163 terminator_node->data.if_bool_expr.then_block = trans_create_node(c, NodeTypeBreak);2230 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
2166 while_node->data.while_expr.body = body_node;2237 while_node->data.while_expr.body = body_node;
21672238
2168 return while_node;2239 return while_node;
2169}2240}
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) {
2172 AstNode *loop_block_node;2273 AstNode *loop_block_node;
2274 TransScope *condition_scope;
2173 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);2275 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
2174 Stmt *init_stmt = stmt->getInit();2276 const Stmt *init_stmt = stmt->getInit();
2175 if (init_stmt == nullptr) {2277 if (init_stmt == nullptr) {
2176 loop_block_node = while_node;2278 loop_block_node = while_node;
2279 condition_scope = parent_scope;
2177 } else {2280 } 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);
2181 if (vars_node == nullptr)2286 if (vars_node == nullptr)
2182 return nullptr;2287 return nullptr;
2183 if (vars_node != skip_add_to_block_node)2288 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);
2187 }2292 }
21882293
2189 Stmt *cond_stmt = stmt->getCond();2294 const Stmt *cond_stmt = stmt->getCond();
2190 if (cond_stmt == nullptr) {2295 if (cond_stmt == nullptr) {
2191 AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral);2296 AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral);
2192 true_node->data.bool_literal.value = true;2297 true_node->data.bool_literal.value = true;
2193 while_node->data.while_expr.condition = true_node;2298 while_node->data.while_expr.condition = true_node;
2194 } else {2299 } 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);
2196 if (while_node->data.while_expr.condition == nullptr)2301 if (while_node->data.while_expr.condition == nullptr)
2197 return nullptr;2302 return nullptr;
2198 }2303 }
21992304
2200 Stmt *inc_stmt = stmt->getInc();2305 const Stmt *inc_stmt = stmt->getInc();
2201 if (inc_stmt != nullptr) {2306 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);
2203 if (inc_node == nullptr)2308 if (inc_node == nullptr)
2204 return nullptr;2309 return nullptr;
2205 while_node->data.while_expr.continue_expr = inc_node;2310 while_node->data.while_expr.continue_expr = inc_node;
2206 }2311 }
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);
2209 if (child_statement == nullptr)2314 if (child_statement == nullptr)
2210 return nullptr;2315 return nullptr;
2211 while_node->data.while_expr.body = child_statement;2316 while_node->data.while_expr.body = child_statement;
...@@ -2213,7 +2318,7 @@ static AstNode *trans_for_loop(Context *c, AstNode *block, ForStmt *stmt) {...@@ -2213,7 +2318,7 @@ static AstNode *trans_for_loop(Context *c, AstNode *block, ForStmt *stmt) {
2213 return loop_block_node;2318 return loop_block_node;
2214}2319}
22152320
2216static AstNode *trans_string_literal(Context *c, AstNode *block, StringLiteral *stmt) {2321static AstNode *trans_string_literal(Context *c, TransScope *scope, const StringLiteral *stmt) {
2217 switch (stmt->getKind()) {2322 switch (stmt->getKind()) {
2218 case StringLiteral::Ascii:2323 case StringLiteral::Ascii:
2219 case StringLiteral::UTF8:2324 case StringLiteral::UTF8:
...@@ -2231,72 +2336,75 @@ static AstNode *trans_string_literal(Context *c, AstNode *block, StringLiteral *...@@ -2231,72 +2336,75 @@ static AstNode *trans_string_literal(Context *c, AstNode *block, StringLiteral *
2231 zig_unreachable();2336 zig_unreachable();
2232}2337}
22332338
2234static AstNode *trans_break_stmt(Context *c, AstNode *block, BreakStmt *stmt) {2339static AstNode *trans_break_stmt(Context *c, TransScope *scope, const BreakStmt *stmt) {
2235 return trans_create_node(c, NodeTypeBreak);2340 return trans_create_node(c, NodeTypeBreak);
2236}2341}
22372342
2238static AstNode *trans_continue_stmt(Context *c, AstNode *block, ContinueStmt *stmt) {2343static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const ContinueStmt *stmt) {
2239 return trans_create_node(c, NodeTypeContinue);2344 return trans_create_node(c, NodeTypeContinue);
2240}2345}
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
2243 Stmt::StmtClass sc = stmt->getStmtClass();2349 Stmt::StmtClass sc = stmt->getStmtClass();
2244 switch (sc) {2350 switch (sc) {
2245 case Stmt::ReturnStmtClass:2351 case Stmt::ReturnStmtClass:
2246 return trans_return_stmt(c, block, (ReturnStmt *)stmt);2352 return trans_return_stmt(c, scope, (const ReturnStmt *)stmt);
2247 case Stmt::CompoundStmtClass:2353 case Stmt::CompoundStmtClass:
2248 return trans_compound_stmt(c, block, (CompoundStmt *)stmt);2354 return trans_compound_stmt(c, scope, (const CompoundStmt *)stmt);
2249 case Stmt::IntegerLiteralClass:2355 case Stmt::IntegerLiteralClass:
2250 return trans_integer_literal(c, (IntegerLiteral *)stmt);2356 return trans_integer_literal(c, (const IntegerLiteral *)stmt);
2251 case Stmt::ConditionalOperatorClass:2357 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);
2253 case Stmt::BinaryOperatorClass:2359 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);
2255 case Stmt::CompoundAssignOperatorClass:2361 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);
2257 case Stmt::ImplicitCastExprClass:2363 case Stmt::ImplicitCastExprClass:
2258 return trans_implicit_cast_expr(c, block, (ImplicitCastExpr *)stmt);2364 return trans_implicit_cast_expr(c, scope, (const ImplicitCastExpr *)stmt);
2259 case Stmt::DeclRefExprClass:2365 case Stmt::DeclRefExprClass:
2260 return trans_decl_ref_expr(c, (DeclRefExpr *)stmt, lrvalue);2366 return trans_decl_ref_expr(c, (const DeclRefExpr *)stmt, lrvalue);
2261 case Stmt::UnaryOperatorClass:2367 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);
2263 case Stmt::DeclStmtClass:2369 case Stmt::DeclStmtClass:
2264 return trans_local_declaration(c, block, (DeclStmt *)stmt);2370 return trans_local_declaration(c, scope, (const DeclStmt *)stmt);
2265 case Stmt::WhileStmtClass:2371 case Stmt::WhileStmtClass:
2266 return trans_while_loop(c, block, (WhileStmt *)stmt);2372 return trans_while_loop(c, scope, (const WhileStmt *)stmt);
2267 case Stmt::IfStmtClass:2373 case Stmt::IfStmtClass:
2268 return trans_if_statement(c, block, (IfStmt *)stmt);2374 return trans_if_statement(c, scope, (const IfStmt *)stmt);
2269 case Stmt::CallExprClass:2375 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);
2271 case Stmt::NullStmtClass:2377 case Stmt::NullStmtClass:
2272 return skip_add_to_block_node;2378 return skip_add_to_block_node;
2273 case Stmt::MemberExprClass:2379 case Stmt::MemberExprClass:
2274 return trans_member_expr(c, block, (MemberExpr *)stmt);2380 return trans_member_expr(c, scope, (const MemberExpr *)stmt);
2275 case Stmt::ArraySubscriptExprClass:2381 case Stmt::ArraySubscriptExprClass:
2276 return trans_array_subscript_expr(c, block, (ArraySubscriptExpr *)stmt);2382 return trans_array_subscript_expr(c, scope, (const ArraySubscriptExpr *)stmt);
2277 case Stmt::CStyleCastExprClass:2383 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);
2279 case Stmt::UnaryExprOrTypeTraitExprClass:2385 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);
2281 case Stmt::DoStmtClass:2387 case Stmt::DoStmtClass:
2282 return trans_do_loop(c, block, (DoStmt *)stmt);2388 return trans_do_loop(c, scope, (const DoStmt *)stmt);
2283 case Stmt::ForStmtClass:2389 case Stmt::ForStmtClass:
2284 return trans_for_loop(c, block, (ForStmt *)stmt);2390 return trans_for_loop(c, scope, (const ForStmt *)stmt);
2285 case Stmt::StringLiteralClass:2391 case Stmt::StringLiteralClass:
2286 return trans_string_literal(c, block, (StringLiteral *)stmt);2392 return trans_string_literal(c, scope, (const StringLiteral *)stmt);
2287 case Stmt::BreakStmtClass:2393 case Stmt::BreakStmtClass:
2288 return trans_break_stmt(c, block, (BreakStmt *)stmt);2394 return trans_break_stmt(c, scope, (const BreakStmt *)stmt);
2289 case Stmt::ContinueStmtClass:2395 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;
2291 case Stmt::CaseStmtClass:2402 case Stmt::CaseStmtClass:
2292 emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass");2403 emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass");
2293 return nullptr;2404 return nullptr;
2294 case Stmt::DefaultStmtClass:2405 case Stmt::DefaultStmtClass:
2295 emit_warning(c, stmt->getLocStart(), "TODO handle C DefaultStmtClass");2406 emit_warning(c, stmt->getLocStart(), "TODO handle C DefaultStmtClass");
2296 return nullptr;2407 return nullptr;
2297 case Stmt::SwitchStmtClass:
2298 emit_warning(c, stmt->getLocStart(), "TODO handle C SwitchStmtClass");
2299 return nullptr;
2300 case Stmt::NoStmtClass:2408 case Stmt::NoStmtClass:
2301 emit_warning(c, stmt->getLocStart(), "TODO handle C NoStmtClass");2409 emit_warning(c, stmt->getLocStart(), "TODO handle C NoStmtClass");
2302 return nullptr;2410 return nullptr;
...@@ -2584,7 +2692,7 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s...@@ -2584,7 +2692,7 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s
2584 emit_warning(c, stmt->getLocStart(), "TODO handle C PackExpansionExprClass");2692 emit_warning(c, stmt->getLocStart(), "TODO handle C PackExpansionExprClass");
2585 return nullptr;2693 return nullptr;
2586 case Stmt::ParenExprClass:2694 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);
2588 case Stmt::ParenListExprClass:2696 case Stmt::ParenListExprClass:
2589 emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass");2697 emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass");
2590 return nullptr;2698 return nullptr;
...@@ -2838,10 +2946,13 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -2838,10 +2946,13 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
2838 return;2946 return;
2839 }2947 }
28402948
2949 TransScope *scope = nullptr;
2950
2841 for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {2951 for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
2842 AstNode *param_node = proto_node->data.fn_proto.params.at(i);2952 AstNode *param_node = proto_node->data.fn_proto.params.at(i);
2843 const ParmVarDecl *param = fn_decl->getParamDecl(i);2953 const ParmVarDecl *param = fn_decl->getParamDecl(i);
2844 const char *name = decl_name(param);2954 const char *name = decl_name(param);
2955
2845 Buf *proto_param_name;2956 Buf *proto_param_name;
2846 if (strlen(name) != 0) {2957 if (strlen(name) != 0) {
2847 proto_param_name = buf_create_from_str(name);2958 proto_param_name = buf_create_from_str(name);
...@@ -2851,7 +2962,11 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -2851,7 +2962,11 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
2851 proto_param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i);2962 proto_param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i);
2852 }2963 }
2853 }2964 }
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;
2855 }2970 }
28562971
2857 if (!fn_decl->hasBody()) {2972 if (!fn_decl->hasBody()) {
...@@ -2863,7 +2978,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -2863,7 +2978,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
2863 // actual function definition with body2978 // actual function definition with body
2864 c->ptr_params.clear();2979 c->ptr_params.clear();
2865 Stmt *body = fn_decl->getBody();2980 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);
2867 assert(actual_body_node != skip_add_to_block_node);2982 assert(actual_body_node != skip_add_to_block_node);
2868 if (actual_body_node == nullptr) {2983 if (actual_body_node == nullptr) {
2869 emit_warning(c, fn_decl->getLocation(), "unable to translate function");2984 emit_warning(c, fn_decl->getLocation(), "unable to translate function");
...@@ -3301,14 +3416,66 @@ static bool decl_visitor(void *context, const Decl *decl) {...@@ -3301,14 +3416,66 @@ static bool decl_visitor(void *context, const Decl *decl) {
3301 return true;3416 return true;
3302}3417}
33033418
3304static bool name_exists(Context *c, Buf *name) {3419static bool name_exists_global(Context *c, Buf *name) {
3305 return get_global(c, name) != nullptr;3420 return get_global(c, name) != nullptr;
3306}3421}
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
3308static void render_aliases(Context *c) {3475static void render_aliases(Context *c) {
3309 for (size_t i = 0; i < c->aliases.length; i += 1) {3476 for (size_t i = 0; i < c->aliases.length; i += 1) {
3310 Alias *alias = &c->aliases.at(i);3477 Alias *alias = &c->aliases.at(i);
3311 if (name_exists(c, alias->new_name))3478 if (name_exists_global(c, alias->new_name))
3312 continue;3479 continue;
33133480
3314 add_global_var(c, alias->new_name, trans_create_node_symbol(c, alias->canon_name));3481 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) {...@@ -3438,7 +3605,7 @@ static void process_symbol_macros(Context *c) {
34383605
3439 // Check if this macro aliases another top level declaration3606 // Check if this macro aliases another top level declaration
3440 AstNode *existing_node = get_global(c, ms.value);3607 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))
3442 continue;3609 continue;
34433610
3444 // If a macro aliases a global variable which is a function pointer, we conclude that3611 // 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) {...@@ -3487,7 +3654,7 @@ static void process_preprocessor_entities(Context *c, ASTUnit &unit) {
3487 continue;3654 continue;
3488 }3655 }
3489 Buf *name = buf_create_from_str(raw_name);3656 Buf *name = buf_create_from_str(raw_name);
3490 if (name_exists(c, name)) {3657 if (name_exists_global(c, name)) {
3491 continue;3658 continue;
3492 }3659 }
34933660
test/translate_c.zig+51
...@@ -963,6 +963,16 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -963,6 +963,16 @@ pub fn addCases(cases: &tests.TranslateCContext) {
963 \\}963 \\}
964 );964 );
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
966 cases.add("break statement",976 cases.add("break statement",
967 \\void foo(void) {977 \\void foo(void) {
968 \\ for (;;) {978 \\ for (;;) {
...@@ -990,6 +1000,47 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -990,6 +1000,47 @@ pub fn addCases(cases: &tests.TranslateCContext) {
990 \\ };1000 \\ };
991 \\}1001 \\}
992 );1002 );
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 //);
993}1044}
9941045
9951046