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);
54bool VarBypassDetector::BuildScopeInformation(
CodeGenModule &CGM,
const Stmt *S,
55 unsigned &origParentScope) {
59 unsigned independentParentScope = origParentScope;
60 unsigned &ParentScope =
62 : independentParentScope);
64 unsigned StmtsToSkip = 0u;
67 case Stmt::IndirectGotoStmtClass:
70 case Stmt::SwitchStmtClass:
72 if (!BuildScopeInformation(CGM,
Init, ParentScope))
77 if (!BuildScopeInformation(CGM, Var, ParentScope))
83 case Stmt::GotoStmtClass:
84 FromScopes.push_back({S, ParentScope});
87 case Stmt::DeclStmtClass: {
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;
150 SC = SC->getNextSwitchCase()) {
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.
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 ...
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Result
The result type of a method or function.
U cast(CodeGen::Address addr)