xref: /minix3/external/bsd/llvm/dist/clang/lib/Sema/ScopeInfo.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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