2323// cxx
2424#include < cxx/ast.h>
2525#include < cxx/control.h>
26+ #include < cxx/memory_layout.h>
2627#include < cxx/names.h>
2728
2829// mlir
@@ -69,7 +70,8 @@ struct Codegen::ExceptionDeclarationVisitor {
6970void Codegen::statement (StatementAST* ast) {
7071 if (!ast) return ;
7172
72- if (currentBlockMightHaveTerminator ()) return ;
73+ // TODO: move to the op visitors
74+ // if (currentBlockMightHaveTerminator()) return;
7375
7476 visit (StatementVisitor{*this }, ast);
7577}
@@ -104,15 +106,21 @@ void Codegen::StatementVisitor::operator()(LabeledStatementAST* ast) {
104106}
105107
106108void Codegen::StatementVisitor::operator ()(CaseStatementAST* ast) {
107- ( void ) gen.emitTodoStmt (ast-> firstSourceLocation (), to_string (ast-> kind ()) );
109+ auto block = gen.newBlock ( );
108110
109- #if false
110- auto expressionResult = gen.expression (ast->expression );
111- #endif
111+ gen.branch (gen.getLocation (ast->firstSourceLocation ()), block);
112+ gen.builder_ .setInsertionPointToEnd (block);
113+
114+ gen.switch_ .caseValues .push_back (ast->caseValue );
115+ gen.switch_ .caseDestinations .push_back (block);
112116}
113117
114118void Codegen::StatementVisitor::operator ()(DefaultStatementAST* ast) {
115- (void )gen.emitTodoStmt (ast->firstSourceLocation (), to_string (ast->kind ()));
119+ auto block = gen.newBlock ();
120+ gen.branch (gen.getLocation (ast->firstSourceLocation ()), block);
121+ gen.builder_ .setInsertionPointToEnd (block);
122+
123+ gen.switch_ .defaultDestination = block;
116124}
117125
118126void Codegen::StatementVisitor::operator ()(ExpressionStatementAST* ast) {
@@ -155,13 +163,41 @@ void Codegen::StatementVisitor::operator()(ConstevalIfStatementAST* ast) {
155163}
156164
157165void Codegen::StatementVisitor::operator ()(SwitchStatementAST* ast) {
158- (void )gen.emitTodoStmt (ast->firstSourceLocation (), to_string (ast->kind ()));
159-
160- #if false
161166 gen.statement (ast->initializer );
162- auto conditionResult = gen.expression (ast->condition );
167+
168+ Switch previousSwitch;
169+ std::swap (gen.switch_ , previousSwitch);
170+
171+ auto beginSwitchBlock = gen.newBlock ();
172+ auto bodySwitchBlock = gen.newBlock ();
173+ auto endSwitchBlock = gen.newBlock ();
174+
175+ gen.branch (gen.getLocation (ast->firstSourceLocation ()), beginSwitchBlock);
176+
177+ gen.builder_ .setInsertionPointToEnd (bodySwitchBlock);
178+
179+ Loop previousLoop{gen.loop_ .continueBlock , endSwitchBlock};
180+ std::swap (gen.loop_ , previousLoop);
181+
163182 gen.statement (ast->statement );
164- #endif
183+ gen.branch (gen.getLocation (ast->lastSourceLocation ()), endSwitchBlock);
184+
185+ gen.builder_ .setInsertionPointToEnd (beginSwitchBlock);
186+
187+ auto conditionResult = gen.expression (ast->condition );
188+
189+ mlir::cxx::SwitchOp::create (
190+ gen.builder_ , gen.getLocation (ast->firstSourceLocation ()),
191+ conditionResult.value , gen.switch_ .defaultDestination , {},
192+ gen.switch_ .caseValues , gen.switch_ .caseDestinations ,
193+ mlir::SmallVector<mlir::ValueRange>(gen.switch_ .caseValues .size ()));
194+
195+ std::swap (gen.switch_ , previousSwitch);
196+ std::swap (gen.loop_ , previousLoop);
197+
198+ gen.builder_ .setInsertionPointToEnd (endSwitchBlock);
199+
200+ bodySwitchBlock->erase ();
165201}
166202
167203void Codegen::StatementVisitor::operator ()(WhileStatementAST* ast) {
@@ -358,4 +394,4 @@ auto Codegen::ExceptionDeclarationVisitor::operator()(
358394 return {};
359395}
360396
361- } // namespace cxx
397+ } // namespace cxx
0 commit comments