authorgravatar for ryan.saunderson@kiriworks.comRyan Saunderson <ryan.saunderson@kiriworks.com> 2017-11-27 11:40:41-06:00
committergravatar for ryan.saunderson88@gmail.comdimenus <ryan.saunderson88@gmail.com> 2017-11-27 11:42:48-06:00
log57049b95b3fe183ea995f212b18e70212eaac23e
tree30ea64f61d5f6136e0e129d51970ab95129da5a4
parent04472f57be5e91e82adf9346e71c1421725716d5
parent671183fa9a0be28851002d07ad7ddf0d3bd29b46

Resolving merge w/ upstream master


2 files changed, 218 insertions(+), 84 deletions(-)

src/translate_c.cpp+137-67
...@@ -82,6 +82,7 @@ struct TransScopeSwitch {...@@ -82,6 +82,7 @@ struct TransScopeSwitch {
82 AstNode *switch_node;82 AstNode *switch_node;
83 uint32_t case_index;83 uint32_t case_index;
84 bool found_default;84 bool found_default;
85 Buf *end_label_name;
85};86};
8687
87struct TransScopeVar {88struct TransScopeVar {
...@@ -156,6 +157,19 @@ static void add_global_weak_alias(Context *c, Buf *new_name, Buf *canon_name) {...@@ -156,6 +157,19 @@ static void add_global_weak_alias(Context *c, Buf *new_name, Buf *canon_name) {
156 alias->canon_name = canon_name;157 alias->canon_name = canon_name;
157}158}
158159
160static Buf *trans_lookup_zig_symbol(Context *c, TransScope *scope, Buf *c_symbol_name) {
161 while (scope != nullptr) {
162 if (scope->id == TransScopeIdVar) {
163 TransScopeVar *var_scope = (TransScopeVar *)scope;
164 if (buf_eql_buf(var_scope->c_name, c_symbol_name)) {
165 return var_scope->zig_name;
166 }
167 }
168 scope = scope->parent;
169 }
170 return c_symbol_name;
171}
172
159static AstNode * trans_create_node(Context *c, NodeType id) {173static AstNode * trans_create_node(Context *c, NodeType id) {
160 AstNode *node = allocate<AstNode>(1);174 AstNode *node = allocate<AstNode>(1);
161 node->type = id;175 node->type = id;
...@@ -248,6 +262,18 @@ static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_vol...@@ -248,6 +262,18 @@ static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_vol
248 return node;262 return node;
249}263}
250264
265static AstNode *trans_create_node_goto(Context *c, Buf *label_name) {
266 AstNode *goto_node = trans_create_node(c, NodeTypeGoto);
267 goto_node->data.goto_expr.name = label_name;
268 return goto_node;
269}
270
271static AstNode *trans_create_node_label(Context *c, Buf *label_name) {
272 AstNode *label_node = trans_create_node(c, NodeTypeLabel);
273 label_node->data.label.name = label_name;
274 return label_node;
275}
276
251static AstNode *trans_create_node_bool(Context *c, bool value) {277static AstNode *trans_create_node_bool(Context *c, bool value) {
252 AstNode *bool_node = trans_create_node(c, NodeTypeBoolLiteral);278 AstNode *bool_node = trans_create_node(c, NodeTypeBoolLiteral);
253 bool_node->data.bool_literal.value = value;279 bool_node->data.bool_literal.value = value;
...@@ -414,6 +440,10 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int)...@@ -414,6 +440,10 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int)
414440
415}441}
416442
443static const Type *qual_type_canon(QualType qt) {
444 return qt.getCanonicalType().getTypePtr();
445}
446
417static QualType get_expr_qual_type(Context *c, const Expr *expr) {447static QualType get_expr_qual_type(Context *c, const Expr *expr) {
418 // String literals in C are `char *` but they should really be `const char *`.448 // String literals in C are `char *` but they should really be `const char *`.
419 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {449 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
...@@ -436,10 +466,7 @@ static AstNode *get_expr_type(Context *c, const Expr *expr) {...@@ -436,10 +466,7 @@ static AstNode *get_expr_type(Context *c, const Expr *expr) {
436 return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getLocStart());466 return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getLocStart());
437}467}
438468
439static bool expr_types_equal(Context *c, const Expr *expr1, const Expr *expr2) {469static bool qual_types_equal(QualType t1, QualType t2) {
440 QualType t1 = get_expr_qual_type(c, expr1);
441 QualType t2 = get_expr_qual_type(c, expr2);
442
443 if (t1.isConstQualified() != t2.isConstQualified()) {470 if (t1.isConstQualified() != t2.isConstQualified()) {
444 return false;471 return false;
445 }472 }
...@@ -456,26 +483,27 @@ static bool is_c_void_type(AstNode *node) {...@@ -456,26 +483,27 @@ static bool is_c_void_type(AstNode *node) {
456 return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));483 return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
457}484}
458485
459static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location, const QualType &qt, AstNode *expr) {486static bool expr_types_equal(Context *c, const Expr *expr1, const Expr *expr2) {
460 // TODO: maybe widen to increase size487 QualType t1 = get_expr_qual_type(c, expr1);
461 // TODO: maybe bitcast to change sign488 QualType t2 = get_expr_qual_type(c, expr2);
462 // TODO: maybe truncate to reduce size489
463 return trans_create_node_fn_call_1(c, trans_qual_type(c, qt, source_location), expr);490 return qual_types_equal(t1, t2);
464}491}
465492
466static bool qual_type_is_fn_ptr(Context *c, const QualType &qt) {493static bool qual_type_is_ptr(QualType qt) {
467 const Type *ty = qt.getTypePtr();494 const Type *ty = qual_type_canon(qt);
495 return ty->getTypeClass() == Type::Pointer;
496}
497
498static bool qual_type_is_fn_ptr(Context *c, QualType qt) {
499 const Type *ty = qual_type_canon(qt);
468 if (ty->getTypeClass() != Type::Pointer) {500 if (ty->getTypeClass() != Type::Pointer) {
469 return false;501 return false;
470 }502 }
471 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);503 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
472 QualType child_qt = pointer_ty->getPointeeType();504 QualType child_qt = pointer_ty->getPointeeType();
473 const Type *child_ty = child_qt.getTypePtr();505 const Type *child_ty = child_qt.getTypePtr();
474 if (child_ty->getTypeClass() != Type::Paren) {506 return child_ty->getTypeClass() == Type::FunctionProto;
475 return false;
476 }
477 const ParenType *paren_ty = static_cast<const ParenType *>(child_ty);
478 return paren_ty->getInnerType().getTypePtr()->getTypeClass() == Type::FunctionProto;
479}507}
480508
481static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) {509static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) {
...@@ -568,17 +596,26 @@ static bool qual_type_child_is_fn_proto(const QualType &qt) {...@@ -568,17 +596,26 @@ static bool qual_type_child_is_fn_proto(const QualType &qt) {
568 return false;596 return false;
569}597}
570598
571static QualType resolve_any_typedef(Context *c, QualType qt) {599static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location, QualType dest_type,
572 const Type * ty = qt.getTypePtr();600 QualType src_type, AstNode *expr)
573 if (ty->getTypeClass() != Type::Typedef)601{
574 return qt;602 if (qual_types_equal(dest_type, src_type)) {
575 const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty);603 return expr;
576 const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();604 }
577 return typedef_decl->getUnderlyingType();605 if (qual_type_is_ptr(dest_type) && qual_type_is_ptr(src_type)) {
606 AstNode *ptr_cast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
607 ptr_cast_node->data.fn_call_expr.params.append(trans_qual_type(c, dest_type, source_location));
608 ptr_cast_node->data.fn_call_expr.params.append(expr);
609 return ptr_cast_node;
610 }
611 // TODO: maybe widen to increase size
612 // TODO: maybe bitcast to change sign
613 // TODO: maybe truncate to reduce size
614 return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), expr);
578}615}
579616
580static bool c_is_signed_integer(Context *c, QualType qt) {617static bool c_is_signed_integer(Context *c, QualType qt) {
581 const Type *c_type = resolve_any_typedef(c, qt).getTypePtr();618 const Type *c_type = qual_type_canon(qt);
582 if (c_type->getTypeClass() != Type::Builtin)619 if (c_type->getTypeClass() != Type::Builtin)
583 return false;620 return false;
584 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);621 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
...@@ -597,7 +634,7 @@ static bool c_is_signed_integer(Context *c, QualType qt) {...@@ -597,7 +634,7 @@ static bool c_is_signed_integer(Context *c, QualType qt) {
597}634}
598635
599static bool c_is_unsigned_integer(Context *c, QualType qt) {636static bool c_is_unsigned_integer(Context *c, QualType qt) {
600 const Type *c_type = resolve_any_typedef(c, qt).getTypePtr();637 const Type *c_type = qual_type_canon(qt);
601 if (c_type->getTypeClass() != Type::Builtin)638 if (c_type->getTypeClass() != Type::Builtin)
602 return false;639 return false;
603 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);640 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
...@@ -865,6 +902,11 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou...@@ -865,6 +902,11 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
865 return nullptr;902 return nullptr;
866 }903 }
867 // convert c_void to actual void (only for return type)904 // convert c_void to actual void (only for return type)
905 // we do want to look at the AstNode instead of QualType, because
906 // if they do something like:
907 // typedef Foo void;
908 // void foo(void) -> Foo;
909 // we want to keep the return type AST node.
868 if (is_c_void_type(proto_node->data.fn_proto.return_type)) {910 if (is_c_void_type(proto_node->data.fn_proto.return_type)) {
869 proto_node->data.fn_proto.return_type = nullptr;911 proto_node->data.fn_proto.return_type = nullptr;
870 }912 }
...@@ -1291,19 +1333,28 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result...@@ -1291,19 +1333,28 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
1291 if (rhs == nullptr) return nullptr;1333 if (rhs == nullptr) return nullptr;
1292 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);1334 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
12931335
1336 // operation_type(*_ref)
1337 AstNode *operation_type_cast = trans_c_cast(c, rhs_location,
1338 stmt->getComputationLHSType(),
1339 stmt->getLHS()->getType(),
1340 trans_create_node_prefix_op(c, PrefixOpDereference,
1341 trans_create_node_symbol(c, tmp_var_name)));
1342
1343 // result_type(... >> u5(rhs))
1344 AstNode *result_type_cast = trans_c_cast(c, rhs_location,
1345 stmt->getComputationResultType(),
1346 stmt->getComputationLHSType(),
1347 trans_create_node_bin_op(c,
1348 operation_type_cast,
1349 bin_op,
1350 coerced_rhs));
1351
1352 // *_ref = ...
1294 AstNode *assign_statement = trans_create_node_bin_op(c,1353 AstNode *assign_statement = trans_create_node_bin_op(c,
1295 trans_create_node_prefix_op(c, PrefixOpDereference,1354 trans_create_node_prefix_op(c, PrefixOpDereference,
1296 trans_create_node_symbol(c, tmp_var_name)),1355 trans_create_node_symbol(c, tmp_var_name)),
1297 BinOpTypeAssign,1356 BinOpTypeAssign, result_type_cast);
1298 trans_c_cast(c, rhs_location,1357
1299 stmt->getComputationResultType(),
1300 trans_create_node_bin_op(c,
1301 trans_c_cast(c, rhs_location,
1302 stmt->getComputationLHSType(),
1303 trans_create_node_prefix_op(c, PrefixOpDereference,
1304 trans_create_node_symbol(c, tmp_var_name))),
1305 bin_op,
1306 coerced_rhs)));
1307 child_scope->node->data.block.statements.append(assign_statement);1358 child_scope->node->data.block.statements.append(assign_statement);
13081359
1309 if (result_used == ResultUsedYes) {1360 if (result_used == ResultUsedYes) {
...@@ -1448,7 +1499,8 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const Im...@@ -1448,7 +1499,8 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const Im
1448 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);1499 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1449 if (target_node == nullptr)1500 if (target_node == nullptr)
1450 return nullptr;1501 return nullptr;
1451 return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(), target_node);1502 return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(),
1503 stmt->getSubExpr()->getType(), target_node);
1452 }1504 }
1453 case CK_FunctionToPointerDecay:1505 case CK_FunctionToPointerDecay:
1454 case CK_ArrayToPointerDecay:1506 case CK_ArrayToPointerDecay:
...@@ -1637,13 +1689,14 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const Im...@@ -1637,13 +1689,14 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const Im
1637 zig_unreachable();1689 zig_unreachable();
1638}1690}
16391691
1640static AstNode *trans_decl_ref_expr(Context *c, const DeclRefExpr *stmt, TransLRValue lrval) {1692static AstNode *trans_decl_ref_expr(Context *c, TransScope *scope, const DeclRefExpr *stmt, TransLRValue lrval) {
1641 const ValueDecl *value_decl = stmt->getDecl();1693 const ValueDecl *value_decl = stmt->getDecl();
1642 Buf *symbol_name = buf_create_from_str(decl_name(value_decl));1694 Buf *c_symbol_name = buf_create_from_str(decl_name(value_decl));
1695 Buf *zig_symbol_name = trans_lookup_zig_symbol(c, scope, c_symbol_name);
1643 if (lrval == TransLValue) {1696 if (lrval == TransLValue) {
1644 c->ptr_params.put(symbol_name, true);1697 c->ptr_params.put(zig_symbol_name, true);
1645 }1698 }
1646 return trans_create_node_symbol(c, symbol_name);1699 return trans_create_node_symbol(c, zig_symbol_name);
1647}1700}
16481701
1649static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, TransScope *scope,1702static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, TransScope *scope,
...@@ -2150,9 +2203,23 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *...@@ -2150,9 +2203,23 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
2150 if (callee_raw_node == nullptr)2203 if (callee_raw_node == nullptr)
2151 return nullptr;2204 return nullptr;
21522205
2153 AstNode *callee_node;2206 AstNode *callee_node = nullptr;
2154 if (qual_type_is_fn_ptr(c, stmt->getCallee()->getType())) {2207 if (qual_type_is_fn_ptr(c, stmt->getCallee()->getType())) {
2155 callee_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, callee_raw_node);2208 if (stmt->getCallee()->getStmtClass() == Stmt::ImplicitCastExprClass) {
2209 const ImplicitCastExpr *implicit_cast = static_cast<const ImplicitCastExpr *>(stmt->getCallee());
2210 if (implicit_cast->getCastKind() == CK_FunctionToPointerDecay) {
2211 if (implicit_cast->getSubExpr()->getStmtClass() == Stmt::DeclRefExprClass) {
2212 const DeclRefExpr *decl_ref = static_cast<const DeclRefExpr *>(implicit_cast->getSubExpr());
2213 const Decl *decl = decl_ref->getFoundDecl();
2214 if (decl->getKind() == Decl::Function) {
2215 callee_node = callee_raw_node;
2216 }
2217 }
2218 }
2219 }
2220 if (callee_node == nullptr) {
2221 callee_node = trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, callee_raw_node);
2222 }
2156 } else {2223 } else {
2157 callee_node = callee_raw_node;2224 callee_node = callee_raw_node;
2158 }2225 }
...@@ -2210,7 +2277,7 @@ static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, Tran...@@ -2210,7 +2277,7 @@ static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, Tran
2210 if (sub_expr_node == nullptr)2277 if (sub_expr_node == nullptr)
2211 return nullptr;2278 return nullptr;
22122279
2213 return trans_c_cast(c, stmt->getLocStart(), stmt->getType(), sub_expr_node);2280 return trans_c_cast(c, stmt->getLocStart(), stmt->getType(), stmt->getSubExpr()->getType(), sub_expr_node);
2214}2281}
22152282
2216static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scope,2283static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scope,
...@@ -2283,11 +2350,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt...@@ -2283,11 +2350,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt
2283}2350}
22842351
2285static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const SwitchStmt *stmt) {2352static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const SwitchStmt *stmt) {
2286 TransScopeWhile *while_scope = trans_scope_while_create(c, parent_scope);2353 TransScopeBlock *block_scope = trans_scope_block_create(c, parent_scope);
2287 while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
2288
2289 TransScopeBlock *block_scope = trans_scope_block_create(c, &while_scope->base);
2290 while_scope->node->data.while_expr.body = block_scope->node;
22912354
2292 TransScopeSwitch *switch_scope;2355 TransScopeSwitch *switch_scope;
22932356
...@@ -2305,6 +2368,10 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const Sw...@@ -2305,6 +2368,10 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const Sw
2305 }2368 }
2306 block_scope->node->data.block.statements.append(switch_scope->switch_node);2369 block_scope->node->data.block.statements.append(switch_scope->switch_node);
23072370
2371 // TODO avoid name collisions
2372 Buf *end_label_name = buf_create_from_str("end");
2373 switch_scope->end_label_name = end_label_name;
2374
2308 const Expr *cond_expr = stmt->getCond();2375 const Expr *cond_expr = stmt->getCond();
2309 assert(cond_expr != nullptr);2376 assert(cond_expr != nullptr);
23102377
...@@ -2331,14 +2398,16 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const Sw...@@ -2331,14 +2398,16 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const Sw
23312398
2332 if (!switch_scope->found_default && !stmt->isAllEnumCasesCovered()) {2399 if (!switch_scope->found_default && !stmt->isAllEnumCasesCovered()) {
2333 AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);2400 AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
2334 prong_node->data.switch_prong.expr = trans_create_node(c, NodeTypeBreak);2401 prong_node->data.switch_prong.expr = trans_create_node_goto(c, end_label_name);
2335 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);2402 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
2336 }2403 }
23372404
2338 // This is necessary if the last switch case "falls through" the end of the switch block2405 // This is necessary if the last switch case "falls through" the end of the switch block
2339 block_scope->node->data.block.statements.append(trans_create_node(c, NodeTypeBreak));2406 block_scope->node->data.block.statements.append(trans_create_node_goto(c, end_label_name));
23402407
2341 return while_scope->node;2408 block_scope->node->data.block.statements.append(trans_create_node_label(c, end_label_name));
2409
2410 return block_scope->node;
2342}2411}
23432412
2344static int trans_switch_case(Context *c, TransScope *parent_scope, const CaseStmt *stmt, AstNode **out_node,2413static int trans_switch_case(Context *c, TransScope *parent_scope, const CaseStmt *stmt, AstNode **out_node,
...@@ -2365,18 +2434,13 @@ static int trans_switch_case(Context *c, TransScope *parent_scope, const CaseStm...@@ -2365,18 +2434,13 @@ static int trans_switch_case(Context *c, TransScope *parent_scope, const CaseStm
2365 return ErrorUnexpected;2434 return ErrorUnexpected;
2366 prong_node->data.switch_prong.items.append(item_node);2435 prong_node->data.switch_prong.items.append(item_node);
23672436
2368 AstNode *goto_node = trans_create_node(c, NodeTypeGoto);2437 prong_node->data.switch_prong.expr = trans_create_node_goto(c, label_name);
2369 goto_node->data.goto_expr.name = label_name;
2370 prong_node->data.switch_prong.expr = goto_node;
23712438
2372 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);2439 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
2373 }2440 }
23742441
2375 AstNode *label_node = trans_create_node(c, NodeTypeLabel);
2376 label_node->data.label.name = label_name;
2377
2378 TransScopeBlock *scope_block = trans_scope_block_find(parent_scope);2442 TransScopeBlock *scope_block = trans_scope_block_find(parent_scope);
2379 scope_block->node->data.block.statements.append(label_node);2443 scope_block->node->data.block.statements.append(trans_create_node_label(c, label_name));
23802444
2381 AstNode *sub_stmt_node;2445 AstNode *sub_stmt_node;
2382 TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node);2446 TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node);
...@@ -2399,23 +2463,19 @@ static int trans_switch_default(Context *c, TransScope *parent_scope, const Defa...@@ -2399,23 +2463,19 @@ static int trans_switch_default(Context *c, TransScope *parent_scope, const Defa
23992463
2400 Buf *label_name = buf_sprintf("default");2464 Buf *label_name = buf_sprintf("default");
24012465
2402 AstNode *label_node = trans_create_node(c, NodeTypeLabel);
2403 label_node->data.label.name = label_name;
2404
2405 {2466 {
2406 // Add the prong2467 // Add the prong
2407 AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);2468 AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
24082469
2409 AstNode *goto_node = trans_create_node(c, NodeTypeGoto);2470 prong_node->data.switch_prong.expr = trans_create_node_goto(c, label_name);
2410 goto_node->data.goto_expr.name = label_name;
2411 prong_node->data.switch_prong.expr = goto_node;
24122471
2413 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);2472 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
2414 switch_scope->found_default = true;2473 switch_scope->found_default = true;
2415 }2474 }
24162475
2417 TransScopeBlock *scope_block = trans_scope_block_find(parent_scope);2476 TransScopeBlock *scope_block = trans_scope_block_find(parent_scope);
2418 scope_block->node->data.block.statements.append(label_node);2477 scope_block->node->data.block.statements.append(trans_create_node_label(c, label_name));
2478
24192479
2420 AstNode *sub_stmt_node;2480 AstNode *sub_stmt_node;
2421 TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node);2481 TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node);
...@@ -2500,7 +2560,17 @@ static AstNode *trans_string_literal(Context *c, TransScope *scope, const String...@@ -2500,7 +2560,17 @@ static AstNode *trans_string_literal(Context *c, TransScope *scope, const String
2500}2560}
25012561
2502static AstNode *trans_break_stmt(Context *c, TransScope *scope, const BreakStmt *stmt) {2562static AstNode *trans_break_stmt(Context *c, TransScope *scope, const BreakStmt *stmt) {
2503 return trans_create_node(c, NodeTypeBreak);2563 TransScope *cur_scope = scope;
2564 while (cur_scope != nullptr) {
2565 if (cur_scope->id == TransScopeIdWhile) {
2566 return trans_create_node(c, NodeTypeBreak);
2567 } else if (cur_scope->id == TransScopeIdSwitch) {
2568 TransScopeSwitch *switch_scope = (TransScopeSwitch *)cur_scope;
2569 return trans_create_node_goto(c, switch_scope->end_label_name);
2570 }
2571 cur_scope = cur_scope->parent;
2572 }
2573 zig_unreachable();
2504}2574}
25052575
2506static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const ContinueStmt *stmt) {2576static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const ContinueStmt *stmt) {
...@@ -2546,7 +2616,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,...@@ -2546,7 +2616,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
2546 trans_implicit_cast_expr(c, scope, (const ImplicitCastExpr *)stmt));2616 trans_implicit_cast_expr(c, scope, (const ImplicitCastExpr *)stmt));
2547 case Stmt::DeclRefExprClass:2617 case Stmt::DeclRefExprClass:
2548 return wrap_stmt(out_node, out_child_scope, scope,2618 return wrap_stmt(out_node, out_child_scope, scope,
2549 trans_decl_ref_expr(c, (const DeclRefExpr *)stmt, lrvalue));2619 trans_decl_ref_expr(c, scope, (const DeclRefExpr *)stmt, lrvalue));
2550 case Stmt::UnaryOperatorClass:2620 case Stmt::UnaryOperatorClass:
2551 return wrap_stmt(out_node, out_child_scope, scope,2621 return wrap_stmt(out_node, out_child_scope, scope,
2552 trans_unary_operator(c, result_used, scope, (const UnaryOperator *)stmt));2622 trans_unary_operator(c, result_used, scope, (const UnaryOperator *)stmt));
test/translate_c.zig+81-17
...@@ -677,12 +677,12 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -677,12 +677,12 @@ pub fn addCases(cases: &tests.TranslateCContext) {
677 \\ };677 \\ };
678 \\ a >>= @import("std").math.Log2Int(c_int)({678 \\ a >>= @import("std").math.Log2Int(c_int)({
679 \\ const _ref = &a;679 \\ const _ref = &a;
680 \\ (*_ref) = c_int(c_int(*_ref) >> @import("std").math.Log2Int(c_int)(1));680 \\ (*_ref) = ((*_ref) >> @import("std").math.Log2Int(c_int)(1));
681 \\ *_ref681 \\ *_ref
682 \\ });682 \\ });
683 \\ a <<= @import("std").math.Log2Int(c_int)({683 \\ a <<= @import("std").math.Log2Int(c_int)({
684 \\ const _ref = &a;684 \\ const _ref = &a;
685 \\ (*_ref) = c_int(c_int(*_ref) << @import("std").math.Log2Int(c_int)(1));685 \\ (*_ref) = ((*_ref) << @import("std").math.Log2Int(c_int)(1));
686 \\ *_ref686 \\ *_ref
687 \\ });687 \\ });
688 \\}688 \\}
...@@ -735,12 +735,12 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -735,12 +735,12 @@ pub fn addCases(cases: &tests.TranslateCContext) {
735 \\ };735 \\ };
736 \\ a >>= @import("std").math.Log2Int(c_uint)({736 \\ a >>= @import("std").math.Log2Int(c_uint)({
737 \\ const _ref = &a;737 \\ const _ref = &a;
738 \\ (*_ref) = c_uint(c_uint(*_ref) >> @import("std").math.Log2Int(c_uint)(1));738 \\ (*_ref) = ((*_ref) >> @import("std").math.Log2Int(c_uint)(1));
739 \\ *_ref739 \\ *_ref
740 \\ });740 \\ });
741 \\ a <<= @import("std").math.Log2Int(c_uint)({741 \\ a <<= @import("std").math.Log2Int(c_uint)({
742 \\ const _ref = &a;742 \\ const _ref = &a;
743 \\ (*_ref) = c_uint(c_uint(*_ref) << @import("std").math.Log2Int(c_uint)(1));743 \\ (*_ref) = ((*_ref) << @import("std").math.Log2Int(c_uint)(1));
744 \\ *_ref744 \\ *_ref
745 \\ });745 \\ });
746 \\}746 \\}
...@@ -878,17 +878,21 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -878,17 +878,21 @@ pub fn addCases(cases: &tests.TranslateCContext) {
878878
879 cases.addC("deref function pointer",879 cases.addC("deref function pointer",
880 \\void foo(void) {}880 \\void foo(void) {}
881 \\void baz(void) {}
881 \\void bar(void) {882 \\void bar(void) {
882 \\ void(*f)(void) = foo;883 \\ void(*f)(void) = foo;
883 \\ f();884 \\ f();
884 \\ (*(f))();885 \\ (*(f))();
886 \\ baz();
885 \\}887 \\}
886 ,888 ,
887 \\export fn foo() {}889 \\export fn foo() {}
890 \\export fn baz() {}
888 \\export fn bar() {891 \\export fn bar() {
889 \\ var f: ?extern fn() = foo;892 \\ var f: ?extern fn() = foo;
890 \\ (??f)();893 \\ (??f)();
891 \\ (??f)();894 \\ (??f)();
895 \\ baz();
892 \\}896 \\}
893 );897 );
894898
...@@ -1019,7 +1023,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1019,7 +1023,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1019 ,1023 ,
1020 \\fn foo(_arg_x: c_int) -> c_int {1024 \\fn foo(_arg_x: c_int) -> c_int {
1021 \\ var x = _arg_x;1025 \\ var x = _arg_x;
1022 \\ while (true) {1026 \\ {
1023 \\ switch (x) {1027 \\ switch (x) {
1024 \\ 1 => goto case_0,1028 \\ 1 => goto case_0,
1025 \\ 2 => goto case_1,1029 \\ 2 => goto case_1,
...@@ -1030,18 +1034,19 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1030,18 +1034,19 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1030 \\ case_0:1034 \\ case_0:
1031 \\ x += 1;1035 \\ x += 1;
1032 \\ case_1:1036 \\ case_1:
1033 \\ break;1037 \\ goto end;
1034 \\ case_2:1038 \\ case_2:
1035 \\ case_3:1039 \\ case_3:
1036 \\ return x + 1;1040 \\ return x + 1;
1037 \\ default:1041 \\ default:
1038 \\ return 10;1042 \\ return 10;
1039 \\ break;1043 \\ goto end;
1044 \\ end:
1040 \\ };1045 \\ };
1041 \\ return x + 13;1046 \\ return x + 13;
1042 \\}1047 \\}
1043 );1048 );
10441049
1045 cases.add("macros with field targets",1050 cases.add("macros with field targets",
1046 \\typedef unsigned int GLbitfield;1051 \\typedef unsigned int GLbitfield;
1047 \\typedef void (*PFNGLCLEARPROC) (GLbitfield mask);1052 \\typedef void (*PFNGLCLEARPROC) (GLbitfield mask);
...@@ -1077,13 +1082,72 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1077,13 +1082,72 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1077 ,1082 ,
1078 \\pub const OpenGLProcs = union_OpenGLProcs;1083 \\pub const OpenGLProcs = union_OpenGLProcs;
1079 );1084 );
1080}
10811085
1082// TODO1086 cases.add("switch statement with no default",
1083//float *ptrcast(int *a) {1087 \\int foo(int x) {
1084// return (float *)a;1088 \\ switch (x) {
1085//}1089 \\ case 1:
1086// should translate to1090 \\ x += 1;
1087// fn ptrcast(a: ?&c_int) -> ?&f32 {1091 \\ case 2:
1088// return @ptrCast(?&f32, a);1092 \\ break;
1089// }1093 \\ case 3:
1094 \\ case 4:
1095 \\ return x + 1;
1096 \\ }
1097 \\ return x + 13;
1098 \\}
1099 ,
1100 \\fn foo(_arg_x: c_int) -> c_int {
1101 \\ var x = _arg_x;
1102 \\ {
1103 \\ switch (x) {
1104 \\ 1 => goto case_0,
1105 \\ 2 => goto case_1,
1106 \\ 3 => goto case_2,
1107 \\ 4 => goto case_3,
1108 \\ else => goto end,
1109 \\ };
1110 \\ case_0:
1111 \\ x += 1;
1112 \\ case_1:
1113 \\ goto end;
1114 \\ case_2:
1115 \\ case_3:
1116 \\ return x + 1;
1117 \\ goto end;
1118 \\ end:
1119 \\ };
1120 \\ return x + 13;
1121 \\}
1122 );
1123
1124 cases.add("variable name shadowing",
1125 \\int foo(void) {
1126 \\ int x = 1;
1127 \\ {
1128 \\ int x = 2;
1129 \\ x += 1;
1130 \\ }
1131 \\ return x;
1132 \\}
1133 ,
1134 \\pub fn foo() -> c_int {
1135 \\ var x: c_int = 1;
1136 \\ {
1137 \\ var x_0: c_int = 2;
1138 \\ x_0 += 1;
1139 \\ };
1140 \\ return x;
1141 \\}
1142 );
1143
1144 cases.add("pointer casting",
1145 \\float *ptrcast(int *a) {
1146 \\ return (float *)a;
1147 \\}
1148 ,
1149 \\fn ptrcast(a: ?&c_int) -> ?&f32 {
1150 \\ return @ptrCast(?&f32, a);
1151 \\}
1152 );
1153}