1 //===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines FunctionScopeInfo and its subclasses, which contain
11 // information about a single function, block, lambda, or method body.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H
16 #define LLVM_CLANG_SEMA_SCOPE_INFO_H
18 #include "clang/AST/Type.h"
19 #include "clang/Basic/PartialDiagnostic.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/SmallVector.h"
28 class ObjCPropertyDecl;
36 class ObjCIvarRefExpr;
37 class ObjCPropertyRefExpr;
38 class ObjCMessageExpr;
42 /// \brief Contains information about the compound statement currently being
44 class CompoundScopeInfo {
47 : HasEmptyLoopBodies(false) { }
49 /// \brief Whether this compound stamement contains `for' or `while' loops
50 /// with empty bodies.
51 bool HasEmptyLoopBodies;
53 void setHasEmptyLoopBodies() {
54 HasEmptyLoopBodies = true;
58 class PossiblyUnreachableDiag {
64 PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
66 : PD(PD), Loc(Loc), stmt(stmt) {}
69 /// \brief Retains information about a function, method, or block that is
70 /// currently being parsed.
71 class FunctionScopeInfo {
80 /// \brief What kind of scope we are describing.
84 /// \brief Whether this function contains a VLA, \@try, try, C++
85 /// initializer, or anything else that can't be jumped past.
86 bool HasBranchProtectedScope;
88 /// \brief Whether this function contains any switches or direct gotos.
89 bool HasBranchIntoScope;
91 /// \brief Whether this function contains any indirect gotos.
94 /// A flag that is set when parsing a method that must call super's
95 /// implementation, such as \c -dealloc, \c -finalize, or any method marked
96 /// with \c __attribute__((objc_requires_super)).
97 bool ObjCShouldCallSuper;
99 /// \brief Used to determine if errors occurred in this function or block.
100 DiagnosticErrorTrap ErrorTrap;
102 /// SwitchStack - This is the current set of active switch statements in the
104 SmallVector<SwitchStmt*, 8> SwitchStack;
106 /// \brief The list of return statements that occur within the function or
107 /// block, if there is any chance of applying the named return value
108 /// optimization, or if we need to infer a return type.
109 SmallVector<ReturnStmt*, 4> Returns;
111 /// \brief The stack of currently active compound stamement scopes in the
113 SmallVector<CompoundScopeInfo, 4> CompoundScopes;
115 /// \brief A list of PartialDiagnostics created but delayed within the
116 /// current function scope. These diagnostics are vetted for reachability
117 /// prior to being emitted.
118 SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
121 /// Represents a simple identification of a weak object.
123 /// Part of the implementation of -Wrepeated-use-of-weak.
125 /// This is used to determine if two weak accesses refer to the same object.
126 /// Here are some examples of how various accesses are "profiled":
128 /// Access Expression | "Base" Decl | "Property" Decl
129 /// :---------------: | :-----------------: | :------------------------------:
130 /// self.property | self (VarDecl) | property (ObjCPropertyDecl)
131 /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl)
132 /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
133 /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl)
134 /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl)
135 /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl)
136 /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
137 /// weakVar | 0 (known) | weakVar (VarDecl)
138 /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl)
140 /// Objects are identified with only two Decls to make it reasonably fast to
142 class WeakObjectProfileTy {
143 /// The base object decl, as described in the class documentation.
145 /// The extra flag is "true" if the Base and Property are enough to uniquely
146 /// identify the object in memory.
148 /// \sa isExactProfile()
149 typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
152 /// The "property" decl, as described in the class documentation.
154 /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
155 /// case of "implicit" properties (regular methods accessed via dot syntax).
156 const NamedDecl *Property;
158 /// Used to find the proper base profile for a given base expression.
159 static BaseInfoTy getBaseInfo(const Expr *BaseE);
161 // For use in DenseMap.
162 friend class DenseMapInfo;
163 inline WeakObjectProfileTy();
164 static inline WeakObjectProfileTy getSentinel();
167 WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
168 WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
169 WeakObjectProfileTy(const DeclRefExpr *RE);
170 WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
172 const NamedDecl *getBase() const { return Base.getPointer(); }
173 const NamedDecl *getProperty() const { return Property; }
175 /// Returns true if the object base specifies a known object in memory,
176 /// rather than, say, an instance variable or property of another object.
178 /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
179 /// considered an exact profile if \c foo is a local variable, even if
180 /// another variable \c foo2 refers to the same object as \c foo.
182 /// For increased precision, accesses with base variables that are
183 /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
184 /// be exact, though this is not true for arbitrary variables
185 /// (foo.prop1.prop2).
186 bool isExactProfile() const {
187 return Base.getInt();
190 bool operator==(const WeakObjectProfileTy &Other) const {
191 return Base == Other.Base && Property == Other.Property;
194 // For use in DenseMap.
195 // We can't specialize the usual llvm::DenseMapInfo at the end of the file
196 // because by that point the DenseMap in FunctionScopeInfo has already been
200 static inline WeakObjectProfileTy getEmptyKey() {
201 return WeakObjectProfileTy();
203 static inline WeakObjectProfileTy getTombstoneKey() {
204 return WeakObjectProfileTy::getSentinel();
207 static unsigned getHashValue(const WeakObjectProfileTy &Val) {
208 typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
209 return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
213 static bool isEqual(const WeakObjectProfileTy &LHS,
214 const WeakObjectProfileTy &RHS) {
220 /// Represents a single use of a weak object.
222 /// Stores both the expression and whether the access is potentially unsafe
223 /// (i.e. it could potentially be warned about).
225 /// Part of the implementation of -Wrepeated-use-of-weak.
227 llvm::PointerIntPair<const Expr *, 1, bool> Rep;
229 WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
231 const Expr *getUseExpr() const { return Rep.getPointer(); }
232 bool isUnsafe() const { return Rep.getInt(); }
233 void markSafe() { Rep.setInt(false); }
235 bool operator==(const WeakUseTy &Other) const {
236 return Rep == Other.Rep;
240 /// Used to collect uses of a particular weak object in a function body.
242 /// Part of the implementation of -Wrepeated-use-of-weak.
243 typedef SmallVector<WeakUseTy, 4> WeakUseVector;
245 /// Used to collect all uses of weak objects in a function body.
247 /// Part of the implementation of -Wrepeated-use-of-weak.
248 typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
249 WeakObjectProfileTy::DenseMapInfo>
253 /// Used to collect all uses of weak objects in this function body.
255 /// Part of the implementation of -Wrepeated-use-of-weak.
256 WeakObjectUseMap WeakObjectUses;
259 /// Record that a weak object was accessed.
261 /// Part of the implementation of -Wrepeated-use-of-weak.
262 template <typename ExprT>
263 inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
265 void recordUseOfWeak(const ObjCMessageExpr *Msg,
266 const ObjCPropertyDecl *Prop);
268 /// Record that a given expression is a "safe" access of a weak object (e.g.
269 /// assigning it to a strong variable.)
271 /// Part of the implementation of -Wrepeated-use-of-weak.
272 void markSafeWeakUse(const Expr *E);
274 const WeakObjectUseMap &getWeakObjectUses() const {
275 return WeakObjectUses;
278 void setHasBranchIntoScope() {
279 HasBranchIntoScope = true;
282 void setHasBranchProtectedScope() {
283 HasBranchProtectedScope = true;
286 void setHasIndirectGoto() {
287 HasIndirectGoto = true;
290 bool NeedsScopeChecking() const {
291 return HasIndirectGoto ||
292 (HasBranchProtectedScope && HasBranchIntoScope);
295 FunctionScopeInfo(DiagnosticsEngine &Diag)
297 HasBranchProtectedScope(false),
298 HasBranchIntoScope(false),
299 HasIndirectGoto(false),
300 ObjCShouldCallSuper(false),
303 virtual ~FunctionScopeInfo();
305 /// \brief Clear out the information in this function scope, making it
306 /// suitable for reuse.
310 class CapturingScopeInfo : public FunctionScopeInfo {
312 enum ImplicitCaptureStyle {
313 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block
316 ImplicitCaptureStyle ImpCaptureStyle;
319 // There are two categories of capture: capturing 'this', and capturing
320 // local variables. There are three ways to capture a local variable:
321 // capture by copy in the C++11 sense, capture by reference
322 // in the C++11 sense, and __block capture. Lambdas explicitly specify
323 // capture by copy or capture by reference. For blocks, __block capture
324 // applies to variables with that annotation, variables of reference type
325 // are captured by reference, and other variables are captured by copy.
327 Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
330 // The variable being captured (if we are not capturing 'this'),
331 // and misc bits descibing the capture.
332 llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
334 // Expression to initialize a field of the given type, and whether this
335 // is a nested capture; the expression is only required if we are
336 // capturing ByVal and the variable's type has a non-trivial
338 llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
340 /// \brief The source location at which the first capture occurred..
343 /// \brief The location of the ellipsis that expands a parameter pack.
344 SourceLocation EllipsisLoc;
346 /// \brief The type as it was captured, which is in effect the type of the
347 /// non-static data member that would hold the capture.
348 QualType CaptureType;
351 Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
352 SourceLocation Loc, SourceLocation EllipsisLoc,
353 QualType CaptureType, Expr *Cpy)
354 : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
355 CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
356 CaptureType(CaptureType){}
358 enum IsThisCapture { ThisCapture };
359 Capture(IsThisCapture, bool isNested, SourceLocation Loc,
360 QualType CaptureType, Expr *Cpy)
361 : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
362 EllipsisLoc(), CaptureType(CaptureType) { }
364 bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
365 bool isVariableCapture() const { return !isThisCapture(); }
366 bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
367 bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
368 bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
369 bool isNested() { return CopyExprAndNested.getInt(); }
371 VarDecl *getVariable() const {
372 return VarAndKind.getPointer();
375 /// \brief Retrieve the location at which this variable was captured.
376 SourceLocation getLocation() const { return Loc; }
378 /// \brief Retrieve the source location of the ellipsis, whose presence
379 /// indicates that the capture is a pack expansion.
380 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
382 /// \brief Retrieve the capture type for this capture, which is effectively
383 /// the type of the non-static data member in the lambda/block structure
384 /// that would store this capture.
385 QualType getCaptureType() const { return CaptureType; }
387 Expr *getCopyExpr() const {
388 return CopyExprAndNested.getPointer();
392 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
393 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
394 HasImplicitReturnType(false)
397 /// CaptureMap - A map of captured variables to (index+1) into Captures.
398 llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
400 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
401 /// zero if 'this' is not captured.
402 unsigned CXXThisCaptureIndex;
404 /// Captures - The captures.
405 SmallVector<Capture, 4> Captures;
407 /// \brief - Whether the target type of return statements in this context
408 /// is deduced (e.g. a lambda or block with omitted return type).
409 bool HasImplicitReturnType;
411 /// ReturnType - The target type of return statements in this context,
412 /// or null if unknown.
415 void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
416 SourceLocation Loc, SourceLocation EllipsisLoc,
417 QualType CaptureType, Expr *Cpy) {
418 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
419 EllipsisLoc, CaptureType, Cpy));
420 CaptureMap[Var] = Captures.size();
423 void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
426 /// \brief Determine whether the C++ 'this' is captured.
427 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
429 /// \brief Retrieve the capture of C++ 'this', if it has been captured.
430 Capture &getCXXThisCapture() {
431 assert(isCXXThisCaptured() && "this has not been captured");
432 return Captures[CXXThisCaptureIndex - 1];
435 /// \brief Determine whether the given variable has been captured.
436 bool isCaptured(VarDecl *Var) const {
437 return CaptureMap.count(Var);
440 /// \brief Retrieve the capture of the given variable, if it has been
441 /// captured already.
442 Capture &getCapture(VarDecl *Var) {
443 assert(isCaptured(Var) && "Variable has not been captured");
444 return Captures[CaptureMap[Var] - 1];
447 const Capture &getCapture(VarDecl *Var) const {
448 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
449 = CaptureMap.find(Var);
450 assert(Known != CaptureMap.end() && "Variable has not been captured");
451 return Captures[Known->second - 1];
454 static bool classof(const FunctionScopeInfo *FSI) {
455 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda;
459 /// \brief Retains information about a block that is currently being parsed.
460 class BlockScopeInfo : public CapturingScopeInfo {
464 /// TheScope - This is the scope for the block itself, which contains
468 /// BlockType - The function type of the block, if one was given.
469 /// Its return type may be BuiltinType::Dependent.
470 QualType FunctionType;
472 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
473 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
479 virtual ~BlockScopeInfo();
481 static bool classof(const FunctionScopeInfo *FSI) {
482 return FSI->Kind == SK_Block;
486 class LambdaScopeInfo : public CapturingScopeInfo {
488 /// \brief The class that describes the lambda.
489 CXXRecordDecl *Lambda;
491 /// \brief The class that describes the lambda.
492 CXXMethodDecl *CallOperator;
494 /// \brief Source range covering the lambda introducer [...].
495 SourceRange IntroducerRange;
497 /// \brief The number of captures in the \c Captures list that are
498 /// explicit captures.
499 unsigned NumExplicitCaptures;
501 /// \brief Whether this is a mutable lambda.
504 /// \brief Whether the (empty) parameter list is explicit.
507 /// \brief Whether any of the capture expressions requires cleanups.
508 bool ExprNeedsCleanups;
510 /// \brief Whether the lambda contains an unexpanded parameter pack.
511 bool ContainsUnexpandedParameterPack;
513 /// \brief Variables used to index into by-copy array captures.
514 llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
516 /// \brief Offsets into the ArrayIndexVars array at which each capture starts
517 /// its list of array index variables.
518 llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
520 LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
521 CXXMethodDecl *CallOperator)
522 : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
523 CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
524 ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
529 virtual ~LambdaScopeInfo();
532 void finishedExplicitCaptures() {
533 NumExplicitCaptures = Captures.size();
536 static bool classof(const FunctionScopeInfo *FSI) {
537 return FSI->Kind == SK_Lambda;
542 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
543 : Base(0, false), Property(0) {}
545 FunctionScopeInfo::WeakObjectProfileTy
546 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
547 FunctionScopeInfo::WeakObjectProfileTy Result;
548 Result.Base.setInt(true);
552 template <typename ExprT>
553 void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
555 WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
556 Uses.push_back(WeakUseTy(E, IsRead));
560 CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
561 QualType CaptureType, Expr *Cpy) {
562 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
564 CXXThisCaptureIndex = Captures.size();
566 if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
567 LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
570 } // end namespace sema
571 } // end namespace clang