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