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