17using namespace CodeGen;
25 Scopes = {{~0
U,
nullptr}};
26 unsigned ParentScope = 0;
27 AlwaysBypassed = !BuildScopeInformation(CGM, Body, ParentScope);
36 unsigned &ParentScope) {
37 const VarDecl *VD = dyn_cast<VarDecl>(
D);
39 Scopes.push_back({ParentScope, VD});
40 ParentScope = Scopes.size() - 1;
43 if (
const VarDecl *VD = dyn_cast<VarDecl>(
D))
45 return BuildScopeInformation(CGM,
Init, ParentScope);
55 unsigned &origParentScope) {
59 unsigned independentParentScope = origParentScope;
60 unsigned &ParentScope =
61 ((isa<Expr>(S) && !isa<StmtExpr>(S)) ? origParentScope
62 : independentParentScope);
64 unsigned StmtsToSkip = 0u;
66 switch (S->getStmtClass()) {
67 case Stmt::IndirectGotoStmtClass:
70 case Stmt::SwitchStmtClass:
71 if (
const Stmt *
Init = cast<SwitchStmt>(S)->getInit()) {
72 if (!BuildScopeInformation(CGM,
Init, ParentScope))
76 if (
const VarDecl *Var = cast<SwitchStmt>(S)->getConditionVariable()) {
77 if (!BuildScopeInformation(CGM, Var, ParentScope))
83 case Stmt::GotoStmtClass:
84 FromScopes.push_back({S, ParentScope});
87 case Stmt::DeclStmtClass: {
88 const DeclStmt *DS = cast<DeclStmt>(S);
89 for (
auto *I : DS->
decls())
90 if (!BuildScopeInformation(CGM, I, origParentScope))
95 case Stmt::CaseStmtClass:
96 case Stmt::DefaultStmtClass:
97 case Stmt::LabelStmtClass:
98 llvm_unreachable(
"the loop below handles labels and cases");
105 for (
const Stmt *SubStmt : S->children()) {
118 if (
const SwitchCase *SC = dyn_cast<SwitchCase>(SubStmt))
119 Next = SC->getSubStmt();
120 else if (
const LabelStmt *LS = dyn_cast<LabelStmt>(SubStmt))
121 Next = LS->getSubStmt();
125 ToScopes[SubStmt] = ParentScope;
132 Result = BuildScopeInformation(CGM, SubStmt, ParentScope);
141void VarBypassDetector::Detect() {
142 for (
const auto &S : FromScopes) {
143 const Stmt *St = S.first;
144 unsigned from = S.second;
145 if (
const GotoStmt *GS = dyn_cast<GotoStmt>(St)) {
146 if (
const LabelStmt *LS = GS->getLabel()->getStmt())
147 Detect(from, ToScopes[LS]);
148 }
else if (
const SwitchStmt *SS = dyn_cast<SwitchStmt>(St)) {
149 for (
const SwitchCase *SC = SS->getSwitchCaseList(); SC;
151 Detect(from, ToScopes[SC]);
154 llvm_unreachable(
"goto or switch was expected");
160void VarBypassDetector::Detect(
unsigned From,
unsigned To) {
163 assert(Scopes[To].first < To);
164 const auto &ScopeTo = Scopes[To];
166 Bypasses.insert(ScopeTo.second);
168 assert(Scopes[From].first < From);
169 From = Scopes[From].first;
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.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Decl - This represents one declaration (or definition), e.g.
This represents one expression.
GotoStmt - This represents a direct goto.
LabelStmt - Represents a label, which has a substatement.
Stmt - This represents one statement.
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
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.
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.