ScopeInfo.h revision 8f1a2db8649eb151ee620273dcf34b700176430f
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
24namespace clang {
25
26class Decl;
27class BlockDecl;
28class CapturedDecl;
29class CXXMethodDecl;
30class FieldDecl;
31class ObjCPropertyDecl;
32class IdentifierInfo;
33class ImplicitParamDecl;
34class LabelDecl;
35class ReturnStmt;
36class Scope;
37class SwitchStmt;
38class VarDecl;
39class DeclRefExpr;
40class ObjCIvarRefExpr;
41class ObjCPropertyRefExpr;
42class ObjCMessageExpr;
43
44namespace sema {
45
46/// \brief Contains information about the compound statement currently being
47/// parsed.
48class CompoundScopeInfo {
49public:
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
57  void setHasEmptyLoopBodies() {
58    HasEmptyLoopBodies = true;
59  }
60};
61
62class PossiblyUnreachableDiag {
63public:
64  PartialDiagnostic PD;
65  SourceLocation Loc;
66  const Stmt *stmt;
67
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.
75class FunctionScopeInfo {
76protected:
77  enum ScopeKind {
78    SK_Function,
79    SK_Block,
80    SK_Lambda,
81    SK_CapturedRegion
82  };
83
84public:
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
128public:
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
180    const NamedDecl *getBase() const { return Base.getPointer(); }
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).
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:
208      static inline WeakObjectProfileTy getEmptyKey() {
209        return WeakObjectProfileTy();
210      }
211      static inline WeakObjectProfileTy getTombstoneKey() {
212        return WeakObjectProfileTy::getSentinel();
213      }
214
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
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:
237    WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {}
238
239    const Expr *getUseExpr() const { return Rep.getPointer(); }
240    bool isUnsafe() const { return Rep.getInt(); }
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
260private:
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
266public:
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
282  const WeakObjectUseMap &getWeakObjectUses() const {
283    return WeakObjectUses;
284  }
285
286  void setHasBranchIntoScope() {
287    HasBranchIntoScope = true;
288  }
289
290  void setHasBranchProtectedScope() {
291    HasBranchProtectedScope = true;
292  }
293
294  void setHasIndirectGoto() {
295    HasIndirectGoto = true;
296  }
297
298  void setHasDroppedStmt() {
299    HasDroppedStmt = true;
300  }
301
302  bool NeedsScopeChecking() const {
303    return !HasDroppedStmt &&
304        (HasIndirectGoto ||
305          (HasBranchProtectedScope && HasBranchIntoScope));
306  }
307
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
324class CapturingScopeInfo : public FunctionScopeInfo {
325public:
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:
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 };
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
391    Capture(FieldDecl *Field, Expr *Init)
392        : VarOrField(Field), InitExprAndCaptureKind(Init, Cap_ThisOrInit),
393          Loc(), EllipsisLoc(), CaptureType() {}
394
395    bool isThisCapture() const {
396      return InitExprAndCaptureKind.getInt() == Cap_ThisOrInit &&
397             VarOrField.is<VarAndNested>();
398    }
399    bool isVariableCapture() const {
400      return InitExprAndCaptureKind.getInt() != Cap_ThisOrInit;
401    }
402    bool isInitCapture() const {
403      return VarOrField.is<FieldDecl*>();
404    }
405    bool isCopyCapture() const {
406      return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
407    }
408    bool isReferenceCapture() const {
409      return InitExprAndCaptureKind.getInt() == Cap_ByRef;
410    }
411    bool isBlockCapture() const {
412      return InitExprAndCaptureKind.getInt() == Cap_Block;
413    }
414    bool isNested() { return VarOrField.dyn_cast<VarAndNested>().getInt(); }
415
416    VarDecl *getVariable() const {
417      return VarOrField.dyn_cast<VarAndNested>().getPointer();
418    }
419    FieldDecl *getInitCaptureField() const {
420      return VarOrField.dyn_cast<FieldDecl*>();
421    }
422
423    /// \brief Retrieve the location at which this variable was captured.
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.
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.
433    QualType getCaptureType() const { return CaptureType; }
434
435    Expr *getInitExpr() const {
436      return InitExprAndCaptureKind.getPointer();
437    }
438  };
439
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
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
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.
479  bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; }
480
481  /// \brief Retrieve the capture of C++ 'this', if it has been captured.
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.
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.
494  Capture &getCapture(VarDecl *Var) {
495    assert(isCaptured(Var) && "Variable has not been captured");
496    return Captures[CaptureMap[Var] - 1];
497  }
498
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
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.
513class BlockScopeInfo : public CapturingScopeInfo {
514public:
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
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
534  static bool classof(const FunctionScopeInfo *FSI) {
535    return FSI->Kind == SK_Block;
536  }
537};
538
539/// \brief Retains information about a captured region.
540class CapturedRegionScopeInfo: public CapturingScopeInfo {
541public:
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
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.
566  StringRef getRegionName() const {
567    switch (CapRegionKind) {
568    case CR_Default:
569      return "default captured statement";
570    case CR_OpenMP:
571      return "OpenMP region";
572    }
573    llvm_unreachable("Invalid captured region kind!");
574  }
575
576  static bool classof(const FunctionScopeInfo *FSI) {
577    return FSI->Kind == SK_CapturedRegion;
578  }
579};
580
581class LambdaScopeInfo : public CapturingScopeInfo {
582public:
583  /// \brief The class that describes the lambda.
584  CXXRecordDecl *Lambda;
585
586  /// \brief The lambda's compiler-generated \c operator().
587  CXXMethodDecl *CallOperator;
588
589  /// \brief Source range covering the lambda introducer [...].
590  SourceRange IntroducerRange;
591
592  /// \brief Source location of the '&' or '=' specifying the default capture
593  /// type, if any.
594  SourceLocation CaptureDefaultLoc;
595
596  /// \brief The number of captures in the \c Captures list that are
597  /// explicit captures.
598  unsigned NumExplicitCaptures;
599
600  /// \brief Whether this is a mutable lambda.
601  bool Mutable;
602
603  /// \brief Whether the (empty) parameter list is explicit.
604  bool ExplicitParams;
605
606  /// \brief Whether any of the capture expressions requires cleanups.
607  bool ExprNeedsCleanups;
608
609  /// \brief Whether the lambda contains an unexpanded parameter pack.
610  bool ContainsUnexpandedParameterPack;
611
612  /// \brief Variables used to index into by-copy array captures.
613  SmallVector<VarDecl *, 4> ArrayIndexVars;
614
615  /// \brief Offsets into the ArrayIndexVars array at which each capture starts
616  /// its list of array index variables.
617  SmallVector<unsigned, 4> ArrayIndexStarts;
618
619  LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda,
620                  CXXMethodDecl *CallOperator)
621    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
622      CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
623      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
624  {
625    Kind = SK_Lambda;
626  }
627
628  virtual ~LambdaScopeInfo();
629
630  /// \brief Note when all explicit captures have been added.
631  void finishedExplicitCaptures() {
632    NumExplicitCaptures = Captures.size();
633  }
634
635  static bool classof(const FunctionScopeInfo *FSI) {
636    return FSI->Kind == SK_Lambda;
637  }
638};
639
640
641FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
642  : Base(0, false), Property(0) {}
643
644FunctionScopeInfo::WeakObjectProfileTy
645FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
646  FunctionScopeInfo::WeakObjectProfileTy Result;
647  Result.Base.setInt(true);
648  return Result;
649}
650
651template <typename ExprT>
652void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) {
653  assert(E);
654  WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)];
655  Uses.push_back(WeakUseTy(E, IsRead));
656}
657
658inline void
659CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc,
660                                   QualType CaptureType, Expr *Cpy) {
661  Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType,
662                             Cpy));
663  CXXThisCaptureIndex = Captures.size();
664
665  if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this))
666    LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size());
667}
668
669} // end namespace sema
670} // end namespace clang
671
672#endif
673