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