24 Worklist.push_back(Body);
25 while (!Worklist.empty()) {
26 const Stmt *S = Worklist.pop_back_val();
30 case Stmt::GotoStmtClass:
31 case Stmt::SwitchStmtClass:
32 case Stmt::IndirectGotoStmtClass:
38 Worklist.push_back(Child);
49 BypassedVarsAtSource.clear();
50 Scopes = {{~0
U,
nullptr}};
51 AlwaysBypassed =
false;
54 unsigned ParentScope = 0;
55 AlwaysBypassed = !BuildScopeInformation(CGM, Body, ParentScope);
64 unsigned &ParentScope) {
65 const VarDecl *VD = dyn_cast<VarDecl>(D);
67 Scopes.push_back({ParentScope, VD});
68 ParentScope = Scopes.size() - 1;
71 if (
const VarDecl *VD = dyn_cast<VarDecl>(D))
73 return BuildScopeInformation(CGM,
Init, ParentScope);
82bool VarBypassDetector::BuildScopeInformation(
CodeGenModule &CGM,
const Stmt *S,
83 unsigned &origParentScope) {
87 unsigned independentParentScope = origParentScope;
88 unsigned &ParentScope =
90 : independentParentScope);
92 unsigned StmtsToSkip = 0u;
95 case Stmt::IndirectGotoStmtClass:
98 case Stmt::SwitchStmtClass:
100 if (!BuildScopeInformation(CGM,
Init, ParentScope))
105 if (!BuildScopeInformation(CGM, Var, ParentScope))
111 case Stmt::GotoStmtClass:
112 FromScopes.push_back({S, ParentScope});
115 case Stmt::DeclStmtClass: {
117 for (
auto *I : DS->
decls())
118 if (!BuildScopeInformation(CGM, I, origParentScope))
123 case Stmt::CaseStmtClass:
124 case Stmt::DefaultStmtClass:
125 case Stmt::LabelStmtClass:
126 llvm_unreachable(
"the loop below handles labels and cases");
133 for (
const Stmt *SubStmt : S->
children()) {
146 if (
const SwitchCase *SC = dyn_cast<SwitchCase>(SubStmt))
147 Next = SC->getSubStmt();
148 else if (
const LabelStmt *LS = dyn_cast<LabelStmt>(SubStmt))
149 Next = LS->getSubStmt();
153 ToScopes[SubStmt] = ParentScope;
160 Result = BuildScopeInformation(CGM, SubStmt, ParentScope);
169void VarBypassDetector::Detect() {
170 for (
const auto &S : FromScopes) {
171 const Stmt *St = S.first;
172 unsigned from = S.second;
173 if (
const GotoStmt *GS = dyn_cast<GotoStmt>(St)) {
174 if (
const LabelStmt *LS = GS->getLabel()->getStmt())
175 Detect(from, ToScopes[LS], GS);
176 }
else if (
const SwitchStmt *SS = dyn_cast<SwitchStmt>(St)) {
179 for (
const SwitchCase *SC = SS->getSwitchCaseList(); SC;
180 SC = SC->getNextSwitchCase()) {
181 Detect(from, ToScopes[SC], SS);
184 llvm_unreachable(
"goto or switch was expected");
190void VarBypassDetector::Detect(
unsigned From,
unsigned To,
const Stmt *Source) {
193 assert(Scopes[To].first < To);
194 const auto &ScopeTo = Scopes[To];
196 Bypasses.insert(ScopeTo.second);
198 BypassedVarsAtSource[Source].insert(ScopeTo.second);
200 assert(Scopes[From].first < From);
201 From = Scopes[From].first;
static bool hasJumpStmts(const Stmt *Body)
True if the body contains a goto, switch, or indirect goto.
This class organizes the cross-function state that is used while generating LLVM code.
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
void Init(CodeGenModule &CGM, const Stmt *Body)
Clear the object and pre-process for the given statement, usually function body statement.
This represents one expression.
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
StmtClass getStmtClass() const
Represents a variable declaration or definition.
const Expr * getInit() const
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
@ Result
The result type of a method or function.
U cast(CodeGen::Address addr)