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