@@ -579,6 +579,65 @@ static LogicalResult printOperation(CppEmitter &emitter,
579
579
return success ();
580
580
}
581
581
582
+ static LogicalResult printOperation (CppEmitter &emitter,
583
+ cf::SwitchOp switchOp) {
584
+ raw_indented_ostream &os = emitter.ostream ();
585
+ auto iteratorCaseValues = (*switchOp.getCaseValues ()).begin ();
586
+ auto iteratorCaseValuesEnd = (*switchOp.getCaseValues ()).end ();
587
+ size_t caseIndex = 0 ;
588
+
589
+ os << " \n switch(" << emitter.getOrCreateName (switchOp.getFlag ()) << " ) {" ;
590
+
591
+
592
+ for (const auto caseBlock : switchOp.getCaseDestinations ()) {
593
+ if (iteratorCaseValues == iteratorCaseValuesEnd)
594
+ return switchOp.emitOpError (" case's value is absent for case block" );
595
+
596
+ os << " \n case " << *(iteratorCaseValues++) << " : {\n " ;
597
+ os.indent ();
598
+
599
+ for (auto pair :
600
+ llvm::zip (switchOp.getCaseOperands (caseIndex++), caseBlock->getArguments ())) {
601
+ Value &operand = std::get<0 >(pair);
602
+ BlockArgument &argument = std::get<1 >(pair);
603
+ os << emitter.getOrCreateName (argument) << " = "
604
+ << emitter.getOrCreateName (operand) << " ;\n " ;
605
+ }
606
+
607
+ os << " goto " ;
608
+
609
+ if (!(emitter.hasBlockLabel (*caseBlock)))
610
+ return switchOp.emitOpError (" unable to find label for case block" );
611
+ os << emitter.getOrCreateName (*caseBlock) << " ;\n " ;
612
+
613
+ os.unindent () << " }" ;
614
+ }
615
+
616
+ os << " \n default: {\n " ;
617
+ os.indent ();
618
+
619
+ auto defaultBlock = switchOp.getDefaultDestination ();
620
+
621
+ for (auto pair : llvm::zip (switchOp.getDefaultOperands (),
622
+ defaultBlock->getArguments ())) {
623
+ Value &operand = std::get<0 >(pair);
624
+ BlockArgument &argument = std::get<1 >(pair);
625
+ os << emitter.getOrCreateName (argument) << " = "
626
+ << emitter.getOrCreateName (operand) << " ;\n " ;
627
+ }
628
+
629
+ os << " goto " ;
630
+
631
+ if (!(emitter.hasBlockLabel (*switchOp.getDefaultDestination ())))
632
+ return switchOp.emitOpError (" unable to find label for default block" );
633
+ os << emitter.getOrCreateName (*switchOp.getDefaultDestination ()) << " ;\n " ;
634
+
635
+ os.unindent () << " }\n " ;
636
+ os << " }\n " ;
637
+
638
+ return success ();
639
+ }
640
+
582
641
static LogicalResult printCallOperation (CppEmitter &emitter, Operation *callOp,
583
642
StringRef callee) {
584
643
if (failed (emitter.emitAssignPrefix (*callOp)))
@@ -997,8 +1056,8 @@ static LogicalResult printFunctionBody(CppEmitter &emitter,
997
1056
// When generating code for an emitc.for and emitc.verbatim op, printing a
998
1057
// trailing semicolon is handled within the printOperation function.
999
1058
bool trailingSemicolon =
1000
- !isa<cf::CondBranchOp, emitc::DeclareFuncOp , emitc::ForOp ,
1001
- emitc::IfOp, emitc::VerbatimOp>(op);
1059
+ !isa<cf::CondBranchOp, cf::SwitchOp , emitc::DeclareFuncOp ,
1060
+ emitc::ForOp, emitc:: IfOp, emitc::VerbatimOp>(op);
1002
1061
1003
1062
if (failed (emitter.emitOperation (
1004
1063
op, /* trailingSemicolon=*/ trailingSemicolon)))
@@ -1496,7 +1555,7 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
1496
1555
// Builtin ops.
1497
1556
.Case <ModuleOp>([&](auto op) { return printOperation (*this , op); })
1498
1557
// CF ops.
1499
- .Case <cf::BranchOp, cf::CondBranchOp>(
1558
+ .Case <cf::BranchOp, cf::CondBranchOp, cf::SwitchOp >(
1500
1559
[&](auto op) { return printOperation (*this , op); })
1501
1560
// EmitC ops.
1502
1561
.Case <emitc::AddOp, emitc::ApplyOp, emitc::AssignOp,
0 commit comments