authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-26 00:58:11-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-11-26 00:58:11-05:00
log1b0e90f70b4dc26c2ba96b7b5709a3ff269bb48a
tree365012ba5cfbb10d6723733edbe23c28fd446634
parent687e3592919940bc3c77a22adbee065fb5c1bc7e

translate-c supports switch statements


2 files changed, 280 insertions(+), 127 deletions(-)

src/translate_c.cpp+240-87
......@@ -69,6 +69,7 @@ enum TransScopeId {
6969 TransScopeIdVar,
7070 TransScopeIdBlock,
7171 TransScopeIdRoot,
72 TransScopeIdWhile,
7273};
7374
7475struct TransScope {
......@@ -79,6 +80,8 @@ struct TransScope {
7980struct TransScopeSwitch {
8081 TransScope base;
8182 AstNode *switch_node;
83 uint32_t case_index;
84 bool found_default;
8285};
8386
8487struct TransScopeVar {
......@@ -96,12 +99,19 @@ struct TransScopeRoot {
9699 TransScope base;
97100};
98101
102struct TransScopeWhile {
103 TransScope base;
104 AstNode *node;
105};
106
99107static TransScopeRoot *trans_scope_root_create(Context *c);
108static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope);
100109static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope);
101110static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scope, Buf *wanted_name);
102//static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope);
111static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope);
103112
104113static TransScopeBlock *trans_scope_block_find(TransScope *scope);
114static TransScopeSwitch *trans_scope_switch_find(TransScope *scope);
105115
106116static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);
107117static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
......@@ -238,6 +248,12 @@ static AstNode *trans_create_node_addr_of(Context *c, bool is_const, bool is_vol
238248 return node;
239249}
240250
251static AstNode *trans_create_node_bool(Context *c, bool value) {
252 AstNode *bool_node = trans_create_node(c, NodeTypeBoolLiteral);
253 bool_node->data.bool_literal.value = value;
254 return bool_node;
255}
256
241257static AstNode *trans_create_node_str_lit_c(Context *c, Buf *buf) {
242258 AstNode *node = trans_create_node(c, NodeTypeStringLiteral);
243259 node->data.string_literal.buf = buf;
......@@ -965,22 +981,30 @@ static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &s
965981 return trans_type(c, qt.getTypePtr(), source_loc);
966982}
967983
968static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const CompoundStmt *stmt,
969 TransScope **out_node_scope)
984static int trans_compound_stmt_inline(Context *c, TransScope *scope, const CompoundStmt *stmt,
985 AstNode *block_node, TransScope **out_node_scope)
970986{
971 TransScopeBlock *child_scope_block = trans_scope_block_create(c, scope);
972 scope = &child_scope_block->base;
987 assert(block_node->type == NodeTypeBlock);
973988 for (CompoundStmt::const_body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
974989 AstNode *child_node;
975990 scope = trans_stmt(c, scope, *it, &child_node);
976991 if (scope == nullptr)
977 return nullptr;
992 return ErrorUnexpected;
978993 if (child_node != nullptr)
979 child_scope_block->node->data.block.statements.append(child_node);
994 block_node->data.block.statements.append(child_node);
980995 }
981996 if (out_node_scope != nullptr) {
982 *out_node_scope = &child_scope_block->base;
997 *out_node_scope = scope;
983998 }
999 return ErrorNone;
1000}
1001
1002static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const CompoundStmt *stmt,
1003 TransScope **out_node_scope)
1004{
1005 TransScopeBlock *child_scope_block = trans_scope_block_create(c, scope);
1006 if (trans_compound_stmt_inline(c, &child_scope_block->base, stmt, child_scope_block->node, out_node_scope))
1007 return nullptr;
9841008 return child_scope_block->node;
9851009}
9861010
......@@ -2081,17 +2105,18 @@ static int trans_local_declaration(Context *c, TransScope *scope, const DeclStmt
20812105}
20822106
20832107static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt *stmt) {
2084 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
2108 TransScopeWhile *while_scope = trans_scope_while_create(c, scope);
20852109
2086 while_node->data.while_expr.condition = trans_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
2087 if (while_node->data.while_expr.condition == nullptr)
2110 while_scope->node->data.while_expr.condition = trans_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
2111 if (while_scope->node->data.while_expr.condition == nullptr)
20882112 return nullptr;
20892113
2090 TransScope *body_scope = trans_stmt(c, scope, stmt->getBody(), &while_node->data.while_expr.body);
2114 TransScope *body_scope = trans_stmt(c, &while_scope->base, stmt->getBody(),
2115 &while_scope->node->data.while_expr.body);
20912116 if (body_scope == nullptr)
20922117 return nullptr;
20932118
2094 return while_node;
2119 return while_scope->node;
20952120}
20962121
20972122static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt *stmt) {
......@@ -2201,11 +2226,9 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scop
22012226}
22022227
22032228static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt *stmt) {
2204 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
2229 TransScopeWhile *while_scope = trans_scope_while_create(c, parent_scope);
22052230
2206 AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral);
2207 true_node->data.bool_literal.value = true;
2208 while_node->data.while_expr.condition = true_node;
2231 while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
22092232
22102233 AstNode *body_node;
22112234 TransScope *child_scope;
......@@ -2222,7 +2245,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt
22222245 // zig: }
22232246
22242247 // We call the low level function so that we can set child_scope to the scope of the generated block.
2225 if (trans_stmt_extra(c, parent_scope, stmt->getBody(), ResultUsedNo, TransRValue, &body_node,
2248 if (trans_stmt_extra(c, &while_scope->base, stmt->getBody(), ResultUsedNo, TransRValue, &body_node,
22262249 nullptr, &child_scope))
22272250 {
22282251 return nullptr;
......@@ -2237,7 +2260,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt
22372260 // zig: a;
22382261 // zig: if (!cond) break;
22392262 // zig: }
2240 TransScopeBlock *child_block_scope = trans_scope_block_create(c, parent_scope);
2263 TransScopeBlock *child_block_scope = trans_scope_block_create(c, &while_scope->base);
22412264 body_node = child_block_scope->node;
22422265 AstNode *child_statement;
22432266 child_scope = trans_stmt(c, &child_block_scope->base, stmt->getBody(), &child_statement);
......@@ -2254,89 +2277,206 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt
22542277
22552278 body_node->data.block.statements.append(terminator_node);
22562279
2257 while_node->data.while_expr.body = body_node;
2280 while_scope->node->data.while_expr.body = body_node;
22582281
2259 return while_node;
2282 return while_scope->node;
22602283}
22612284
2262//static AstNode *trans_switch_stmt(Context *c, TransScope *scope, const SwitchStmt *stmt) {
2263// AstNode *switch_block_node = trans_create_node(c, NodeTypeBlock);
2264// AstNode *switch_node = trans_create_node(c, NodeTypeSwitchExpr);
2265// const DeclStmt *var_decl_stmt = stmt->getConditionVariableDeclStmt();
2266// if (var_decl_stmt != nullptr) {
2267// AstNode *vars_node = trans_stmt(c, switch_block_node, var_decl_stmt);
2268// if (vars_node == nullptr)
2269// return nullptr;
2270// if (vars_node != nullptr)
2271// switch_block_node->data.block.statements.append(vars_node);
2272// }
2273// switch_block_node->data.block.statements.append(switch_node);
2274//
2275// const Expr *cond_expr = stmt->getCond();
2276// assert(cond_expr != nullptr);
2277//
2278// AstNode *expr_node = trans_expr(c, ResultUsedYes, switch_block_node, cond_expr, TransRValue);
2279// if (expr_node == nullptr)
2280// return nullptr;
2281// switch_node->data.switch_expr.expr = expr_node;
2282//
2283// AstNode *body_node = trans_stmt(c, switch_block_node, stmt->getBody());
2284// if (body_node == nullptr)
2285// return nullptr;
2286// if (body_node != nullptr)
2287// switch_block_node->data.block.statements.append(body_node);
2288//
2289// return switch_block_node;
2290//}
2285static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const SwitchStmt *stmt) {
2286 TransScopeWhile *while_scope = trans_scope_while_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;
2291
2292 TransScopeSwitch *switch_scope;
2293
2294 const DeclStmt *var_decl_stmt = stmt->getConditionVariableDeclStmt();
2295 if (var_decl_stmt == nullptr) {
2296 switch_scope = trans_scope_switch_create(c, &block_scope->base);
2297 } else {
2298 AstNode *vars_node;
2299 TransScope *var_scope = trans_stmt(c, &block_scope->base, var_decl_stmt, &vars_node);
2300 if (var_scope == nullptr)
2301 return nullptr;
2302 if (vars_node != nullptr)
2303 block_scope->node->data.block.statements.append(vars_node);
2304 switch_scope = trans_scope_switch_create(c, var_scope);
2305 }
2306 block_scope->node->data.block.statements.append(switch_scope->switch_node);
2307
2308 const Expr *cond_expr = stmt->getCond();
2309 assert(cond_expr != nullptr);
2310
2311 AstNode *expr_node = trans_expr(c, ResultUsedYes, &block_scope->base, cond_expr, TransRValue);
2312 if (expr_node == nullptr)
2313 return nullptr;
2314 switch_scope->switch_node->data.switch_expr.expr = expr_node;
2315
2316 AstNode *body_node;
2317 const Stmt *body_stmt = stmt->getBody();
2318 if (body_stmt->getStmtClass() == Stmt::CompoundStmtClass) {
2319 if (trans_compound_stmt_inline(c, &switch_scope->base, (const CompoundStmt *)body_stmt,
2320 block_scope->node, nullptr))
2321 {
2322 return nullptr;
2323 }
2324 } else {
2325 TransScope *body_scope = trans_stmt(c, &switch_scope->base, body_stmt, &body_node);
2326 if (body_scope == nullptr)
2327 return nullptr;
2328 if (body_node != nullptr)
2329 block_scope->node->data.block.statements.append(body_node);
2330 }
2331
2332 if (!switch_scope->found_default && !stmt->isAllEnumCasesCovered()) {
2333 AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
2334 prong_node->data.switch_prong.expr = trans_create_node(c, NodeTypeBreak);
2335 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
2336 }
2337
2338 // 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));
2340
2341 return while_scope->node;
2342}
2343
2344static int trans_switch_case(Context *c, TransScope *parent_scope, const CaseStmt *stmt, AstNode **out_node,
2345 TransScope **out_scope)
2346{
2347 *out_node = nullptr;
2348
2349 if (stmt->getRHS() != nullptr) {
2350 emit_warning(c, stmt->getLocStart(), "TODO support GNU switch case a ... b extension");
2351 return ErrorUnexpected;
2352 }
2353
2354 TransScopeSwitch *switch_scope = trans_scope_switch_find(parent_scope);
2355 assert(switch_scope != nullptr);
2356
2357 Buf *label_name = buf_sprintf("case_%" PRIu32, switch_scope->case_index);
2358 switch_scope->case_index += 1;
2359
2360 {
2361 // Add the prong
2362 AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
2363 AstNode *item_node = trans_expr(c, ResultUsedYes, &switch_scope->base, stmt->getLHS(), TransRValue);
2364 if (item_node == nullptr)
2365 return ErrorUnexpected;
2366 prong_node->data.switch_prong.items.append(item_node);
2367
2368 AstNode *goto_node = trans_create_node(c, NodeTypeGoto);
2369 goto_node->data.goto_expr.name = label_name;
2370 prong_node->data.switch_prong.expr = goto_node;
2371
2372 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
2373 }
2374
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);
2379 scope_block->node->data.block.statements.append(label_node);
2380
2381 AstNode *sub_stmt_node;
2382 TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node);
2383 if (new_scope == nullptr)
2384 return ErrorUnexpected;
2385 if (sub_stmt_node != nullptr)
2386 scope_block->node->data.block.statements.append(sub_stmt_node);
2387
2388 *out_scope = new_scope;
2389 return ErrorNone;
2390}
2391
2392static int trans_switch_default(Context *c, TransScope *parent_scope, const DefaultStmt *stmt, AstNode **out_node,
2393 TransScope **out_scope)
2394{
2395 *out_node = nullptr;
2396
2397 TransScopeSwitch *switch_scope = trans_scope_switch_find(parent_scope);
2398 assert(switch_scope != nullptr);
2399
2400 Buf *label_name = buf_sprintf("default");
2401
2402 AstNode *label_node = trans_create_node(c, NodeTypeLabel);
2403 label_node->data.label.name = label_name;
2404
2405 {
2406 // Add the prong
2407 AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
2408
2409 AstNode *goto_node = trans_create_node(c, NodeTypeGoto);
2410 goto_node->data.goto_expr.name = label_name;
2411 prong_node->data.switch_prong.expr = goto_node;
2412
2413 switch_scope->switch_node->data.switch_expr.prongs.append(prong_node);
2414 switch_scope->found_default = true;
2415 }
2416
2417 TransScopeBlock *scope_block = trans_scope_block_find(parent_scope);
2418 scope_block->node->data.block.statements.append(label_node);
2419
2420 AstNode *sub_stmt_node;
2421 TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node);
2422 if (new_scope == nullptr)
2423 return ErrorUnexpected;
2424 if (sub_stmt_node != nullptr)
2425 scope_block->node->data.block.statements.append(sub_stmt_node);
2426
2427 *out_scope = new_scope;
2428 return ErrorNone;
2429}
22912430
22922431static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForStmt *stmt) {
22932432 AstNode *loop_block_node;
2294 TransScope *inner_scope;
2295 AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr);
2433 TransScopeWhile *while_scope;
2434 TransScope *cond_scope;
22962435 const Stmt *init_stmt = stmt->getInit();
22972436 if (init_stmt == nullptr) {
2298 loop_block_node = while_node;
2299 inner_scope = parent_scope;
2437 while_scope = trans_scope_while_create(c, parent_scope);
2438 loop_block_node = while_scope->node;
2439 cond_scope = parent_scope;
23002440 } else {
23012441 TransScopeBlock *child_scope = trans_scope_block_create(c, parent_scope);
23022442 loop_block_node = child_scope->node;
2303 inner_scope = &child_scope->base;
23042443
23052444 AstNode *vars_node;
2306 inner_scope = trans_stmt(c, &child_scope->base, init_stmt, &vars_node);
2307 if (inner_scope == nullptr)
2445 cond_scope = trans_stmt(c, &child_scope->base, init_stmt, &vars_node);
2446 if (cond_scope == nullptr)
23082447 return nullptr;
23092448 if (vars_node != nullptr)
23102449 child_scope->node->data.block.statements.append(vars_node);
23112450
2312 child_scope->node->data.block.statements.append(while_node);
2451 while_scope = trans_scope_while_create(c, cond_scope);
2452
2453 child_scope->node->data.block.statements.append(while_scope->node);
23132454 }
23142455
23152456 const Stmt *cond_stmt = stmt->getCond();
23162457 if (cond_stmt == nullptr) {
2317 AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral);
2318 true_node->data.bool_literal.value = true;
2319 while_node->data.while_expr.condition = true_node;
2458 while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
23202459 } else {
2321 TransScope *cond_scope = trans_stmt(c, inner_scope, cond_stmt, &while_node->data.while_expr.condition);
2322 if (cond_scope == nullptr)
2460 TransScope *end_cond_scope = trans_stmt(c, cond_scope, cond_stmt,
2461 &while_scope->node->data.while_expr.condition);
2462 if (end_cond_scope == nullptr)
23232463 return nullptr;
23242464 }
23252465
23262466 const Stmt *inc_stmt = stmt->getInc();
23272467 if (inc_stmt != nullptr) {
23282468 AstNode *inc_node;
2329 TransScope *inc_scope = trans_stmt(c, inner_scope, inc_stmt, &inc_node);
2469 TransScope *inc_scope = trans_stmt(c, cond_scope, inc_stmt, &inc_node);
23302470 if (inc_scope == nullptr)
23312471 return nullptr;
2332 while_node->data.while_expr.continue_expr = inc_node;
2472 while_scope->node->data.while_expr.continue_expr = inc_node;
23332473 }
23342474
2335 AstNode *child_statement;
2336 TransScope *body_scope = trans_stmt(c, inner_scope, stmt->getBody(), &child_statement);
2475 AstNode *body_statement;
2476 TransScope *body_scope = trans_stmt(c, &while_scope->base, stmt->getBody(), &body_statement);
23372477 if (body_scope == nullptr)
23382478 return nullptr;
2339 while_node->data.while_expr.body = child_statement;
2479 while_scope->node->data.while_expr.body = body_statement;
23402480
23412481 return loop_block_node;
23422482}
......@@ -2371,9 +2511,8 @@ static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_
23712511 if (result_node == nullptr)
23722512 return ErrorUnexpected;
23732513 *out_node = result_node;
2374 if (out_scope != nullptr) {
2514 if (out_scope != nullptr)
23752515 *out_scope = in_scope;
2376 }
23772516 return ErrorNone;
23782517}
23792518
......@@ -2456,18 +2595,13 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
24562595 case Stmt::ParenExprClass:
24572596 return wrap_stmt(out_node, out_child_scope, scope,
24582597 trans_expr(c, result_used, scope, ((const ParenExpr*)stmt)->getSubExpr(), lrvalue));
2459// case Stmt::SwitchStmtClass:
2460// return wrap_stmt(out_node, out_child_scope, scope,
2461// trans_switch_stmt(c, scope, (const SwitchStmt *)stmt));
24622598 case Stmt::SwitchStmtClass:
2463 emit_warning(c, stmt->getLocStart(), "TODO handle C SwitchStmtClass");
2464 return ErrorUnexpected;
2599 return wrap_stmt(out_node, out_child_scope, scope,
2600 trans_switch_stmt(c, scope, (const SwitchStmt *)stmt));
24652601 case Stmt::CaseStmtClass:
2466 emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass");
2467 return ErrorUnexpected;
2602 return trans_switch_case(c, scope, (const CaseStmt *)stmt, out_node, out_child_scope);
24682603 case Stmt::DefaultStmtClass:
2469 emit_warning(c, stmt->getLocStart(), "TODO handle C DefaultStmtClass");
2470 return ErrorUnexpected;
2604 return trans_switch_default(c, scope, (const DefaultStmt *)stmt, out_node, out_child_scope);
24712605 case Stmt::NoStmtClass:
24722606 emit_warning(c, stmt->getLocStart(), "TODO handle C NoStmtClass");
24732607 return ErrorUnexpected;
......@@ -2981,7 +3115,8 @@ static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope
29813115 TransLRValue lrval)
29823116{
29833117 AstNode *result_node;
2984 if (trans_stmt_extra(c, scope, expr, result_used, lrval, &result_node, nullptr, nullptr)) {
3118 TransScope *result_scope;
3119 if (trans_stmt_extra(c, scope, expr, result_used, lrval, &result_node, &result_scope, nullptr)) {
29853120 return nullptr;
29863121 }
29873122 return result_node;
......@@ -3536,6 +3671,14 @@ static TransScopeRoot *trans_scope_root_create(Context *c) {
35363671 return result;
35373672}
35383673
3674static TransScopeWhile *trans_scope_while_create(Context *c, TransScope *parent_scope) {
3675 TransScopeWhile *result = allocate<TransScopeWhile>(1);
3676 result->base.id = TransScopeIdWhile;
3677 result->base.parent = parent_scope;
3678 result->node = trans_create_node(c, NodeTypeWhileExpr);
3679 return result;
3680}
3681
35393682static TransScopeBlock *trans_scope_block_create(Context *c, TransScope *parent_scope) {
35403683 TransScopeBlock *result = allocate<TransScopeBlock>(1);
35413684 result->base.id = TransScopeIdBlock;
......@@ -3553,13 +3696,13 @@ static TransScopeVar *trans_scope_var_create(Context *c, TransScope *parent_scop
35533696 return result;
35543697}
35553698
3556//static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope) {
3557// TransScopeSwitch *result = allocate<TransScopeSwitch>(1);
3558// result->base.id = TransScopeIdSwitch;
3559// result->base.parent = parent_scope;
3560// result->switch_node = trans_create_node(c, NodeTypeSwitchExpr);
3561// return result;
3562//}
3699static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *parent_scope) {
3700 TransScopeSwitch *result = allocate<TransScopeSwitch>(1);
3701 result->base.id = TransScopeIdSwitch;
3702 result->base.parent = parent_scope;
3703 result->switch_node = trans_create_node(c, NodeTypeSwitchExpr);
3704 return result;
3705}
35633706
35643707static TransScopeBlock *trans_scope_block_find(TransScope *scope) {
35653708 while (scope != nullptr) {
......@@ -3571,6 +3714,16 @@ static TransScopeBlock *trans_scope_block_find(TransScope *scope) {
35713714 return nullptr;
35723715}
35733716
3717static TransScopeSwitch *trans_scope_switch_find(TransScope *scope) {
3718 while (scope != nullptr) {
3719 if (scope->id == TransScopeIdSwitch) {
3720 return (TransScopeSwitch *)scope;
3721 }
3722 scope = scope->parent;
3723 }
3724 return nullptr;
3725}
3726
35743727static void render_aliases(Context *c) {
35753728 for (size_t i = 0; i < c->aliases.length; i += 1) {
35763729 Alias *alias = &c->aliases.at(i);
test/translate_c.zig+40-40
......@@ -1001,46 +1001,46 @@ pub fn addCases(cases: &tests.TranslateCContext) {
10011001 \\}
10021002 );
10031003
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 //);
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(_arg_x: c_int) -> c_int {
1021 \\ var x = _arg_x;
1022 \\ while (true) {
1023 \\ switch (x) {
1024 \\ 1 => goto case_0,
1025 \\ 2 => goto case_1,
1026 \\ 3 => goto case_2,
1027 \\ 4 => goto case_3,
1028 \\ else => goto default,
1029 \\ };
1030 \\ case_0:
1031 \\ x += 1;
1032 \\ case_1:
1033 \\ break;
1034 \\ case_2:
1035 \\ case_3:
1036 \\ return x + 1;
1037 \\ default:
1038 \\ return 10;
1039 \\ break;
1040 \\ };
1041 \\ return x + 13;
1042 \\}
1043 );
10441044}
10451045
10461046