Skip to content

Commit 6558323

Browse files
committed
Add BreakTarget
1 parent 228f855 commit 6558323

2 files changed

Lines changed: 40 additions & 10 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,7 @@ bool Converter::VisitIfStmt(clang::IfStmt *stmt) {
990990
}
991991

992992
bool Converter::VisitWhileStmt(clang::WhileStmt *stmt) {
993+
PushBreakTarget push(break_target_stack_, BreakTarget::Loop);
993994
StrCat("'loop_:");
994995
StrCat(keyword::kWhile);
995996
ConvertCondition(stmt->getCond());
@@ -1002,6 +1003,7 @@ bool Converter::VisitWhileStmt(clang::WhileStmt *stmt) {
10021003
}
10031004

10041005
bool Converter::VisitDoStmt(clang::DoStmt *stmt) {
1006+
PushBreakTarget push(break_target_stack_, BreakTarget::Loop);
10051007
StrCat("'loop_:");
10061008
StrCat(keyword::kLoop, token::kOpenCurlyBracket);
10071009
curr_for_inc_.emplace(nullptr);
@@ -1016,6 +1018,7 @@ bool Converter::VisitDoStmt(clang::DoStmt *stmt) {
10161018
}
10171019

10181020
bool Converter::VisitForStmt(clang::ForStmt *stmt) {
1021+
PushBreakTarget push(break_target_stack_, BreakTarget::Loop);
10191022
Convert(stmt->getInit());
10201023
StrCat("'loop_:");
10211024
StrCat(keyword::kWhile);
@@ -1055,6 +1058,7 @@ void Converter::ConvertLoopVariable(clang::VarDecl *decl,
10551058

10561059
void Converter::ConvertForRangeBody(clang::CXXForRangeStmt *stmt,
10571060
const clang::VarDecl *map_iter_decl) {
1061+
PushBreakTarget push(break_target_stack_, BreakTarget::Loop);
10581062
std::optional<ScopedMapIterDecl> skip;
10591063
if (map_iter_decl)
10601064
skip.emplace(*this, map_iter_decl);
@@ -1136,10 +1140,12 @@ bool Converter::VisitCXXForRangeStmtIndexBased(clang::CXXForRangeStmt *stmt,
11361140
}
11371141

11381142
bool Converter::VisitBreakStmt([[maybe_unused]] clang::BreakStmt *stmt) {
1139-
StrCat(keyword::kBreak);
1140-
if (switch_depth_ > 0) {
1143+
if (break_target_stack_.isRegularSwitch()) {
1144+
StrCat(keyword::kBreak);
11411145
StrCat("'switch");
1146+
return false;
11421147
}
1148+
StrCat(keyword::kBreak);
11431149
return false;
11441150
}
11451151

@@ -2657,9 +2663,9 @@ bool Converter::VisitSwitchStmt(clang::SwitchStmt *stmt) {
26572663
StrCat("{");
26582664
}
26592665

2660-
if (!has_fallthrough) {
2661-
++switch_depth_;
2662-
}
2666+
PushBreakTarget push(break_target_stack_, has_fallthrough
2667+
? BreakTarget::FallthroughSwitch
2668+
: BreakTarget::RegularSwitch);
26632669

26642670
clang::SwitchCase *default_case = nullptr;
26652671
for (auto *sc : GetTopLevelSwitchCases(stmt)) {
@@ -2685,10 +2691,6 @@ bool Converter::VisitSwitchStmt(clang::SwitchStmt *stmt) {
26852691
StrCat(R"( _ => {})");
26862692
}
26872693

2688-
if (!has_fallthrough) {
2689-
--switch_depth_;
2690-
}
2691-
26922694
if (has_fallthrough) {
26932695
StrCat("})");
26942696
} else {

cpp2rust/converter/converter.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,35 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
463463
clang::ASTContext &ctx_;
464464
clang::FunctionDecl *curr_function_ = nullptr;
465465
bool in_function_formals_ = false;
466-
int switch_depth_ = 0;
466+
467+
enum class BreakTarget { Loop, RegularSwitch, FallthroughSwitch };
468+
class BreakTargetStack {
469+
public:
470+
void push(BreakTarget t) { stack_.push(t); }
471+
void pop() { stack_.pop(); }
472+
bool isRegularSwitch() const {
473+
return !stack_.empty() && stack_.top() == BreakTarget::RegularSwitch;
474+
}
475+
476+
private:
477+
std::stack<BreakTarget> stack_;
478+
};
479+
BreakTargetStack break_target_stack_;
480+
481+
class PushBreakTarget {
482+
public:
483+
PushBreakTarget(BreakTargetStack &stack, BreakTarget target)
484+
: stack_(stack) {
485+
stack_.push(target);
486+
}
487+
~PushBreakTarget() { stack_.pop(); }
488+
PushBreakTarget(const PushBreakTarget &) = delete;
489+
PushBreakTarget &operator=(const PushBreakTarget &) = delete;
490+
491+
private:
492+
BreakTargetStack &stack_;
493+
};
494+
467495
std::stack<clang::Expr *> curr_for_inc_;
468496
std::stack<clang::QualType> curr_init_type_;
469497

0 commit comments

Comments
 (0)