1212795Sdim//===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===// 2212795Sdim// 3212795Sdim// The LLVM Compiler Infrastructure 4212795Sdim// 5212795Sdim// This file is distributed under the University of Illinois Open Source 6212795Sdim// License. See LICENSE.TXT for details. 7212795Sdim// 8212795Sdim//===----------------------------------------------------------------------===// 9212795Sdim// 10243830Sdim// This file defines FunctionScopeInfo and its subclasses, which contain 11243830Sdim// information about a single function, block, lambda, or method body. 12212795Sdim// 13212795Sdim//===----------------------------------------------------------------------===// 14212795Sdim 15212795Sdim#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H 16212795Sdim#define LLVM_CLANG_SEMA_SCOPE_INFO_H 17212795Sdim 18212795Sdim#include "clang/AST/Type.h" 19251662Sdim#include "clang/Basic/CapturedStmt.h" 20219077Sdim#include "clang/Basic/PartialDiagnostic.h" 21212795Sdim#include "llvm/ADT/DenseMap.h" 22212795Sdim#include "llvm/ADT/SmallVector.h" 23212795Sdim 24212795Sdimnamespace clang { 25212795Sdim 26243830Sdimclass Decl; 27212795Sdimclass BlockDecl; 28251662Sdimclass CapturedDecl; 29234353Sdimclass CXXMethodDecl; 30243830Sdimclass ObjCPropertyDecl; 31212795Sdimclass IdentifierInfo; 32251662Sdimclass ImplicitParamDecl; 33218893Sdimclass LabelDecl; 34212795Sdimclass ReturnStmt; 35212795Sdimclass Scope; 36212795Sdimclass SwitchStmt; 37234353Sdimclass VarDecl; 38243830Sdimclass DeclRefExpr; 39243830Sdimclass ObjCIvarRefExpr; 40243830Sdimclass ObjCPropertyRefExpr; 41243830Sdimclass ObjCMessageExpr; 42212795Sdim 43212795Sdimnamespace sema { 44212795Sdim 45234353Sdim/// \brief Contains information about the compound statement currently being 46234353Sdim/// parsed. 47234353Sdimclass CompoundScopeInfo { 48234353Sdimpublic: 49234353Sdim CompoundScopeInfo() 50234353Sdim : HasEmptyLoopBodies(false) { } 51234353Sdim 52234353Sdim /// \brief Whether this compound stamement contains `for' or `while' loops 53234353Sdim /// with empty bodies. 54234353Sdim bool HasEmptyLoopBodies; 55234353Sdim 56234353Sdim void setHasEmptyLoopBodies() { 57234353Sdim HasEmptyLoopBodies = true; 58234353Sdim } 59234353Sdim}; 60234353Sdim 61219077Sdimclass PossiblyUnreachableDiag { 62219077Sdimpublic: 63219077Sdim PartialDiagnostic PD; 64219077Sdim SourceLocation Loc; 65219077Sdim const Stmt *stmt; 66219077Sdim 67219077Sdim PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, 68219077Sdim const Stmt *stmt) 69219077Sdim : PD(PD), Loc(Loc), stmt(stmt) {} 70219077Sdim}; 71219077Sdim 72212795Sdim/// \brief Retains information about a function, method, or block that is 73212795Sdim/// currently being parsed. 74212795Sdimclass FunctionScopeInfo { 75234353Sdimprotected: 76234353Sdim enum ScopeKind { 77234353Sdim SK_Function, 78234353Sdim SK_Block, 79251662Sdim SK_Lambda, 80251662Sdim SK_CapturedRegion 81234353Sdim }; 82234353Sdim 83212795Sdimpublic: 84234353Sdim /// \brief What kind of scope we are describing. 85234353Sdim /// 86234353Sdim ScopeKind Kind; 87212795Sdim 88239462Sdim /// \brief Whether this function contains a VLA, \@try, try, C++ 89212795Sdim /// initializer, or anything else that can't be jumped past. 90212795Sdim bool HasBranchProtectedScope; 91212795Sdim 92212795Sdim /// \brief Whether this function contains any switches or direct gotos. 93212795Sdim bool HasBranchIntoScope; 94212795Sdim 95212795Sdim /// \brief Whether this function contains any indirect gotos. 96212795Sdim bool HasIndirectGoto; 97212795Sdim 98249423Sdim /// \brief Whether a statement was dropped because it was invalid. 99249423Sdim bool HasDroppedStmt; 100249423Sdim 101243830Sdim /// A flag that is set when parsing a method that must call super's 102243830Sdim /// implementation, such as \c -dealloc, \c -finalize, or any method marked 103243830Sdim /// with \c __attribute__((objc_requires_super)). 104243830Sdim bool ObjCShouldCallSuper; 105239462Sdim 106218893Sdim /// \brief Used to determine if errors occurred in this function or block. 107218893Sdim DiagnosticErrorTrap ErrorTrap; 108212795Sdim 109212795Sdim /// SwitchStack - This is the current set of active switch statements in the 110212795Sdim /// block. 111226633Sdim SmallVector<SwitchStmt*, 8> SwitchStack; 112212795Sdim 113212795Sdim /// \brief The list of return statements that occur within the function or 114212795Sdim /// block, if there is any chance of applying the named return value 115239462Sdim /// optimization, or if we need to infer a return type. 116226633Sdim SmallVector<ReturnStmt*, 4> Returns; 117234353Sdim 118234353Sdim /// \brief The stack of currently active compound stamement scopes in the 119234353Sdim /// function. 120234353Sdim SmallVector<CompoundScopeInfo, 4> CompoundScopes; 121234353Sdim 122219077Sdim /// \brief A list of PartialDiagnostics created but delayed within the 123219077Sdim /// current function scope. These diagnostics are vetted for reachability 124219077Sdim /// prior to being emitted. 125226633Sdim SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; 126212795Sdim 127243830Sdimpublic: 128243830Sdim /// Represents a simple identification of a weak object. 129243830Sdim /// 130243830Sdim /// Part of the implementation of -Wrepeated-use-of-weak. 131243830Sdim /// 132243830Sdim /// This is used to determine if two weak accesses refer to the same object. 133243830Sdim /// Here are some examples of how various accesses are "profiled": 134243830Sdim /// 135243830Sdim /// Access Expression | "Base" Decl | "Property" Decl 136243830Sdim /// :---------------: | :-----------------: | :------------------------------: 137243830Sdim /// self.property | self (VarDecl) | property (ObjCPropertyDecl) 138243830Sdim /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl) 139243830Sdim /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl) 140243830Sdim /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl) 141243830Sdim /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl) 142243830Sdim /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl) 143243830Sdim /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl) 144243830Sdim /// weakVar | 0 (known) | weakVar (VarDecl) 145243830Sdim /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl) 146243830Sdim /// 147243830Sdim /// Objects are identified with only two Decls to make it reasonably fast to 148243830Sdim /// compare them. 149243830Sdim class WeakObjectProfileTy { 150243830Sdim /// The base object decl, as described in the class documentation. 151243830Sdim /// 152243830Sdim /// The extra flag is "true" if the Base and Property are enough to uniquely 153243830Sdim /// identify the object in memory. 154243830Sdim /// 155243830Sdim /// \sa isExactProfile() 156243830Sdim typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy; 157243830Sdim BaseInfoTy Base; 158243830Sdim 159243830Sdim /// The "property" decl, as described in the class documentation. 160243830Sdim /// 161243830Sdim /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the 162243830Sdim /// case of "implicit" properties (regular methods accessed via dot syntax). 163243830Sdim const NamedDecl *Property; 164243830Sdim 165243830Sdim /// Used to find the proper base profile for a given base expression. 166243830Sdim static BaseInfoTy getBaseInfo(const Expr *BaseE); 167243830Sdim 168243830Sdim // For use in DenseMap. 169243830Sdim friend class DenseMapInfo; 170243830Sdim inline WeakObjectProfileTy(); 171243830Sdim static inline WeakObjectProfileTy getSentinel(); 172243830Sdim 173243830Sdim public: 174243830Sdim WeakObjectProfileTy(const ObjCPropertyRefExpr *RE); 175243830Sdim WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property); 176243830Sdim WeakObjectProfileTy(const DeclRefExpr *RE); 177243830Sdim WeakObjectProfileTy(const ObjCIvarRefExpr *RE); 178243830Sdim 179243830Sdim const NamedDecl *getBase() const { return Base.getPointer(); } 180243830Sdim const NamedDecl *getProperty() const { return Property; } 181243830Sdim 182243830Sdim /// Returns true if the object base specifies a known object in memory, 183243830Sdim /// rather than, say, an instance variable or property of another object. 184243830Sdim /// 185243830Sdim /// Note that this ignores the effects of aliasing; that is, \c foo.bar is 186243830Sdim /// considered an exact profile if \c foo is a local variable, even if 187243830Sdim /// another variable \c foo2 refers to the same object as \c foo. 188243830Sdim /// 189243830Sdim /// For increased precision, accesses with base variables that are 190243830Sdim /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to 191243830Sdim /// be exact, though this is not true for arbitrary variables 192243830Sdim /// (foo.prop1.prop2). 193243830Sdim bool isExactProfile() const { 194243830Sdim return Base.getInt(); 195243830Sdim } 196243830Sdim 197243830Sdim bool operator==(const WeakObjectProfileTy &Other) const { 198243830Sdim return Base == Other.Base && Property == Other.Property; 199243830Sdim } 200243830Sdim 201243830Sdim // For use in DenseMap. 202243830Sdim // We can't specialize the usual llvm::DenseMapInfo at the end of the file 203243830Sdim // because by that point the DenseMap in FunctionScopeInfo has already been 204243830Sdim // instantiated. 205243830Sdim class DenseMapInfo { 206243830Sdim public: 207243830Sdim static inline WeakObjectProfileTy getEmptyKey() { 208243830Sdim return WeakObjectProfileTy(); 209243830Sdim } 210243830Sdim static inline WeakObjectProfileTy getTombstoneKey() { 211243830Sdim return WeakObjectProfileTy::getSentinel(); 212243830Sdim } 213243830Sdim 214243830Sdim static unsigned getHashValue(const WeakObjectProfileTy &Val) { 215243830Sdim typedef std::pair<BaseInfoTy, const NamedDecl *> Pair; 216243830Sdim return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base, 217243830Sdim Val.Property)); 218243830Sdim } 219243830Sdim 220243830Sdim static bool isEqual(const WeakObjectProfileTy &LHS, 221243830Sdim const WeakObjectProfileTy &RHS) { 222243830Sdim return LHS == RHS; 223243830Sdim } 224243830Sdim }; 225243830Sdim }; 226243830Sdim 227243830Sdim /// Represents a single use of a weak object. 228243830Sdim /// 229243830Sdim /// Stores both the expression and whether the access is potentially unsafe 230243830Sdim /// (i.e. it could potentially be warned about). 231243830Sdim /// 232243830Sdim /// Part of the implementation of -Wrepeated-use-of-weak. 233243830Sdim class WeakUseTy { 234243830Sdim llvm::PointerIntPair<const Expr *, 1, bool> Rep; 235243830Sdim public: 236243830Sdim WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {} 237243830Sdim 238243830Sdim const Expr *getUseExpr() const { return Rep.getPointer(); } 239243830Sdim bool isUnsafe() const { return Rep.getInt(); } 240243830Sdim void markSafe() { Rep.setInt(false); } 241243830Sdim 242243830Sdim bool operator==(const WeakUseTy &Other) const { 243243830Sdim return Rep == Other.Rep; 244243830Sdim } 245243830Sdim }; 246243830Sdim 247243830Sdim /// Used to collect uses of a particular weak object in a function body. 248243830Sdim /// 249243830Sdim /// Part of the implementation of -Wrepeated-use-of-weak. 250243830Sdim typedef SmallVector<WeakUseTy, 4> WeakUseVector; 251243830Sdim 252243830Sdim /// Used to collect all uses of weak objects in a function body. 253243830Sdim /// 254243830Sdim /// Part of the implementation of -Wrepeated-use-of-weak. 255243830Sdim typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8, 256243830Sdim WeakObjectProfileTy::DenseMapInfo> 257243830Sdim WeakObjectUseMap; 258243830Sdim 259243830Sdimprivate: 260243830Sdim /// Used to collect all uses of weak objects in this function body. 261243830Sdim /// 262243830Sdim /// Part of the implementation of -Wrepeated-use-of-weak. 263243830Sdim WeakObjectUseMap WeakObjectUses; 264243830Sdim 265243830Sdimpublic: 266243830Sdim /// Record that a weak object was accessed. 267243830Sdim /// 268243830Sdim /// Part of the implementation of -Wrepeated-use-of-weak. 269243830Sdim template <typename ExprT> 270243830Sdim inline void recordUseOfWeak(const ExprT *E, bool IsRead = true); 271243830Sdim 272243830Sdim void recordUseOfWeak(const ObjCMessageExpr *Msg, 273243830Sdim const ObjCPropertyDecl *Prop); 274243830Sdim 275243830Sdim /// Record that a given expression is a "safe" access of a weak object (e.g. 276243830Sdim /// assigning it to a strong variable.) 277243830Sdim /// 278243830Sdim /// Part of the implementation of -Wrepeated-use-of-weak. 279243830Sdim void markSafeWeakUse(const Expr *E); 280243830Sdim 281243830Sdim const WeakObjectUseMap &getWeakObjectUses() const { 282243830Sdim return WeakObjectUses; 283243830Sdim } 284243830Sdim 285212795Sdim void setHasBranchIntoScope() { 286212795Sdim HasBranchIntoScope = true; 287212795Sdim } 288212795Sdim 289212795Sdim void setHasBranchProtectedScope() { 290212795Sdim HasBranchProtectedScope = true; 291212795Sdim } 292212795Sdim 293212795Sdim void setHasIndirectGoto() { 294212795Sdim HasIndirectGoto = true; 295212795Sdim } 296212795Sdim 297249423Sdim void setHasDroppedStmt() { 298249423Sdim HasDroppedStmt = true; 299249423Sdim } 300249423Sdim 301212795Sdim bool NeedsScopeChecking() const { 302249423Sdim return !HasDroppedStmt && 303249423Sdim (HasIndirectGoto || 304249423Sdim (HasBranchProtectedScope && HasBranchIntoScope)); 305212795Sdim } 306212795Sdim 307226633Sdim FunctionScopeInfo(DiagnosticsEngine &Diag) 308234353Sdim : Kind(SK_Function), 309212795Sdim HasBranchProtectedScope(false), 310212795Sdim HasBranchIntoScope(false), 311212795Sdim HasIndirectGoto(false), 312249423Sdim HasDroppedStmt(false), 313243830Sdim ObjCShouldCallSuper(false), 314218893Sdim ErrorTrap(Diag) { } 315212795Sdim 316212795Sdim virtual ~FunctionScopeInfo(); 317212795Sdim 318212795Sdim /// \brief Clear out the information in this function scope, making it 319212795Sdim /// suitable for reuse. 320218893Sdim void Clear(); 321212795Sdim}; 322212795Sdim 323234353Sdimclass CapturingScopeInfo : public FunctionScopeInfo { 324234353Sdimpublic: 325234353Sdim enum ImplicitCaptureStyle { 326251662Sdim ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block, 327251662Sdim ImpCap_CapturedRegion 328234353Sdim }; 329234353Sdim 330234353Sdim ImplicitCaptureStyle ImpCaptureStyle; 331234353Sdim 332234353Sdim class Capture { 333234353Sdim // There are two categories of capture: capturing 'this', and capturing 334234353Sdim // local variables. There are three ways to capture a local variable: 335234353Sdim // capture by copy in the C++11 sense, capture by reference 336234353Sdim // in the C++11 sense, and __block capture. Lambdas explicitly specify 337234353Sdim // capture by copy or capture by reference. For blocks, __block capture 338234353Sdim // applies to variables with that annotation, variables of reference type 339234353Sdim // are captured by reference, and other variables are captured by copy. 340234353Sdim enum CaptureKind { 341234353Sdim Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block 342234353Sdim }; 343234353Sdim 344234353Sdim // The variable being captured (if we are not capturing 'this'), 345234353Sdim // and misc bits descibing the capture. 346234353Sdim llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind; 347234353Sdim 348234353Sdim // Expression to initialize a field of the given type, and whether this 349234353Sdim // is a nested capture; the expression is only required if we are 350234353Sdim // capturing ByVal and the variable's type has a non-trivial 351234353Sdim // copy constructor. 352234353Sdim llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested; 353234353Sdim 354234353Sdim /// \brief The source location at which the first capture occurred.. 355234353Sdim SourceLocation Loc; 356234353Sdim 357234353Sdim /// \brief The location of the ellipsis that expands a parameter pack. 358234353Sdim SourceLocation EllipsisLoc; 359234353Sdim 360234353Sdim /// \brief The type as it was captured, which is in effect the type of the 361234353Sdim /// non-static data member that would hold the capture. 362234353Sdim QualType CaptureType; 363234353Sdim 364234353Sdim public: 365234353Sdim Capture(VarDecl *Var, bool block, bool byRef, bool isNested, 366234353Sdim SourceLocation Loc, SourceLocation EllipsisLoc, 367234353Sdim QualType CaptureType, Expr *Cpy) 368234353Sdim : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy), 369234353Sdim CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc), 370234353Sdim CaptureType(CaptureType){} 371234353Sdim 372234353Sdim enum IsThisCapture { ThisCapture }; 373234353Sdim Capture(IsThisCapture, bool isNested, SourceLocation Loc, 374234353Sdim QualType CaptureType, Expr *Cpy) 375234353Sdim : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc), 376234353Sdim EllipsisLoc(), CaptureType(CaptureType) { } 377234353Sdim 378234353Sdim bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; } 379234353Sdim bool isVariableCapture() const { return !isThisCapture(); } 380234353Sdim bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; } 381234353Sdim bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; } 382234353Sdim bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; } 383234353Sdim bool isNested() { return CopyExprAndNested.getInt(); } 384234353Sdim 385234353Sdim VarDecl *getVariable() const { 386234353Sdim return VarAndKind.getPointer(); 387234353Sdim } 388234353Sdim 389234353Sdim /// \brief Retrieve the location at which this variable was captured. 390234353Sdim SourceLocation getLocation() const { return Loc; } 391234353Sdim 392234353Sdim /// \brief Retrieve the source location of the ellipsis, whose presence 393234353Sdim /// indicates that the capture is a pack expansion. 394234353Sdim SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 395234353Sdim 396234353Sdim /// \brief Retrieve the capture type for this capture, which is effectively 397234353Sdim /// the type of the non-static data member in the lambda/block structure 398234353Sdim /// that would store this capture. 399234353Sdim QualType getCaptureType() const { return CaptureType; } 400234353Sdim 401234353Sdim Expr *getCopyExpr() const { 402234353Sdim return CopyExprAndNested.getPointer(); 403234353Sdim } 404234353Sdim }; 405234353Sdim 406234353Sdim CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style) 407234353Sdim : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0), 408234353Sdim HasImplicitReturnType(false) 409234353Sdim {} 410234353Sdim 411234353Sdim /// CaptureMap - A map of captured variables to (index+1) into Captures. 412234353Sdim llvm::DenseMap<VarDecl*, unsigned> CaptureMap; 413234353Sdim 414234353Sdim /// CXXThisCaptureIndex - The (index+1) of the capture of 'this'; 415234353Sdim /// zero if 'this' is not captured. 416234353Sdim unsigned CXXThisCaptureIndex; 417234353Sdim 418234353Sdim /// Captures - The captures. 419234353Sdim SmallVector<Capture, 4> Captures; 420234353Sdim 421234353Sdim /// \brief - Whether the target type of return statements in this context 422234353Sdim /// is deduced (e.g. a lambda or block with omitted return type). 423234353Sdim bool HasImplicitReturnType; 424234353Sdim 425234353Sdim /// ReturnType - The target type of return statements in this context, 426234353Sdim /// or null if unknown. 427234353Sdim QualType ReturnType; 428234353Sdim 429234353Sdim void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, 430234353Sdim SourceLocation Loc, SourceLocation EllipsisLoc, 431234353Sdim QualType CaptureType, Expr *Cpy) { 432234353Sdim Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, 433234353Sdim EllipsisLoc, CaptureType, Cpy)); 434234353Sdim CaptureMap[Var] = Captures.size(); 435234353Sdim } 436234353Sdim 437234353Sdim void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, 438243830Sdim Expr *Cpy); 439234353Sdim 440234353Sdim /// \brief Determine whether the C++ 'this' is captured. 441234353Sdim bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } 442234353Sdim 443234353Sdim /// \brief Retrieve the capture of C++ 'this', if it has been captured. 444234353Sdim Capture &getCXXThisCapture() { 445234353Sdim assert(isCXXThisCaptured() && "this has not been captured"); 446234353Sdim return Captures[CXXThisCaptureIndex - 1]; 447234353Sdim } 448234353Sdim 449234353Sdim /// \brief Determine whether the given variable has been captured. 450234353Sdim bool isCaptured(VarDecl *Var) const { 451234353Sdim return CaptureMap.count(Var); 452234353Sdim } 453234353Sdim 454234353Sdim /// \brief Retrieve the capture of the given variable, if it has been 455234353Sdim /// captured already. 456234353Sdim Capture &getCapture(VarDecl *Var) { 457234353Sdim assert(isCaptured(Var) && "Variable has not been captured"); 458234353Sdim return Captures[CaptureMap[Var] - 1]; 459234353Sdim } 460234353Sdim 461234353Sdim const Capture &getCapture(VarDecl *Var) const { 462234353Sdim llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known 463234353Sdim = CaptureMap.find(Var); 464234353Sdim assert(Known != CaptureMap.end() && "Variable has not been captured"); 465234353Sdim return Captures[Known->second - 1]; 466234353Sdim } 467234353Sdim 468234353Sdim static bool classof(const FunctionScopeInfo *FSI) { 469251662Sdim return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda 470251662Sdim || FSI->Kind == SK_CapturedRegion; 471234353Sdim } 472234353Sdim}; 473234353Sdim 474212795Sdim/// \brief Retains information about a block that is currently being parsed. 475234353Sdimclass BlockScopeInfo : public CapturingScopeInfo { 476212795Sdimpublic: 477212795Sdim BlockDecl *TheDecl; 478212795Sdim 479212795Sdim /// TheScope - This is the scope for the block itself, which contains 480212795Sdim /// arguments etc. 481212795Sdim Scope *TheScope; 482212795Sdim 483212795Sdim /// BlockType - The function type of the block, if one was given. 484212795Sdim /// Its return type may be BuiltinType::Dependent. 485212795Sdim QualType FunctionType; 486212795Sdim 487226633Sdim BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) 488234353Sdim : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block), 489234353Sdim TheScope(BlockScope) 490212795Sdim { 491234353Sdim Kind = SK_Block; 492212795Sdim } 493212795Sdim 494212795Sdim virtual ~BlockScopeInfo(); 495212795Sdim 496234353Sdim static bool classof(const FunctionScopeInfo *FSI) { 497234353Sdim return FSI->Kind == SK_Block; 498234353Sdim } 499212795Sdim}; 500212795Sdim 501251662Sdim/// \brief Retains information about a captured region. 502251662Sdimclass CapturedRegionScopeInfo: public CapturingScopeInfo { 503251662Sdimpublic: 504251662Sdim /// \brief The CapturedDecl for this statement. 505251662Sdim CapturedDecl *TheCapturedDecl; 506251662Sdim /// \brief The captured record type. 507251662Sdim RecordDecl *TheRecordDecl; 508251662Sdim /// \brief This is the enclosing scope of the captured region. 509251662Sdim Scope *TheScope; 510251662Sdim /// \brief The implicit parameter for the captured variables. 511251662Sdim ImplicitParamDecl *ContextParam; 512251662Sdim /// \brief The kind of captured region. 513251662Sdim CapturedRegionKind CapRegionKind; 514251662Sdim 515251662Sdim CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, 516251662Sdim RecordDecl *RD, ImplicitParamDecl *Context, 517251662Sdim CapturedRegionKind K) 518251662Sdim : CapturingScopeInfo(Diag, ImpCap_CapturedRegion), 519251662Sdim TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S), 520251662Sdim ContextParam(Context), CapRegionKind(K) 521251662Sdim { 522251662Sdim Kind = SK_CapturedRegion; 523251662Sdim } 524251662Sdim 525251662Sdim virtual ~CapturedRegionScopeInfo(); 526251662Sdim 527251662Sdim /// \brief A descriptive name for the kind of captured region this is. 528251662Sdim StringRef getRegionName() const { 529251662Sdim switch (CapRegionKind) { 530251662Sdim case CR_Default: 531251662Sdim return "default captured statement"; 532251662Sdim } 533251662Sdim llvm_unreachable("Invalid captured region kind!"); 534251662Sdim } 535251662Sdim 536251662Sdim static bool classof(const FunctionScopeInfo *FSI) { 537251662Sdim return FSI->Kind == SK_CapturedRegion; 538251662Sdim } 539251662Sdim}; 540251662Sdim 541234353Sdimclass LambdaScopeInfo : public CapturingScopeInfo { 542234353Sdimpublic: 543234353Sdim /// \brief The class that describes the lambda. 544234353Sdim CXXRecordDecl *Lambda; 545234353Sdim 546234353Sdim /// \brief The class that describes the lambda. 547234353Sdim CXXMethodDecl *CallOperator; 548234353Sdim 549234353Sdim /// \brief Source range covering the lambda introducer [...]. 550234353Sdim SourceRange IntroducerRange; 551234353Sdim 552234353Sdim /// \brief The number of captures in the \c Captures list that are 553234353Sdim /// explicit captures. 554234353Sdim unsigned NumExplicitCaptures; 555234353Sdim 556234353Sdim /// \brief Whether this is a mutable lambda. 557234353Sdim bool Mutable; 558234353Sdim 559234353Sdim /// \brief Whether the (empty) parameter list is explicit. 560234353Sdim bool ExplicitParams; 561234353Sdim 562234353Sdim /// \brief Whether any of the capture expressions requires cleanups. 563234353Sdim bool ExprNeedsCleanups; 564234353Sdim 565239462Sdim /// \brief Whether the lambda contains an unexpanded parameter pack. 566239462Sdim bool ContainsUnexpandedParameterPack; 567239462Sdim 568234353Sdim /// \brief Variables used to index into by-copy array captures. 569249423Sdim SmallVector<VarDecl *, 4> ArrayIndexVars; 570234353Sdim 571234353Sdim /// \brief Offsets into the ArrayIndexVars array at which each capture starts 572234353Sdim /// its list of array index variables. 573249423Sdim SmallVector<unsigned, 4> ArrayIndexStarts; 574234353Sdim 575234353Sdim LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda, 576234353Sdim CXXMethodDecl *CallOperator) 577234353Sdim : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda), 578234353Sdim CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false), 579239462Sdim ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false) 580234353Sdim { 581234353Sdim Kind = SK_Lambda; 582234353Sdim } 583234353Sdim 584234353Sdim virtual ~LambdaScopeInfo(); 585234353Sdim 586234353Sdim /// \brief Note when 587234353Sdim void finishedExplicitCaptures() { 588234353Sdim NumExplicitCaptures = Captures.size(); 589234353Sdim } 590243830Sdim 591243830Sdim static bool classof(const FunctionScopeInfo *FSI) { 592234353Sdim return FSI->Kind == SK_Lambda; 593234353Sdim } 594234353Sdim}; 595234353Sdim 596243830Sdim 597243830SdimFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy() 598243830Sdim : Base(0, false), Property(0) {} 599243830Sdim 600243830SdimFunctionScopeInfo::WeakObjectProfileTy 601243830SdimFunctionScopeInfo::WeakObjectProfileTy::getSentinel() { 602243830Sdim FunctionScopeInfo::WeakObjectProfileTy Result; 603243830Sdim Result.Base.setInt(true); 604243830Sdim return Result; 605212795Sdim} 606243830Sdim 607243830Sdimtemplate <typename ExprT> 608243830Sdimvoid FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) { 609243830Sdim assert(E); 610243830Sdim WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)]; 611243830Sdim Uses.push_back(WeakUseTy(E, IsRead)); 612212795Sdim} 613212795Sdim 614243830Sdiminline void 615243830SdimCapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc, 616243830Sdim QualType CaptureType, Expr *Cpy) { 617243830Sdim Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, 618243830Sdim Cpy)); 619243830Sdim CXXThisCaptureIndex = Captures.size(); 620243830Sdim 621243830Sdim if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this)) 622243830Sdim LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size()); 623243830Sdim} 624243830Sdim 625243830Sdim} // end namespace sema 626243830Sdim} // end namespace clang 627243830Sdim 628212795Sdim#endif 629