1*67e74705SXin Li //===--- ScopeInfo.cpp - Information about a semantic context -------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file implements FunctionScopeInfo and its subclasses, which contain
11*67e74705SXin Li // information about a single function, block, lambda, or method body.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li
15*67e74705SXin Li #include "clang/Sema/ScopeInfo.h"
16*67e74705SXin Li #include "clang/AST/Decl.h"
17*67e74705SXin Li #include "clang/AST/DeclCXX.h"
18*67e74705SXin Li #include "clang/AST/DeclObjC.h"
19*67e74705SXin Li #include "clang/AST/Expr.h"
20*67e74705SXin Li #include "clang/AST/ExprCXX.h"
21*67e74705SXin Li #include "clang/AST/ExprObjC.h"
22*67e74705SXin Li
23*67e74705SXin Li using namespace clang;
24*67e74705SXin Li using namespace sema;
25*67e74705SXin Li
Clear()26*67e74705SXin Li void FunctionScopeInfo::Clear() {
27*67e74705SXin Li HasBranchProtectedScope = false;
28*67e74705SXin Li HasBranchIntoScope = false;
29*67e74705SXin Li HasIndirectGoto = false;
30*67e74705SXin Li HasDroppedStmt = false;
31*67e74705SXin Li HasOMPDeclareReductionCombiner = false;
32*67e74705SXin Li ObjCShouldCallSuper = false;
33*67e74705SXin Li ObjCIsDesignatedInit = false;
34*67e74705SXin Li ObjCWarnForNoDesignatedInitChain = false;
35*67e74705SXin Li ObjCIsSecondaryInit = false;
36*67e74705SXin Li ObjCWarnForNoInitDelegation = false;
37*67e74705SXin Li FirstReturnLoc = SourceLocation();
38*67e74705SXin Li FirstCXXTryLoc = SourceLocation();
39*67e74705SXin Li FirstSEHTryLoc = SourceLocation();
40*67e74705SXin Li
41*67e74705SXin Li SwitchStack.clear();
42*67e74705SXin Li Returns.clear();
43*67e74705SXin Li CoroutinePromise = nullptr;
44*67e74705SXin Li CoroutineStmts.clear();
45*67e74705SXin Li ErrorTrap.reset();
46*67e74705SXin Li PossiblyUnreachableDiags.clear();
47*67e74705SXin Li WeakObjectUses.clear();
48*67e74705SXin Li ModifiedNonNullParams.clear();
49*67e74705SXin Li }
50*67e74705SXin Li
getBestPropertyDecl(const ObjCPropertyRefExpr * PropE)51*67e74705SXin Li static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
52*67e74705SXin Li if (PropE->isExplicitProperty())
53*67e74705SXin Li return PropE->getExplicitProperty();
54*67e74705SXin Li
55*67e74705SXin Li return PropE->getImplicitPropertyGetter();
56*67e74705SXin Li }
57*67e74705SXin Li
58*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy
getBaseInfo(const Expr * E)59*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {
60*67e74705SXin Li E = E->IgnoreParenCasts();
61*67e74705SXin Li
62*67e74705SXin Li const NamedDecl *D = nullptr;
63*67e74705SXin Li bool IsExact = false;
64*67e74705SXin Li
65*67e74705SXin Li switch (E->getStmtClass()) {
66*67e74705SXin Li case Stmt::DeclRefExprClass:
67*67e74705SXin Li D = cast<DeclRefExpr>(E)->getDecl();
68*67e74705SXin Li IsExact = isa<VarDecl>(D);
69*67e74705SXin Li break;
70*67e74705SXin Li case Stmt::MemberExprClass: {
71*67e74705SXin Li const MemberExpr *ME = cast<MemberExpr>(E);
72*67e74705SXin Li D = ME->getMemberDecl();
73*67e74705SXin Li IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts());
74*67e74705SXin Li break;
75*67e74705SXin Li }
76*67e74705SXin Li case Stmt::ObjCIvarRefExprClass: {
77*67e74705SXin Li const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E);
78*67e74705SXin Li D = IE->getDecl();
79*67e74705SXin Li IsExact = IE->getBase()->isObjCSelfExpr();
80*67e74705SXin Li break;
81*67e74705SXin Li }
82*67e74705SXin Li case Stmt::PseudoObjectExprClass: {
83*67e74705SXin Li const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E);
84*67e74705SXin Li const ObjCPropertyRefExpr *BaseProp =
85*67e74705SXin Li dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
86*67e74705SXin Li if (BaseProp) {
87*67e74705SXin Li D = getBestPropertyDecl(BaseProp);
88*67e74705SXin Li
89*67e74705SXin Li if (BaseProp->isObjectReceiver()) {
90*67e74705SXin Li const Expr *DoubleBase = BaseProp->getBase();
91*67e74705SXin Li if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase))
92*67e74705SXin Li DoubleBase = OVE->getSourceExpr();
93*67e74705SXin Li
94*67e74705SXin Li IsExact = DoubleBase->isObjCSelfExpr();
95*67e74705SXin Li }
96*67e74705SXin Li }
97*67e74705SXin Li break;
98*67e74705SXin Li }
99*67e74705SXin Li default:
100*67e74705SXin Li break;
101*67e74705SXin Li }
102*67e74705SXin Li
103*67e74705SXin Li return BaseInfoTy(D, IsExact);
104*67e74705SXin Li }
105*67e74705SXin Li
isVLATypeCaptured(const VariableArrayType * VAT) const106*67e74705SXin Li bool CapturingScopeInfo::isVLATypeCaptured(const VariableArrayType *VAT) const {
107*67e74705SXin Li RecordDecl *RD = nullptr;
108*67e74705SXin Li if (auto *LSI = dyn_cast<LambdaScopeInfo>(this))
109*67e74705SXin Li RD = LSI->Lambda;
110*67e74705SXin Li else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(this))
111*67e74705SXin Li RD = CRSI->TheRecordDecl;
112*67e74705SXin Li
113*67e74705SXin Li if (RD)
114*67e74705SXin Li for (auto *FD : RD->fields()) {
115*67e74705SXin Li if (FD->hasCapturedVLAType() && FD->getCapturedVLAType() == VAT)
116*67e74705SXin Li return true;
117*67e74705SXin Li }
118*67e74705SXin Li return false;
119*67e74705SXin Li }
120*67e74705SXin Li
WeakObjectProfileTy(const ObjCPropertyRefExpr * PropE)121*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
122*67e74705SXin Li const ObjCPropertyRefExpr *PropE)
123*67e74705SXin Li : Base(nullptr, true), Property(getBestPropertyDecl(PropE)) {
124*67e74705SXin Li
125*67e74705SXin Li if (PropE->isObjectReceiver()) {
126*67e74705SXin Li const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase());
127*67e74705SXin Li const Expr *E = OVE->getSourceExpr();
128*67e74705SXin Li Base = getBaseInfo(E);
129*67e74705SXin Li } else if (PropE->isClassReceiver()) {
130*67e74705SXin Li Base.setPointer(PropE->getClassReceiver());
131*67e74705SXin Li } else {
132*67e74705SXin Li assert(PropE->isSuperReceiver());
133*67e74705SXin Li }
134*67e74705SXin Li }
135*67e74705SXin Li
WeakObjectProfileTy(const Expr * BaseE,const ObjCPropertyDecl * Prop)136*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,
137*67e74705SXin Li const ObjCPropertyDecl *Prop)
138*67e74705SXin Li : Base(nullptr, true), Property(Prop) {
139*67e74705SXin Li if (BaseE)
140*67e74705SXin Li Base = getBaseInfo(BaseE);
141*67e74705SXin Li // else, this is a message accessing a property on super.
142*67e74705SXin Li }
143*67e74705SXin Li
WeakObjectProfileTy(const DeclRefExpr * DRE)144*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
145*67e74705SXin Li const DeclRefExpr *DRE)
146*67e74705SXin Li : Base(nullptr, true), Property(DRE->getDecl()) {
147*67e74705SXin Li assert(isa<VarDecl>(Property));
148*67e74705SXin Li }
149*67e74705SXin Li
WeakObjectProfileTy(const ObjCIvarRefExpr * IvarE)150*67e74705SXin Li FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
151*67e74705SXin Li const ObjCIvarRefExpr *IvarE)
152*67e74705SXin Li : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) {
153*67e74705SXin Li }
154*67e74705SXin Li
recordUseOfWeak(const ObjCMessageExpr * Msg,const ObjCPropertyDecl * Prop)155*67e74705SXin Li void FunctionScopeInfo::recordUseOfWeak(const ObjCMessageExpr *Msg,
156*67e74705SXin Li const ObjCPropertyDecl *Prop) {
157*67e74705SXin Li assert(Msg && Prop);
158*67e74705SXin Li WeakUseVector &Uses =
159*67e74705SXin Li WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)];
160*67e74705SXin Li Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0));
161*67e74705SXin Li }
162*67e74705SXin Li
markSafeWeakUse(const Expr * E)163*67e74705SXin Li void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
164*67e74705SXin Li E = E->IgnoreParenCasts();
165*67e74705SXin Li
166*67e74705SXin Li if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
167*67e74705SXin Li markSafeWeakUse(POE->getSyntacticForm());
168*67e74705SXin Li return;
169*67e74705SXin Li }
170*67e74705SXin Li
171*67e74705SXin Li if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) {
172*67e74705SXin Li markSafeWeakUse(Cond->getTrueExpr());
173*67e74705SXin Li markSafeWeakUse(Cond->getFalseExpr());
174*67e74705SXin Li return;
175*67e74705SXin Li }
176*67e74705SXin Li
177*67e74705SXin Li if (const BinaryConditionalOperator *Cond =
178*67e74705SXin Li dyn_cast<BinaryConditionalOperator>(E)) {
179*67e74705SXin Li markSafeWeakUse(Cond->getCommon());
180*67e74705SXin Li markSafeWeakUse(Cond->getFalseExpr());
181*67e74705SXin Li return;
182*67e74705SXin Li }
183*67e74705SXin Li
184*67e74705SXin Li // Has this weak object been seen before?
185*67e74705SXin Li FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
186*67e74705SXin Li if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
187*67e74705SXin Li if (!RefExpr->isObjectReceiver())
188*67e74705SXin Li return;
189*67e74705SXin Li if (isa<OpaqueValueExpr>(RefExpr->getBase()))
190*67e74705SXin Li Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
191*67e74705SXin Li else {
192*67e74705SXin Li markSafeWeakUse(RefExpr->getBase());
193*67e74705SXin Li return;
194*67e74705SXin Li }
195*67e74705SXin Li }
196*67e74705SXin Li else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
197*67e74705SXin Li Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
198*67e74705SXin Li else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
199*67e74705SXin Li Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
200*67e74705SXin Li else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
201*67e74705SXin Li Uses = WeakObjectUses.end();
202*67e74705SXin Li if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
203*67e74705SXin Li if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
204*67e74705SXin Li Uses =
205*67e74705SXin Li WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(),
206*67e74705SXin Li Prop));
207*67e74705SXin Li }
208*67e74705SXin Li }
209*67e74705SXin Li }
210*67e74705SXin Li else
211*67e74705SXin Li return;
212*67e74705SXin Li
213*67e74705SXin Li if (Uses == WeakObjectUses.end())
214*67e74705SXin Li return;
215*67e74705SXin Li
216*67e74705SXin Li // Has there been a read from the object using this Expr?
217*67e74705SXin Li FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse =
218*67e74705SXin Li llvm::find(llvm::reverse(Uses->second), WeakUseTy(E, true));
219*67e74705SXin Li if (ThisUse == Uses->second.rend())
220*67e74705SXin Li return;
221*67e74705SXin Li
222*67e74705SXin Li ThisUse->markSafe();
223*67e74705SXin Li }
224*67e74705SXin Li
getPotentialVariableCapture(unsigned Idx,VarDecl * & VD,Expr * & E) const225*67e74705SXin Li void LambdaScopeInfo::getPotentialVariableCapture(unsigned Idx, VarDecl *&VD,
226*67e74705SXin Li Expr *&E) const {
227*67e74705SXin Li assert(Idx < getNumPotentialVariableCaptures() &&
228*67e74705SXin Li "Index of potential capture must be within 0 to less than the "
229*67e74705SXin Li "number of captures!");
230*67e74705SXin Li E = PotentiallyCapturingExprs[Idx];
231*67e74705SXin Li if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
232*67e74705SXin Li VD = dyn_cast<VarDecl>(DRE->getFoundDecl());
233*67e74705SXin Li else if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
234*67e74705SXin Li VD = dyn_cast<VarDecl>(ME->getMemberDecl());
235*67e74705SXin Li else
236*67e74705SXin Li llvm_unreachable("Only DeclRefExprs or MemberExprs should be added for "
237*67e74705SXin Li "potential captures");
238*67e74705SXin Li assert(VD);
239*67e74705SXin Li }
240*67e74705SXin Li
~FunctionScopeInfo()241*67e74705SXin Li FunctionScopeInfo::~FunctionScopeInfo() { }
~BlockScopeInfo()242*67e74705SXin Li BlockScopeInfo::~BlockScopeInfo() { }
~CapturedRegionScopeInfo()243*67e74705SXin Li CapturedRegionScopeInfo::~CapturedRegionScopeInfo() { }
244