@@ -579,6 +579,65 @@ static LogicalResult printOperation(CppEmitter &emitter,
579579 return success ();
580580}
581581
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+ for (const auto caseBlock : switchOp.getCaseDestinations ()) {
592+ if (iteratorCaseValues == iteratorCaseValuesEnd)
593+ return switchOp.emitOpError (" case's value is absent for case block" );
594+
595+ os << " \n case "
596+ << " (" << *(iteratorCaseValues++) << " )"
597+ << " : {\n " ;
598+ os.indent ();
599+
600+ for (auto pair : llvm::zip (switchOp.getCaseOperands (caseIndex++),
601+ caseBlock->getArguments ())) {
602+ Value &operand = std::get<0 >(pair);
603+ BlockArgument &argument = std::get<1 >(pair);
604+ os << emitter.getOrCreateName (argument) << " = "
605+ << emitter.getOrCreateName (operand) << " ;\n " ;
606+ }
607+
608+ os << " goto " ;
609+
610+ if (!(emitter.hasBlockLabel (*caseBlock)))
611+ return switchOp.emitOpError (" unable to find label for case block" );
612+ os << emitter.getOrCreateName (*caseBlock) << " ;\n " ;
613+
614+ os.unindent () << " }" ;
615+ }
616+
617+ os << " \n default: {\n " ;
618+ os.indent ();
619+
620+ for (auto pair :
621+ llvm::zip (switchOp.getDefaultOperands (),
622+ (switchOp.getDefaultDestination ())->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+
582641static LogicalResult printCallOperation (CppEmitter &emitter, Operation *callOp,
583642 StringRef callee) {
584643 if (failed (emitter.emitAssignPrefix (*callOp)))
@@ -997,8 +1056,8 @@ static LogicalResult printFunctionBody(CppEmitter &emitter,
9971056 // When generating code for an emitc.for and emitc.verbatim op, printing a
9981057 // trailing semicolon is handled within the printOperation function.
9991058 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);
10021061
10031062 if (failed (emitter.emitOperation (
10041063 op, /* trailingSemicolon=*/ trailingSemicolon)))
@@ -1496,7 +1555,7 @@ LogicalResult CppEmitter::emitOperation(Operation &op, bool trailingSemicolon) {
14961555 // Builtin ops.
14971556 .Case <ModuleOp>([&](auto op) { return printOperation (*this , op); })
14981557 // CF ops.
1499- .Case <cf::BranchOp, cf::CondBranchOp>(
1558+ .Case <cf::BranchOp, cf::CondBranchOp, cf::SwitchOp >(
15001559 [&](auto op) { return printOperation (*this , op); })
15011560 // EmitC ops.
15021561 .Case <emitc::AddOp, emitc::ApplyOp, emitc::AssignOp,
0 commit comments