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