• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===//
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 defines FunctionScopeInfo and its subclasses, which contain
11 // information about a single function, block, lambda, or method body.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H
16 #define LLVM_CLANG_SEMA_SCOPE_INFO_H
17 
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"
23 
24 namespace clang {
25 
26 class Decl;
27 class BlockDecl;
28 class CapturedDecl;
29 class CXXMethodDecl;
30 class FieldDecl;
31 class ObjCPropertyDecl;
32 class IdentifierInfo;
33 class ImplicitParamDecl;
34 class LabelDecl;
35 class ReturnStmt;
36 class Scope;
37 class SwitchStmt;
38 class VarDecl;
39 class DeclRefExpr;
40 class ObjCIvarRefExpr;
41 class ObjCPropertyRefExpr;
42 class ObjCMessageExpr;
43 
44 namespace sema {
45 
46 /// \brief Contains information about the compound statement currently being
47 /// parsed.
48 class CompoundScopeInfo {
49 public:
CompoundScopeInfo()50   CompoundScopeInfo()
51     : HasEmptyLoopBodies(false) { }
52 
53   /// \brief Whether this compound stamement contains `for' or `while' loops
54   /// with empty bodies.
55   bool HasEmptyLoopBodies;
56 
setHasEmptyLoopBodies()57   void setHasEmptyLoopBodies() {
58     HasEmptyLoopBodies = true;
59   }
60 };
61 
62 class PossiblyUnreachableDiag {
63 public:
64   PartialDiagnostic PD;
65   SourceLocation Loc;
66   const Stmt *stmt;
67 
PossiblyUnreachableDiag(const PartialDiagnostic & PD,SourceLocation Loc,const Stmt * stmt)68   PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc,
69                           const Stmt *stmt)
70     : PD(PD), Loc(Loc), stmt(stmt) {}
71 };
72 
73 /// \brief Retains information about a function, method, or block that is
74 /// currently being parsed.
75 class FunctionScopeInfo {
76 protected:
77   enum ScopeKind {
78     SK_Function,
79     SK_Block,
80     SK_Lambda,
81     SK_CapturedRegion
82   };
83 
84 public:
85   /// \brief What kind of scope we are describing.
86   ///
87   ScopeKind Kind;
88 
89   /// \brief Whether this function contains a VLA, \@try, try, C++
90   /// initializer, or anything else that can't be jumped past.
91   bool HasBranchProtectedScope;
92 
93   /// \brief Whether this function contains any switches or direct gotos.
94   bool HasBranchIntoScope;
95 
96   /// \brief Whether this function contains any indirect gotos.
97   bool HasIndirectGoto;
98 
99   /// \brief Whether a statement was dropped because it was invalid.
100   bool HasDroppedStmt;
101 
102   /// A flag that is set when parsing a method that must call super's
103   /// implementation, such as \c -dealloc, \c -finalize, or any method marked
104   /// with \c __attribute__((objc_requires_super)).
105   bool ObjCShouldCallSuper;
106 
107   /// \brief Used to determine if errors occurred in this function or block.
108   DiagnosticErrorTrap ErrorTrap;
109 
110   /// SwitchStack - This is the current set of active switch statements in the
111   /// block.
112   SmallVector<SwitchStmt*, 8> SwitchStack;
113 
114   /// \brief The list of return statements that occur within the function or
115   /// block, if there is any chance of applying the named return value
116   /// optimization, or if we need to infer a return type.
117   SmallVector<ReturnStmt*, 4> Returns;
118 
119   /// \brief The stack of currently active compound stamement scopes in the
120   /// function.
121   SmallVector<CompoundScopeInfo, 4> CompoundScopes;
122 
123   /// \brief A list of PartialDiagnostics created but delayed within the
124   /// current function scope.  These diagnostics are vetted for reachability
125   /// prior to being emitted.
126   SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags;
127 
128 public:
129   /// Represents a simple identification of a weak object.
130   ///
131   /// Part of the implementation of -Wrepeated-use-of-weak.
132   ///
133   /// This is used to determine if two weak accesses refer to the same object.
134   /// Here are some examples of how various accesses are "profiled":
135   ///
136   /// Access Expression |     "Base" Decl     |          "Property" Decl
137   /// :---------------: | :-----------------: | :------------------------------:
138   /// self.property     | self (VarDecl)      | property (ObjCPropertyDecl)
139   /// self.implicitProp | self (VarDecl)      | -implicitProp (ObjCMethodDecl)
140   /// self->ivar.prop   | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl)
141   /// cxxObj.obj.prop   | obj (FieldDecl)     | prop (ObjCPropertyDecl)
142   /// [self foo].prop   | 0 (unknown)         | prop (ObjCPropertyDecl)
143   /// self.prop1.prop2  | prop1 (ObjCPropertyDecl)    | prop2 (ObjCPropertyDecl)
144   /// MyClass.prop      | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl)
145   /// weakVar           | 0 (known)           | weakVar (VarDecl)
146   /// self->weakIvar    | self (VarDecl)      | weakIvar (ObjCIvarDecl)
147   ///
148   /// Objects are identified with only two Decls to make it reasonably fast to
149   /// compare them.
150   class WeakObjectProfileTy {
151     /// The base object decl, as described in the class documentation.
152     ///
153     /// The extra flag is "true" if the Base and Property are enough to uniquely
154     /// identify the object in memory.
155     ///
156     /// \sa isExactProfile()
157     typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy;
158     BaseInfoTy Base;
159 
160     /// The "property" decl, as described in the class documentation.
161     ///
162     /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the
163     /// case of "implicit" properties (regular methods accessed via dot syntax).
164     const NamedDecl *Property;
165 
166     /// Used to find the proper base profile for a given base expression.
167     static BaseInfoTy getBaseInfo(const Expr *BaseE);
168 
169     // For use in DenseMap.
170     friend class DenseMapInfo;
171     inline WeakObjectProfileTy();
172     static inline WeakObjectProfileTy getSentinel();
173 
174   public:
175     WeakObjectProfileTy(const ObjCPropertyRefExpr *RE);
176     WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property);
177     WeakObjectProfileTy(const DeclRefExpr *RE);
178     WeakObjectProfileTy(const ObjCIvarRefExpr *RE);
179 
getBase()180     const NamedDecl *getBase() const { return Base.getPointer(); }
getProperty()181     const NamedDecl *getProperty() const { return Property; }
182 
183     /// Returns true if the object base specifies a known object in memory,
184     /// rather than, say, an instance variable or property of another object.
185     ///
186     /// Note that this ignores the effects of aliasing; that is, \c foo.bar is
187     /// considered an exact profile if \c foo is a local variable, even if
188     /// another variable \c foo2 refers to the same object as \c foo.
189     ///
190     /// For increased precision, accesses with base variables that are
191     /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to
192     /// be exact, though this is not true for arbitrary variables
193     /// (foo.prop1.prop2).
isExactProfile()194     bool isExactProfile() const {
195       return Base.getInt();
196     }
197 
198     bool operator==(const WeakObjectProfileTy &Other) const {
199       return Base == Other.Base && Property == Other.Property;
200     }
201 
202     // For use in DenseMap.
203     // We can't specialize the usual llvm::DenseMapInfo at the end of the file
204     // because by that point the DenseMap in FunctionScopeInfo has already been
205     // instantiated.
206     class DenseMapInfo {
207     public:
getEmptyKey()208       static inline WeakObjectProfileTy getEmptyKey() {
209         return WeakObjectProfileTy();
210       }
getTombstoneKey()211       static inline WeakObjectProfileTy getTombstoneKey() {
212         return WeakObjectProfileTy::getSentinel();
213       }
214 
getHashValue(const WeakObjectProfileTy & Val)215       static unsigned getHashValue(const WeakObjectProfileTy &Val) {
216         typedef std::pair<BaseInfoTy, const NamedDecl *> Pair;
217         return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base,
218                                                            Val.Property));
219       }
220 
isEqual(const WeakObjectProfileTy & LHS,const WeakObjectProfileTy & RHS)221       static bool isEqual(const WeakObjectProfileTy &LHS,
222                           const WeakObjectProfileTy &RHS) {
223         return LHS == RHS;
224       }
225     };
226   };
227 
228   /// Represents a single use of a weak object.
229   ///
230   /// Stores both the expression and whether the access is potentially unsafe
231   /// (i.e. it could potentially be warned about).
232   ///
233   /// Part of the implementation of -Wrepeated-use-of-weak.
234   class WeakUseTy {
235     llvm::PointerIntPair<const Expr *, 1, bool> Rep;
236   public:
WeakUseTy(const Expr * Use,bool IsRead)237     WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
238 
getUseExpr()239     const Expr *getUseExpr() const { return Rep.getPointer(); }
isUnsafe()240     bool isUnsafe() const { return Rep.getInt(); }
markSafe()241     void markSafe() { Rep.setInt(false); }
242 
243     bool operator==(const WeakUseTy &Other) const {
244       return Rep == Other.Rep;
245     }
246   };
247 
248   /// Used to collect uses of a particular weak object in a function body.
249   ///
250   /// Part of the implementation of -Wrepeated-use-of-weak.
251   typedef SmallVector<WeakUseTy, 4> WeakUseVector;
252 
253   /// Used to collect all uses of weak objects in a function body.
254   ///
255   /// Part of the implementation of -Wrepeated-use-of-weak.
256   typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8,
257                               WeakObjectProfileTy::DenseMapInfo>
258           WeakObjectUseMap;
259 
260 private:
261   /// Used to collect all uses of weak objects in this function body.
262   ///
263   /// Part of the implementation of -Wrepeated-use-of-weak.
264   WeakObjectUseMap WeakObjectUses;
265 
266 public:
267   /// Record that a weak object was accessed.
268   ///
269   /// Part of the implementation of -Wrepeated-use-of-weak.
270   template <typename ExprT>
271   inline void recordUseOfWeak(const ExprT *E, bool IsRead = true);
272 
273   void recordUseOfWeak(const ObjCMessageExpr *Msg,
274                        const ObjCPropertyDecl *Prop);
275 
276   /// Record that a given expression is a "safe" access of a weak object (e.g.
277   /// assigning it to a strong variable.)
278   ///
279   /// Part of the implementation of -Wrepeated-use-of-weak.
280   void markSafeWeakUse(const Expr *E);
281 
getWeakObjectUses()282   const WeakObjectUseMap &getWeakObjectUses() const {
283     return WeakObjectUses;
284   }
285 
setHasBranchIntoScope()286   void setHasBranchIntoScope() {
287     HasBranchIntoScope = true;
288   }
289 
setHasBranchProtectedScope()290   void setHasBranchProtectedScope() {
291     HasBranchProtectedScope = true;
292   }
293 
setHasIndirectGoto()294   void setHasIndirectGoto() {
295     HasIndirectGoto = true;
296   }
297 
setHasDroppedStmt()298   void setHasDroppedStmt() {
299     HasDroppedStmt = true;
300   }
301 
NeedsScopeChecking()302   bool NeedsScopeChecking() const {
303     return !HasDroppedStmt &&
304         (HasIndirectGoto ||
305           (HasBranchProtectedScope && HasBranchIntoScope));
306   }
307 
FunctionScopeInfo(DiagnosticsEngine & Diag)308   FunctionScopeInfo(DiagnosticsEngine &Diag)
309     : Kind(SK_Function),
310       HasBranchProtectedScope(false),
311       HasBranchIntoScope(false),
312       HasIndirectGoto(false),
313       HasDroppedStmt(false),
314       ObjCShouldCallSuper(false),
315       ErrorTrap(Diag) { }
316 
317   virtual ~FunctionScopeInfo();
318 
319   /// \brief Clear out the information in this function scope, making it
320   /// suitable for reuse.
321   void Clear();
322 };
323 
324 class CapturingScopeInfo : public FunctionScopeInfo {
325 public:
326   enum ImplicitCaptureStyle {
327     ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
328     ImpCap_CapturedRegion
329   };
330 
331   ImplicitCaptureStyle ImpCaptureStyle;
332 
333   class Capture {
334     // There are three categories of capture: capturing 'this', capturing
335     // local variables, and C++1y initialized captures (which can have an
336     // arbitrary initializer, and don't really capture in the traditional
337     // sense at all).
338     //
339     // There are three ways to capture a local variable:
340     //  - capture by copy in the C++11 sense,
341     //  - capture by reference in the C++11 sense, and
342     //  - __block capture.
343     // Lambdas explicitly specify capture by copy or capture by reference.
344     // For blocks, __block capture applies to variables with that annotation,
345     // variables of reference type are captured by reference, and other
346     // variables are captured by copy.
347     enum CaptureKind {
348       Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_ThisOrInit
349     };
350 
351     // The variable being captured (if we are not capturing 'this', and whether
352     // this is a nested capture; the expression is only required if we are
353     // capturing ByVal and the variable's type has a non-trivial copy
354     // constructor, or for an initialized capture.
355     typedef llvm::PointerIntPair<VarDecl*, 1, bool> VarAndNested;
356 
357     // The variable being captured, or the implicitly-generated field for
358     // an init-capture.
359     llvm::PointerUnion<VarAndNested, FieldDecl*> VarOrField;
360 
361     // Expression to initialize a field of the given type, and the kind of
362     // capture (if this is a capture and not an init-capture).
363     llvm::PointerIntPair<Expr*, 2, CaptureKind> InitExprAndCaptureKind;
364 
365     /// \brief The source location at which the first capture occurred.
366     SourceLocation Loc;
367 
368     /// \brief The location of the ellipsis that expands a parameter pack.
369     SourceLocation EllipsisLoc;
370 
371     /// \brief The type as it was captured, which is in effect the type of the
372     /// non-static data member that would hold the capture.
373     QualType CaptureType;
374 
375   public:
Capture(VarDecl * Var,bool Block,bool ByRef,bool IsNested,SourceLocation Loc,SourceLocation EllipsisLoc,QualType CaptureType,Expr * Cpy)376     Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
377             SourceLocation Loc, SourceLocation EllipsisLoc,
378             QualType CaptureType, Expr *Cpy)
379         : VarOrField(VarAndNested(Var, IsNested)),
380           InitExprAndCaptureKind(Cpy, Block ? Cap_Block :
381                                       ByRef ? Cap_ByRef : Cap_ByCopy),
382           Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
383 
384     enum IsThisCapture { ThisCapture };
Capture(IsThisCapture,bool IsNested,SourceLocation Loc,QualType CaptureType,Expr * Cpy)385     Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
386             QualType CaptureType, Expr *Cpy)
387         : VarOrField(VarAndNested(0, IsNested)),
388           InitExprAndCaptureKind(Cpy, Cap_ThisOrInit),
389           Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {}
390 
Capture(FieldDecl * Field,Expr * Init)391     Capture(FieldDecl *Field, Expr *Init)
392         : VarOrField(Field), InitExprAndCaptureKind(Init, Cap_ThisOrInit),
393           Loc(), EllipsisLoc(), CaptureType() {}
394 
isThisCapture()395     bool isThisCapture() const {
396       return InitExprAndCaptureKind.getInt() == Cap_ThisOrInit &&
397              VarOrField.is<VarAndNested>();
398     }
isVariableCapture()399     bool isVariableCapture() const {
400       return InitExprAndCaptureKind.getInt() != Cap_ThisOrInit;
401     }
isInitCapture()402     bool isInitCapture() const {
403       return VarOrField.is<FieldDecl*>();
404     }
isCopyCapture()405     bool isCopyCapture() const {
406       return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
407     }
isReferenceCapture()408     bool isReferenceCapture() const {
409       return InitExprAndCaptureKind.getInt() == Cap_ByRef;
410     }
isBlockCapture()411     bool isBlockCapture() const {
412       return InitExprAndCaptureKind.getInt() == Cap_Block;
413     }
isNested()414     bool isNested() { return VarOrField.dyn_cast<VarAndNested>().getInt(); }
415 
getVariable()416     VarDecl *getVariable() const {
417       return VarOrField.dyn_cast<VarAndNested>().getPointer();
418     }
getInitCaptureField()419     FieldDecl *getInitCaptureField() const {
420       return VarOrField.dyn_cast<FieldDecl*>();
421     }
422 
423     /// \brief Retrieve the location at which this variable was captured.
getLocation()424     SourceLocation getLocation() const { return Loc; }
425 
426     /// \brief Retrieve the source location of the ellipsis, whose presence
427     /// indicates that the capture is a pack expansion.
getEllipsisLoc()428     SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
429 
430     /// \brief Retrieve the capture type for this capture, which is effectively
431     /// the type of the non-static data member in the lambda/block structure
432     /// that would store this capture.
getCaptureType()433     QualType getCaptureType() const { return CaptureType; }
434 
getInitExpr()435     Expr *getInitExpr() const {
436       return InitExprAndCaptureKind.getPointer();
437     }
438   };
439 
CapturingScopeInfo(DiagnosticsEngine & Diag,ImplicitCaptureStyle Style)440   CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
441     : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0),
442       HasImplicitReturnType(false)
443      {}
444 
445   /// CaptureMap - A map of captured variables to (index+1) into Captures.
446   llvm::DenseMap<VarDecl*, unsigned> CaptureMap;
447 
448   /// CXXThisCaptureIndex - The (index+1) of the capture of 'this';
449   /// zero if 'this' is not captured.
450   unsigned CXXThisCaptureIndex;
451 
452   /// Captures - The captures.
453   SmallVector<Capture, 4> Captures;
454 
455   /// \brief - Whether the target type of return statements in this context
456   /// is deduced (e.g. a lambda or block with omitted return type).
457   bool HasImplicitReturnType;
458 
459   /// ReturnType - The target type of return statements in this context,
460   /// or null if unknown.
461   QualType ReturnType;
462 
addCapture(VarDecl * Var,bool isBlock,bool isByref,bool isNested,SourceLocation Loc,SourceLocation EllipsisLoc,QualType CaptureType,Expr * Cpy)463   void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested,
464                   SourceLocation Loc, SourceLocation EllipsisLoc,
465                   QualType CaptureType, Expr *Cpy) {
466     Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc,
467                                EllipsisLoc, CaptureType, Cpy));
468     CaptureMap[Var] = Captures.size();
469   }
470 
471   void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType,
472                       Expr *Cpy);
473 
addInitCapture(FieldDecl * Field,Expr * Init)474   void addInitCapture(FieldDecl *Field, Expr *Init) {
475     Captures.push_back(Capture(Field, Init));
476   }
477 
478   /// \brief Determine whether the C++ 'this' is captured.
isCXXThisCaptured()479   bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
480 
481   /// \brief Retrieve the capture of C++ 'this', if it has been captured.
getCXXThisCapture()482   Capture &getCXXThisCapture() {
483     assert(isCXXThisCaptured() && "this has not been captured");
484     return Captures[CXXThisCaptureIndex - 1];
485   }
486 
487   /// \brief Determine whether the given variable has been captured.
isCaptured(VarDecl * Var)488   bool isCaptured(VarDecl *Var) const {
489     return CaptureMap.count(Var);
490   }
491 
492   /// \brief Retrieve the capture of the given variable, if it has been
493   /// captured already.
getCapture(VarDecl * Var)494   Capture &getCapture(VarDecl *Var) {
495     assert(isCaptured(Var) && "Variable has not been captured");
496     return Captures[CaptureMap[Var] - 1];
497   }
498 
getCapture(VarDecl * Var)499   const Capture &getCapture(VarDecl *Var) const {
500     llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known
501       = CaptureMap.find(Var);
502     assert(Known != CaptureMap.end() && "Variable has not been captured");
503     return Captures[Known->second - 1];
504   }
505 
classof(const FunctionScopeInfo * FSI)506   static bool classof(const FunctionScopeInfo *FSI) {
507     return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda
508                                  || FSI->Kind == SK_CapturedRegion;
509   }
510 };
511 
512 /// \brief Retains information about a block that is currently being parsed.
513 class BlockScopeInfo : public CapturingScopeInfo {
514 public:
515   BlockDecl *TheDecl;
516 
517   /// TheScope - This is the scope for the block itself, which contains
518   /// arguments etc.
519   Scope *TheScope;
520 
521   /// BlockType - The function type of the block, if one was given.
522   /// Its return type may be BuiltinType::Dependent.
523   QualType FunctionType;
524 
BlockScopeInfo(DiagnosticsEngine & Diag,Scope * BlockScope,BlockDecl * Block)525   BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block)
526     : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block),
527       TheScope(BlockScope)
528   {
529     Kind = SK_Block;
530   }
531 
532   virtual ~BlockScopeInfo();
533 
classof(const FunctionScopeInfo * FSI)534   static bool classof(const FunctionScopeInfo *FSI) {
535     return FSI->Kind == SK_Block;
536   }
537 };
538 
539 /// \brief Retains information about a captured region.
540 class CapturedRegionScopeInfo: public CapturingScopeInfo {
541 public:
542   /// \brief The CapturedDecl for this statement.
543   CapturedDecl *TheCapturedDecl;
544   /// \brief The captured record type.
545   RecordDecl *TheRecordDecl;
546   /// \brief This is the enclosing scope of the captured region.
547   Scope *TheScope;
548   /// \brief The implicit parameter for the captured variables.
549   ImplicitParamDecl *ContextParam;
550   /// \brief The kind of captured region.
551   CapturedRegionKind CapRegionKind;
552 
CapturedRegionScopeInfo(DiagnosticsEngine & Diag,Scope * S,CapturedDecl * CD,RecordDecl * RD,ImplicitParamDecl * Context,CapturedRegionKind K)553   CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD,
554                           RecordDecl *RD, ImplicitParamDecl *Context,
555                           CapturedRegionKind K)
556     : CapturingScopeInfo(Diag, ImpCap_CapturedRegion),
557       TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S),
558       ContextParam(Context), CapRegionKind(K)
559   {
560     Kind = SK_CapturedRegion;
561   }
562 
563   virtual ~CapturedRegionScopeInfo();
564 
565   /// \brief A descriptive name for the kind of captured region this is.
getRegionName()566   StringRef getRegionName() const {
567     switch (CapRegionKind) {
568     case CR_Default:
569       return "default captured statement";
570     }
571     llvm_unreachable("Invalid captured region kind!");
572   }
573 
classof(const FunctionScopeInfo * FSI)574   static bool classof(const FunctionScopeInfo *FSI) {
575     return FSI->Kind == SK_CapturedRegion;
576   }
577 };
578 
579 class LambdaScopeInfo : public CapturingScopeInfo {
580 public:
581   /// \brief The class that describes the lambda.
582   CXXRecordDecl *Lambda;
583 
584   /// \brief The class that describes the lambda.
585   CXXMethodDecl *CallOperator;
586 
587   /// \brief Source range covering the lambda introducer [...].
588   SourceRange IntroducerRange;
589 
590   /// \brief The number of captures in the \c Captures list that are
591   /// explicit captures.
592   unsigned NumExplicitCaptures;
593 
594   /// \brief Whether this is a mutable lambda.
595   bool Mutable;
596 
597   /// \brief Whether the (empty) parameter list is explicit.
598   bool ExplicitParams;
599 
600   /// \brief Whether any of the capture expressions requires cleanups.
601   bool ExprNeedsCleanups;
602 
603   /// \brief Whether the lambda contains an unexpanded parameter pack.
604   bool ContainsUnexpandedParameterPack;
605 
606   /// \brief Variables used to index into by-copy array captures.
607   SmallVector<VarDecl *, 4> ArrayIndexVars;
608 
609   /// \brief Offsets into the ArrayIndexVars array at which each capture starts
610   /// its list of array index variables.
611   SmallVector<unsigned, 4> ArrayIndexStarts;
612 
LambdaScopeInfo(DiagnosticsEngine & Diag,CXXRecordDecl * Lambda,CXXMethodDecl * CallOperator)613   LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
614                   CXXMethodDecl *CallOperator)
615     : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
616       CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
617       ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
618   {
619     Kind = SK_Lambda;
620   }
621 
622   virtual ~LambdaScopeInfo();
623 
624   /// \brief Note when
finishedExplicitCaptures()625   void finishedExplicitCaptures() {
626     NumExplicitCaptures = Captures.size();
627   }
628 
classof(const FunctionScopeInfo * FSI)629   static bool classof(const FunctionScopeInfo *FSI) {
630     return FSI->Kind == SK_Lambda;
631   }
632 };
633 
634 
WeakObjectProfileTy()635 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
636   : Base(0, false), Property(0) {}
637 
638 FunctionScopeInfo::WeakObjectProfileTy
getSentinel()639 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
640   FunctionScopeInfo::WeakObjectProfileTy Result;
641   Result.Base.setInt(true);
642   return Result;
643 }
644 
645 template <typename ExprT>
recordUseOfWeak(const ExprT * E,bool IsRead)646 void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
647   assert(E);
648   WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
649   Uses.push_back(WeakUseTy(E, IsRead));
650 }
651 
652 inline void
addThisCapture(bool isNested,SourceLocation Loc,QualType CaptureType,Expr * Cpy)653 CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
654                                    QualType CaptureType, Expr *Cpy) {
655   Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
656                              Cpy));
657   CXXThisCaptureIndex = Captures.size();
658 
659   if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
660     LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
661 }
662 
663 } // end namespace sema
664 } // end namespace clang
665 
666 #endif
667