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/CapturedStmt.h"
20 #include "clang/Basic/PartialDiagnostic.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/SmallVector.h"
30 class ObjCPropertyDecl;
32 class ImplicitParamDecl;
39 class ObjCIvarRefExpr;
40 class ObjCPropertyRefExpr;
41 class ObjCMessageExpr;
45 /// \brief Contains information about the compound statement currently being
47 class CompoundScopeInfo {
50 : HasEmptyLoopBodies(false) { }
52 /// \brief Whether this compound stamement contains `for' or `while' loops
53 /// with empty bodies.
54 bool HasEmptyLoopBodies;
56 void setHasEmptyLoopBodies() {
57 HasEmptyLoopBodies = true;
61 class PossiblyUnreachableDiag {
67 PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
69 : PD(PD), Loc(Loc), stmt(stmt) {}
72 /// \brief Retains information about a function, method, or block that is
73 /// currently being parsed.
74 class FunctionScopeInfo {
84 /// \brief What kind of scope we are describing.
88 /// \brief Whether this function contains a VLA, \@try, try, C++
89 /// initializer, or anything else that can't be jumped past.
90 bool HasBranchProtectedScope;
92 /// \brief Whether this function contains any switches or direct gotos.
93 bool HasBranchIntoScope;
95 /// \brief Whether this function contains any indirect gotos.
98 /// \brief Whether a statement was dropped because it was invalid.
101 /// A flag that is set when parsing a method that must call super's
102 /// implementation, such as \c -dealloc, \c -finalize, or any method marked
103 /// with \c __attribute__((objc_requires_super)).
104 bool ObjCShouldCallSuper;
106 /// \brief Used to determine if errors occurred in this function or block.
107 DiagnosticErrorTrap ErrorTrap;
109 /// SwitchStack - This is the current set of active switch statements in the
111 SmallVector<SwitchStmt*, 8> SwitchStack;
113 /// \brief The list of return statements that occur within the function or
114 /// block, if there is any chance of applying the named return value
115 /// optimization, or if we need to infer a return type.
116 SmallVector<ReturnStmt*, 4> Returns;
118 /// \brief The stack of currently active compound stamement scopes in the
120 SmallVector<CompoundScopeInfo, 4> CompoundScopes;
122 /// \brief A list of PartialDiagnostics created but delayed within the
123 /// current function scope. These diagnostics are vetted for reachability
124 /// prior to being emitted.
125 SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
128 /// Represents a simple identification of a weak object.
130 /// Part of the implementation of -Wrepeated-use-of-weak.
132 /// This is used to determine if two weak accesses refer to the same object.
133 /// Here are some examples of how various accesses are "profiled":
135 /// Access Expression | "Base" Decl | "Property" Decl
136 /// :---------------: | :-----------------: | :------------------------------:
137 /// self.property | self (VarDecl) | property (ObjCPropertyDecl)
138 /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl)
139 /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
140 /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl)
141 /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl)
142 /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl)
143 /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
144 /// weakVar | 0 (known) | weakVar (VarDecl)
145 /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl)
147 /// Objects are identified with only two Decls to make it reasonably fast to
149 class WeakObjectProfileTy {
150 /// The base object decl, as described in the class documentation.
152 /// The extra flag is "true" if the Base and Property are enough to uniquely
153 /// identify the object in memory.
155 /// \sa isExactProfile()
156 typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
159 /// The "property" decl, as described in the class documentation.
161 /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
162 /// case of "implicit" properties (regular methods accessed via dot syntax).
163 const NamedDecl *Property;
165 /// Used to find the proper base profile for a given base expression.
166 static BaseInfoTy getBaseInfo(const Expr *BaseE);
168 // For use in DenseMap.
169 friend class DenseMapInfo;
170 inline WeakObjectProfileTy();
171 static inline WeakObjectProfileTy getSentinel();
174 WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
175 WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
176 WeakObjectProfileTy(const DeclRefExpr *RE);
177 WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
179 const NamedDecl *getBase() const { return Base.getPointer(); }
180 const NamedDecl *getProperty() const { return Property; }
182 /// Returns true if the object base specifies a known object in memory,
183 /// rather than, say, an instance variable or property of another object.
185 /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
186 /// considered an exact profile if \c foo is a local variable, even if
187 /// another variable \c foo2 refers to the same object as \c foo.
189 /// For increased precision, accesses with base variables that are
190 /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
191 /// be exact, though this is not true for arbitrary variables
192 /// (foo.prop1.prop2).
193 bool isExactProfile() const {
194 return Base.getInt();
197 bool operator==(const WeakObjectProfileTy &Other) const {
198 return Base == Other.Base && Property == Other.Property;
201 // For use in DenseMap.
202 // We can't specialize the usual llvm::DenseMapInfo at the end of the file
203 // because by that point the DenseMap in FunctionScopeInfo has already been
207 static inline WeakObjectProfileTy getEmptyKey() {
208 return WeakObjectProfileTy();
210 static inline WeakObjectProfileTy getTombstoneKey() {
211 return WeakObjectProfileTy::getSentinel();
214 static unsigned getHashValue(const WeakObjectProfileTy &Val) {
215 typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
216 return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
220 static bool isEqual(const WeakObjectProfileTy &LHS,
221 const WeakObjectProfileTy &RHS) {
227 /// Represents a single use of a weak object.
229 /// Stores both the expression and whether the access is potentially unsafe
230 /// (i.e. it could potentially be warned about).
232 /// Part of the implementation of -Wrepeated-use-of-weak.
234 llvm::PointerIntPair<const Expr *, 1, bool> Rep;
236 WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
238 const Expr *getUseExpr() const { return Rep.getPointer(); }
239 bool isUnsafe() const { return Rep.getInt(); }
240 void markSafe() { Rep.setInt(false); }
242 bool operator==(const WeakUseTy &Other) const {
243 return Rep == Other.Rep;
247 /// Used to collect uses of a particular weak object in a function body.
249 /// Part of the implementation of -Wrepeated-use-of-weak.
250 typedef SmallVector<WeakUseTy, 4> WeakUseVector;
252 /// Used to collect all uses of weak objects in a function body.
254 /// Part of the implementation of -Wrepeated-use-of-weak.
255 typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
256 WeakObjectProfileTy::DenseMapInfo>
260 /// Used to collect all uses of weak objects in this function body.
262 /// Part of the implementation of -Wrepeated-use-of-weak.
263 WeakObjectUseMap WeakObjectUses;
266 /// Record that a weak object was accessed.
268 /// Part of the implementation of -Wrepeated-use-of-weak.
269 template <typename ExprT>
270 inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
272 void recordUseOfWeak(const ObjCMessageExpr *Msg,
273 const ObjCPropertyDecl *Prop);
275 /// Record that a given expression is a "safe" access of a weak object (e.g.
276 /// assigning it to a strong variable.)
278 /// Part of the implementation of -Wrepeated-use-of-weak.
279 void markSafeWeakUse(const Expr *E);
281 const WeakObjectUseMap &getWeakObjectUses() const {
282 return WeakObjectUses;
285 void setHasBranchIntoScope() {
286 HasBranchIntoScope = true;
289 void setHasBranchProtectedScope() {
290 HasBranchProtectedScope = true;
293 void setHasIndirectGoto() {
294 HasIndirectGoto = true;
297 void setHasDroppedStmt() {
298 HasDroppedStmt = true;
301 bool NeedsScopeChecking() const {
302 return !HasDroppedStmt &&
304 (HasBranchProtectedScope && HasBranchIntoScope));
307 FunctionScopeInfo(DiagnosticsEngine &Diag)
309 HasBranchProtectedScope(false),
310 HasBranchIntoScope(false),
311 HasIndirectGoto(false),
312 HasDroppedStmt(false),
313 ObjCShouldCallSuper(false),
316 virtual ~FunctionScopeInfo();
318 /// \brief Clear out the information in this function scope, making it
319 /// suitable for reuse.
323 class CapturingScopeInfo : public FunctionScopeInfo {
325 enum ImplicitCaptureStyle {
326 ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
327 ImpCap_CapturedRegion
330 ImplicitCaptureStyle ImpCaptureStyle;
333 // There are two categories of capture: capturing 'this', and capturing
334 // local variables. There are three ways to capture a local variable:
335 // capture by copy in the C++11 sense, capture by reference
336 // in the C++11 sense, and __block capture. Lambdas explicitly specify
337 // capture by copy or capture by reference. For blocks, __block capture
338 // applies to variables with that annotation, variables of reference type
339 // are captured by reference, and other variables are captured by copy.
341 Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block
344 // The variable being captured (if we are not capturing 'this'),
345 // and misc bits descibing the capture.
346 llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind;
348 // Expression to initialize a field of the given type, and whether this
349 // is a nested capture; the expression is only required if we are
350 // capturing ByVal and the variable's type has a non-trivial
352 llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested;
354 /// \brief The source location at which the first capture occurred..
357 /// \brief The location of the ellipsis that expands a parameter pack.
358 SourceLocation EllipsisLoc;
360 /// \brief The type as it was captured, which is in effect the type of the
361 /// non-static data member that would hold the capture.
362 QualType CaptureType;
365 Capture(VarDecl *Var, bool block, bool byRef, bool isNested,
366 SourceLocation Loc, SourceLocation EllipsisLoc,
367 QualType CaptureType, Expr *Cpy)
368 : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy),
369 CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc),
370 CaptureType(CaptureType){}
372 enum IsThisCapture { ThisCapture };
373 Capture(IsThisCapture, bool isNested, SourceLocation Loc,
374 QualType CaptureType, Expr *Cpy)
375 : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc),
376 EllipsisLoc(), CaptureType(CaptureType) { }
378 bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; }
379 bool isVariableCapture() const { return !isThisCapture(); }
380 bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; }
381 bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; }
382 bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; }
383 bool isNested() { return CopyExprAndNested.getInt(); }
385 VarDecl *getVariable() const {
386 return VarAndKind.getPointer();
389 /// \brief Retrieve the location at which this variable was captured.
390 SourceLocation getLocation() const { return Loc; }
392 /// \brief Retrieve the source location of the ellipsis, whose presence
393 /// indicates that the capture is a pack expansion.
394 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
396 /// \brief Retrieve the capture type for this capture, which is effectively
397 /// the type of the non-static data member in the lambda/block structure
398 /// that would store this capture.
399 QualType getCaptureType() const { return CaptureType; }
401 Expr *getCopyExpr() const {
402 return CopyExprAndNested.getPointer();
406 CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
407 : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
408 HasImplicitReturnType(false)
411 /// CaptureMap - A map of captured variables to (index+1) into Captures.
412 llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
414 /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
415 /// zero if 'this' is not captured.
416 unsigned CXXThisCaptureIndex;
418 /// Captures - The captures.
419 SmallVector<Capture, 4> Captures;
421 /// \brief - Whether the target type of return statements in this context
422 /// is deduced (e.g. a lambda or block with omitted return type).
423 bool HasImplicitReturnType;
425 /// ReturnType - The target type of return statements in this context,
426 /// or null if unknown.
429 void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
430 SourceLocation Loc, SourceLocation EllipsisLoc,
431 QualType CaptureType, Expr *Cpy) {
432 Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
433 EllipsisLoc, CaptureType, Cpy));
434 CaptureMap[Var] = Captures.size();
437 void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
440 /// \brief Determine whether the C++ 'this' is captured.
441 bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
443 /// \brief Retrieve the capture of C++ 'this', if it has been captured.
444 Capture &getCXXThisCapture() {
445 assert(isCXXThisCaptured() && "this has not been captured");
446 return Captures[CXXThisCaptureIndex - 1];
449 /// \brief Determine whether the given variable has been captured.
450 bool isCaptured(VarDecl *Var) const {
451 return CaptureMap.count(Var);
454 /// \brief Retrieve the capture of the given variable, if it has been
455 /// captured already.
456 Capture &getCapture(VarDecl *Var) {
457 assert(isCaptured(Var) && "Variable has not been captured");
458 return Captures[CaptureMap[Var] - 1];
461 const Capture &getCapture(VarDecl *Var) const {
462 llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
463 = CaptureMap.find(Var);
464 assert(Known != CaptureMap.end() && "Variable has not been captured");
465 return Captures[Known->second - 1];
468 static bool classof(const FunctionScopeInfo *FSI) {
469 return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
470 || FSI->Kind == SK_CapturedRegion;
474 /// \brief Retains information about a block that is currently being parsed.
475 class BlockScopeInfo : public CapturingScopeInfo {
479 /// TheScope - This is the scope for the block itself, which contains
483 /// BlockType - The function type of the block, if one was given.
484 /// Its return type may be BuiltinType::Dependent.
485 QualType FunctionType;
487 BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
488 : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
494 virtual ~BlockScopeInfo();
496 static bool classof(const FunctionScopeInfo *FSI) {
497 return FSI->Kind == SK_Block;
501 /// \brief Retains information about a captured region.
502 class CapturedRegionScopeInfo: public CapturingScopeInfo {
504 /// \brief The CapturedDecl for this statement.
505 CapturedDecl *TheCapturedDecl;
506 /// \brief The captured record type.
507 RecordDecl *TheRecordDecl;
508 /// \brief This is the enclosing scope of the captured region.
510 /// \brief The implicit parameter for the captured variables.
511 ImplicitParamDecl *ContextParam;
512 /// \brief The kind of captured region.
513 CapturedRegionKind CapRegionKind;
515 CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
516 RecordDecl *RD, ImplicitParamDecl *Context,
517 CapturedRegionKind K)
518 : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
519 TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
520 ContextParam(Context), CapRegionKind(K)
522 Kind = SK_CapturedRegion;
525 virtual ~CapturedRegionScopeInfo();
527 /// \brief A descriptive name for the kind of captured region this is.
528 StringRef getRegionName() const {
529 switch (CapRegionKind) {
531 return "default captured statement";
533 llvm_unreachable("Invalid captured region kind!");
536 static bool classof(const FunctionScopeInfo *FSI) {
537 return FSI->Kind == SK_CapturedRegion;
541 class LambdaScopeInfo : public CapturingScopeInfo {
543 /// \brief The class that describes the lambda.
544 CXXRecordDecl *Lambda;
546 /// \brief The class that describes the lambda.
547 CXXMethodDecl *CallOperator;
549 /// \brief Source range covering the lambda introducer [...].
550 SourceRange IntroducerRange;
552 /// \brief The number of captures in the \c Captures list that are
553 /// explicit captures.
554 unsigned NumExplicitCaptures;
556 /// \brief Whether this is a mutable lambda.
559 /// \brief Whether the (empty) parameter list is explicit.
562 /// \brief Whether any of the capture expressions requires cleanups.
563 bool ExprNeedsCleanups;
565 /// \brief Whether the lambda contains an unexpanded parameter pack.
566 bool ContainsUnexpandedParameterPack;
568 /// \brief Variables used to index into by-copy array captures.
569 SmallVector<VarDecl *, 4> ArrayIndexVars;
571 /// \brief Offsets into the ArrayIndexVars array at which each capture starts
572 /// its list of array index variables.
573 SmallVector<unsigned, 4> ArrayIndexStarts;
575 LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
576 CXXMethodDecl *CallOperator)
577 : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
578 CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
579 ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
584 virtual ~LambdaScopeInfo();
587 void finishedExplicitCaptures() {
588 NumExplicitCaptures = Captures.size();
591 static bool classof(const FunctionScopeInfo *FSI) {
592 return FSI->Kind == SK_Lambda;
597 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
598 : Base(0, false), Property(0) {}
600 FunctionScopeInfo::WeakObjectProfileTy
601 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
602 FunctionScopeInfo::WeakObjectProfileTy Result;
603 Result.Base.setInt(true);
607 template <typename ExprT>
608 void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
610 WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
611 Uses.push_back(WeakUseTy(E, IsRead));
615 CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
616 QualType CaptureType, Expr *Cpy) {
617 Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
619 CXXThisCaptureIndex = Captures.size();
621 if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
622 LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
625 } // end namespace sema
626 } // end namespace clang