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