8
8
9
9
#include " VarBypassDetector.h"
10
10
11
+ #include " CodeGenModule.h"
11
12
#include " clang/AST/Decl.h"
12
13
#include " clang/AST/Expr.h"
13
14
#include " clang/AST/Stmt.h"
@@ -17,21 +18,21 @@ using namespace CodeGen;
17
18
18
19
// / Clear the object and pre-process for the given statement, usually function
19
20
// / body statement.
20
- void VarBypassDetector::Init (const Stmt *Body) {
21
+ void VarBypassDetector::Init (CodeGenModule &CGM, const Stmt *Body) {
21
22
FromScopes.clear ();
22
23
ToScopes.clear ();
23
24
Bypasses.clear ();
24
25
Scopes = {{~0U , nullptr }};
25
26
unsigned ParentScope = 0 ;
26
- AlwaysBypassed = !BuildScopeInformation (Body, ParentScope);
27
+ AlwaysBypassed = !BuildScopeInformation (CGM, Body, ParentScope);
27
28
if (!AlwaysBypassed)
28
29
Detect ();
29
30
}
30
31
31
32
// / Build scope information for a declaration that is part of a DeclStmt.
32
33
// / Returns false if we failed to build scope information and can't tell for
33
34
// / which vars are being bypassed.
34
- bool VarBypassDetector::BuildScopeInformation (const Decl *D,
35
+ bool VarBypassDetector::BuildScopeInformation (CodeGenModule &CGM, const Decl *D,
35
36
unsigned &ParentScope) {
36
37
const VarDecl *VD = dyn_cast<VarDecl>(D);
37
38
if (VD && VD->hasLocalStorage ()) {
@@ -41,7 +42,7 @@ bool VarBypassDetector::BuildScopeInformation(const Decl *D,
41
42
42
43
if (const VarDecl *VD = dyn_cast<VarDecl>(D))
43
44
if (const Expr *Init = VD->getInit ())
44
- return BuildScopeInformation (Init, ParentScope);
45
+ return BuildScopeInformation (CGM, Init, ParentScope);
45
46
46
47
return true ;
47
48
}
@@ -50,7 +51,7 @@ bool VarBypassDetector::BuildScopeInformation(const Decl *D,
50
51
// / LabelAndGotoScopes and recursively walking the AST as needed.
51
52
// / Returns false if we failed to build scope information and can't tell for
52
53
// / which vars are being bypassed.
53
- bool VarBypassDetector::BuildScopeInformation (const Stmt *S,
54
+ bool VarBypassDetector::BuildScopeInformation (CodeGenModule &CGM, const Stmt *S,
54
55
unsigned &origParentScope) {
55
56
// If this is a statement, rather than an expression, scopes within it don't
56
57
// propagate out into the enclosing scope. Otherwise we have to worry about
@@ -68,12 +69,12 @@ bool VarBypassDetector::BuildScopeInformation(const Stmt *S,
68
69
69
70
case Stmt::SwitchStmtClass:
70
71
if (const Stmt *Init = cast<SwitchStmt>(S)->getInit ()) {
71
- if (!BuildScopeInformation (Init, ParentScope))
72
+ if (!BuildScopeInformation (CGM, Init, ParentScope))
72
73
return false ;
73
74
++StmtsToSkip;
74
75
}
75
76
if (const VarDecl *Var = cast<SwitchStmt>(S)->getConditionVariable ()) {
76
- if (!BuildScopeInformation (Var, ParentScope))
77
+ if (!BuildScopeInformation (CGM, Var, ParentScope))
77
78
return false ;
78
79
++StmtsToSkip;
79
80
}
@@ -86,7 +87,7 @@ bool VarBypassDetector::BuildScopeInformation(const Stmt *S,
86
87
case Stmt::DeclStmtClass: {
87
88
const DeclStmt *DS = cast<DeclStmt>(S);
88
89
for (auto *I : DS->decls ())
89
- if (!BuildScopeInformation (I, origParentScope))
90
+ if (!BuildScopeInformation (CGM, I, origParentScope))
90
91
return false ;
91
92
return true ;
92
93
}
@@ -126,7 +127,11 @@ bool VarBypassDetector::BuildScopeInformation(const Stmt *S,
126
127
}
127
128
128
129
// Recursively walk the AST.
129
- if (!BuildScopeInformation (SubStmt, ParentScope))
130
+ bool Result;
131
+ CGM.runWithSufficientStackSpace (S->getEndLoc (), [&] {
132
+ Result = BuildScopeInformation (CGM, SubStmt, ParentScope);
133
+ });
134
+ if (!Result)
130
135
return false ;
131
136
}
132
137
return true ;
0 commit comments