clang  3.7.0
ScopeInfo.cpp
Go to the documentation of this file.
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 
28  HasBranchIntoScope = false;
29  HasIndirectGoto = false;
30  HasDroppedStmt = false;
31  ObjCShouldCallSuper = false;
32  ObjCIsDesignatedInit = false;
34  ObjCIsSecondaryInit = false;
38 
39  SwitchStack.clear();
40  Returns.clear();
41  ErrorTrap.reset();
43  WeakObjectUses.clear();
44  ModifiedNonNullParams.clear();
45 }
46 
47 static const NamedDecl *getBestPropertyDecl(const ObjCPropertyRefExpr *PropE) {
48  if (PropE->isExplicitProperty())
49  return PropE->getExplicitProperty();
50 
51  return PropE->getImplicitPropertyGetter();
52 }
53 
54 FunctionScopeInfo::WeakObjectProfileTy::BaseInfoTy
55 FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {
56  E = E->IgnoreParenCasts();
57 
58  const NamedDecl *D = nullptr;
59  bool IsExact = false;
60 
61  switch (E->getStmtClass()) {
62  case Stmt::DeclRefExprClass:
63  D = cast<DeclRefExpr>(E)->getDecl();
64  IsExact = isa<VarDecl>(D);
65  break;
66  case Stmt::MemberExprClass: {
67  const MemberExpr *ME = cast<MemberExpr>(E);
68  D = ME->getMemberDecl();
69  IsExact = isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts());
70  break;
71  }
72  case Stmt::ObjCIvarRefExprClass: {
73  const ObjCIvarRefExpr *IE = cast<ObjCIvarRefExpr>(E);
74  D = IE->getDecl();
75  IsExact = IE->getBase()->isObjCSelfExpr();
76  break;
77  }
78  case Stmt::PseudoObjectExprClass: {
79  const PseudoObjectExpr *POE = cast<PseudoObjectExpr>(E);
80  const ObjCPropertyRefExpr *BaseProp =
81  dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
82  if (BaseProp) {
83  D = getBestPropertyDecl(BaseProp);
84 
85  const Expr *DoubleBase = BaseProp->getBase();
86  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(DoubleBase))
87  DoubleBase = OVE->getSourceExpr();
88 
89  IsExact = DoubleBase->isObjCSelfExpr();
90  }
91  break;
92  }
93  default:
94  break;
95  }
96 
97  return BaseInfoTy(D, IsExact);
98 }
99 
101  RecordDecl *RD = nullptr;
102  if (auto *LSI = dyn_cast<LambdaScopeInfo>(this))
103  RD = LSI->Lambda;
104  else if (auto CRSI = dyn_cast<CapturedRegionScopeInfo>(this))
105  RD = CRSI->TheRecordDecl;
106 
107  if (RD)
108  for (auto *FD : RD->fields()) {
109  if (FD->hasCapturedVLAType() && FD->getCapturedVLAType() == VAT)
110  return true;
111  }
112  return false;
113 }
114 
115 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
116  const ObjCPropertyRefExpr *PropE)
117  : Base(nullptr, true), Property(getBestPropertyDecl(PropE)) {
118 
119  if (PropE->isObjectReceiver()) {
120  const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase());
121  const Expr *E = OVE->getSourceExpr();
122  Base = getBaseInfo(E);
123  } else if (PropE->isClassReceiver()) {
124  Base.setPointer(PropE->getClassReceiver());
125  } else {
126  assert(PropE->isSuperReceiver());
127  }
128 }
129 
130 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,
131  const ObjCPropertyDecl *Prop)
132  : Base(nullptr, true), Property(Prop) {
133  if (BaseE)
134  Base = getBaseInfo(BaseE);
135  // else, this is a message accessing a property on super.
136 }
137 
138 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
139  const DeclRefExpr *DRE)
140  : Base(nullptr, true), Property(DRE->getDecl()) {
141  assert(isa<VarDecl>(Property));
142 }
143 
144 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
145  const ObjCIvarRefExpr *IvarE)
146  : Base(getBaseInfo(IvarE->getBase())), Property(IvarE->getDecl()) {
147 }
148 
150  const ObjCPropertyDecl *Prop) {
151  assert(Msg && Prop);
152  WeakUseVector &Uses =
153  WeakObjectUses[WeakObjectProfileTy(Msg->getInstanceReceiver(), Prop)];
154  Uses.push_back(WeakUseTy(Msg, Msg->getNumArgs() == 0));
155 }
156 
158  E = E->IgnoreParenCasts();
159 
160  if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
162  return;
163  }
164 
165  if (const ConditionalOperator *Cond = dyn_cast<ConditionalOperator>(E)) {
166  markSafeWeakUse(Cond->getTrueExpr());
167  markSafeWeakUse(Cond->getFalseExpr());
168  return;
169  }
170 
171  if (const BinaryConditionalOperator *Cond =
172  dyn_cast<BinaryConditionalOperator>(E)) {
173  markSafeWeakUse(Cond->getCommon());
174  markSafeWeakUse(Cond->getFalseExpr());
175  return;
176  }
177 
178  // Has this weak object been seen before?
179  FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
180  if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
181  if (!RefExpr->isObjectReceiver())
182  return;
183  if (isa<OpaqueValueExpr>(RefExpr->getBase()))
184  Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
185  else {
186  markSafeWeakUse(RefExpr->getBase());
187  return;
188  }
189  }
190  else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
191  Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
192  else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
193  Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
194  else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
195  Uses = WeakObjectUses.end();
196  if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
197  if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
198  Uses =
199  WeakObjectUses.find(WeakObjectProfileTy(MsgE->getInstanceReceiver(),
200  Prop));
201  }
202  }
203  }
204  else
205  return;
206 
207  if (Uses == WeakObjectUses.end())
208  return;
209 
210  // Has there been a read from the object using this Expr?
211  FunctionScopeInfo::WeakUseVector::reverse_iterator ThisUse =
212  std::find(Uses->second.rbegin(), Uses->second.rend(), WeakUseTy(E, true));
213  if (ThisUse == Uses->second.rend())
214  return;
215 
216  ThisUse->markSafe();
217 }
218 
220  Expr *&E) const {
221  assert(Idx < getNumPotentialVariableCaptures() &&
222  "Index of potential capture must be within 0 to less than the "
223  "number of captures!");
224  E = PotentiallyCapturingExprs[Idx];
225  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
226  VD = dyn_cast<VarDecl>(DRE->getFoundDecl());
227  else if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
228  VD = dyn_cast<VarDecl>(ME->getMemberDecl());
229  else
230  llvm_unreachable("Only DeclRefExprs or MemberExprs should be added for "
231  "potential captures");
232  assert(VD);
233 }
234 
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:2411
const Expr * getBase() const
Definition: ExprObjC.h:504
Expr * getSyntacticForm()
Definition: Expr.h:4756
static const NamedDecl * getBestPropertyDecl(const ObjCPropertyRefExpr *PropE)
Definition: ScopeInfo.cpp:47
bool isExplicitProperty() const
Definition: ExprObjC.h:626
SmallVector< SwitchStmt *, 8 > SwitchStack
Definition: ScopeInfo.h:138
Defines the clang::Expr interface and subclasses for C++ expressions.
bool HasDroppedStmt
Whether a statement was dropped because it was invalid.
Definition: ScopeInfo.h:105
ObjCInterfaceDecl * getClassReceiver() const
Definition: ExprObjC.h:691
SourceLocation FirstSEHTryLoc
First SEH '__try' statement in the current function.
Definition: ScopeInfo.h:131
DiagnosticErrorTrap ErrorTrap
Used to determine if errors occurred in this function or block.
Definition: ScopeInfo.h:134
void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const
Definition: ScopeInfo.cpp:219
bool isSuperReceiver() const
Definition: ExprObjC.h:695
field_range fields() const
Definition: Decl.h:3349
Expr * IgnoreParenCasts() LLVM_READONLY
Definition: Expr.cpp:2439
const Expr * getBase() const
Definition: ExprObjC.h:677
SourceLocation FirstCXXTryLoc
First C++ 'try' statement in the current function.
Definition: ScopeInfo.h:128
ObjCIvarDecl * getDecl()
Definition: ExprObjC.h:500
static ObjCPropertyDecl * findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID)
Lookup a property by name in the specified DeclContext.
Definition: DeclObjC.cpp:154
SmallVector< ReturnStmt *, 4 > Returns
The list of return statements that occur within the function or block, if there is any chance of appl...
Definition: ScopeInfo.h:143
void recordUseOfWeak(const ExprT *E, bool IsRead=true)
Definition: ScopeInfo.h:826
bool isObjCSelfExpr() const
Check if this expression is the ObjC 'self' implicit parameter.
Definition: Expr.cpp:3353
ObjCMethodDecl * getImplicitPropertyGetter() const
Definition: ExprObjC.h:633
bool HasBranchProtectedScope
Whether this function contains a VLA, @try, try, C++ initializer, or anything else that can't be jump...
Definition: ScopeInfo.h:96
bool isVLATypeCaptured(const VariableArrayType *VAT) const
Determine whether the given variable-array type has been captured.
Definition: ScopeInfo.cpp:100
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:858
llvm::SmallPtrSet< const ParmVarDecl *, 8 > ModifiedNonNullParams
A list of parameters which have the nonnull attribute and are modified in the function.
Definition: ScopeInfo.h:156
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
Expr * getSourceExpr() const
Definition: Expr.h:869
void reset()
Set to initial state of "no errors occurred".
Definition: Diagnostic.h:844
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:2424
bool ObjCIsDesignatedInit
True when this is a method marked as a designated initializer.
Definition: ScopeInfo.h:113
bool isObjectReceiver() const
Definition: ExprObjC.h:694
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition: ExprObjC.h:1152
bool isClassReceiver() const
Definition: ExprObjC.h:696
bool HasIndirectGoto
Whether this function contains any indirect gotos.
Definition: ScopeInfo.h:102
Expr * IgnoreParenImpCasts() LLVM_READONLY
Definition: Expr.cpp:2526
void markSafeWeakUse(const Expr *E)
Definition: ScopeInfo.cpp:157
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver. ...
Definition: ExprObjC.h:1274
ObjCPropertyDecl * getExplicitProperty() const
Definition: ExprObjC.h:628
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:474
Expr * getBase() const
Definition: Expr.h:2405
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
SmallVector< PossiblyUnreachableDiag, 4 > PossiblyUnreachableDiags
A list of PartialDiagnostics created but delayed within the current function scope. These diagnostics are vetted for reachability prior to being emitted.
Definition: ScopeInfo.h:152
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
Definition: Expr.h:899
#define true
Definition: stdbool.h:32
void Clear()
Clear out the information in this function scope, making it suitable for reuse.
Definition: ScopeInfo.cpp:26
bool HasBranchIntoScope
Whether this function contains any switches or direct gotos.
Definition: ScopeInfo.h:99