ScopeInfo.h revision f8af98286022f72157d84951b48fde5fb369ab29
1781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===// 2781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// 3781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// The LLVM Compiler Infrastructure 4781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// 5781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// This file is distributed under the University of Illinois Open Source 6781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// License. See LICENSE.TXT for details. 7781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// 8781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//===----------------------------------------------------------------------===// 9781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// 10781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// This file defines FunctionScopeInfo and BlockScopeInfo. 11781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// 12781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//===----------------------------------------------------------------------===// 13781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 14781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H 15781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#define LLVM_CLANG_SEMA_SCOPE_INFO_H 16781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 17781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "clang/AST/Type.h" 18351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Basic/PartialDiagnostic.h" 19781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/DenseMap.h" 20781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/SmallVector.h" 21781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 22781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace clang { 23781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 24781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass BlockDecl; 25f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass CXXMethodDecl; 26781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass IdentifierInfo; 27ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnerclass LabelDecl; 28781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass ReturnStmt; 29781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass Scope; 30781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass SwitchStmt; 31f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass VarDecl; 32781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 33781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace sema { 34781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 35351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekclass PossiblyUnreachableDiag { 36351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekpublic: 37351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek PartialDiagnostic PD; 38351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek SourceLocation Loc; 39351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek const Stmt *stmt; 40351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 41351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, 42351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek const Stmt *stmt) 43351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek : PD(PD), Loc(Loc), stmt(stmt) {} 44351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek}; 45351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 46781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a function, method, or block that is 47781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// currently being parsed. 48781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass FunctionScopeInfo { 49ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanprotected: 50ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman enum ScopeKind { 51ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman SK_Function, 52ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman SK_Block, 53ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman SK_Lambda 54ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman }; 55ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman 56781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic: 57ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// \brief What kind of scope we are describing. 58ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// 59ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman ScopeKind Kind; 60781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 61781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Whether this function contains a VLA, @try, try, C++ 62781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// initializer, or anything else that can't be jumped past. 63781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasBranchProtectedScope; 64781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 65781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Whether this function contains any switches or direct gotos. 66781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasBranchIntoScope; 67781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 68781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Whether this function contains any indirect gotos. 69781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasIndirectGoto; 70781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 718fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis /// \brief Used to determine if errors occurred in this function or block. 728fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis DiagnosticErrorTrap ErrorTrap; 73781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 74781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// SwitchStack - This is the current set of active switch statements in the 75781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// block. 76686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<SwitchStmt*, 8> SwitchStack; 77781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 78781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief The list of return statements that occur within the function or 79781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// block, if there is any chance of applying the named return value 80781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// optimization. 81686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<ReturnStmt*, 4> Returns; 82351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 83351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// \brief A list of PartialDiagnostics created but delayed within the 84351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// current function scope. These diagnostics are vetted for reachability 85351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// prior to being emitted. 86686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; 87781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 88781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasBranchIntoScope() { 89781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchIntoScope = true; 90781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 91781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 92781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasBranchProtectedScope() { 93781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchProtectedScope = true; 94781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 95781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 96781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasIndirectGoto() { 97781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasIndirectGoto = true; 98781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 99781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 100781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool NeedsScopeChecking() const { 101781472fe99a120098c631b0cbe33c89f8cef5e70John McCall return HasIndirectGoto || 102781472fe99a120098c631b0cbe33c89f8cef5e70John McCall (HasBranchProtectedScope && HasBranchIntoScope); 103781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 104781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 105d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie FunctionScopeInfo(DiagnosticsEngine &Diag) 106ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman : Kind(SK_Function), 107781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchProtectedScope(false), 108781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchIntoScope(false), 109781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasIndirectGoto(false), 1108fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis ErrorTrap(Diag) { } 111781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 112781472fe99a120098c631b0cbe33c89f8cef5e70John McCall virtual ~FunctionScopeInfo(); 113781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 114781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Clear out the information in this function scope, making it 115781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// suitable for reuse. 1168fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis void Clear(); 117781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 118781472fe99a120098c631b0cbe33c89f8cef5e70John McCall static bool classof(const FunctionScopeInfo *FSI) { return true; } 119781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}; 120781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 121b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass CapturingScopeInfo : public FunctionScopeInfo { 122b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanpublic: 123b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum ImplicitCaptureStyle { 124b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block 125b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 126b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 127b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman ImplicitCaptureStyle ImpCaptureStyle; 128b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 129b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman class Capture { 130b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // There are two categories of capture: capturing 'this', and capturing 131b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // local variables. There are three ways to capture a local variable: 132b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // capture by copy in the C++11 sense, capture by reference 133b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // in the C++11 sense, and __block capture. Lambdas explicitly specify 134b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // capture by copy or capture by reference. For blocks, __block capture 135b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // applies to variables with that annotation, variables of reference type 136b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // are captured by reference, and other variables are captured by copy. 137b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum CaptureKind { 138b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block 139b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 140b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 141b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // The variable being captured (if we are not capturing 'this'), 142b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // and misc bits descibing the capture. 143b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind; 144b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 145b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // Expression to initialize a field of the given type, and whether this 146b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // is a nested capture; the expression is only required if we are 147b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // capturing ByVal and the variable's type has a non-trivial 148b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // copy constructor. 149b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested; 150b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 15193962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor /// \brief The source location at which the first capture occurred.. 15293962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor SourceLocation Loc; 15393962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor 154b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman public: 155b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman Capture(VarDecl *Var, bool block, bool byRef, bool isNested, 156b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman SourceLocation Loc, Expr *Cpy) 157b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy), 158b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman CopyExprAndNested(Cpy, isNested) {} 159b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 160b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum IsThisCapture { ThisCapture }; 161668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedman Capture(IsThisCapture, bool isNested, SourceLocation Loc, Expr *Cpy) 162668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedman : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc) { 163b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 164b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 165b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; } 166b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isVariableCapture() const { return !isThisCapture(); } 167b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; } 168b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; } 169b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; } 170b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isNested() { return CopyExprAndNested.getInt(); } 171b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 172b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman VarDecl *getVariable() const { 173b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman return VarAndKind.getPointer(); 174b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 17593962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor 17693962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor /// \brief Retrieve the location at which this variable was captured. 17793962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor SourceLocation getLocation() const { return Loc; } 17893962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor 179b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman Expr *getCopyExpr() const { 180b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman return CopyExprAndNested.getPointer(); 181b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 182b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 183b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 184b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style) 18584b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0), 18684b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman HasImplicitReturnType(false) 187b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman {} 188b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 189b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// CaptureMap - A map of captured variables to (index+1) into Captures. 190b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman llvm::DenseMap<VarDecl*, unsigned> CaptureMap; 191b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 192b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// CXXThisCaptureIndex - The (index+1) of the capture of 'this'; 193b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// zero if 'this' is not captured. 194b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman unsigned CXXThisCaptureIndex; 195b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 196b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// Captures - The captures. 197b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman SmallVector<Capture, 4> Captures; 198b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 19984b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// \brief - Whether the target type of return statements in this context 20084b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// is deduced (e.g. a lambda or block with omitted return type). 20184b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman bool HasImplicitReturnType; 20284b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman 20384b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// ReturnType - The target type of return statements in this context, 20484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// or null if unknown. 20584b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman QualType ReturnType; 20684b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman 207b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman void AddCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, 208b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman SourceLocation Loc, Expr *Cpy) { 209b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, Cpy)); 210b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman CaptureMap[Var] = Captures.size(); 211b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 212b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 213668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedman void AddThisCapture(bool isNested, SourceLocation Loc, Expr *Cpy) { 214668165ab1e604b063c0aa0df8ff91c80879670bfEli Friedman Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, Cpy)); 215b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman CXXThisCaptureIndex = Captures.size(); 216b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 217b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 218a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Determine whether the C++ 'this' is captured. 219a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } 220a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 221a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Retrieve the capture of C++ 'this', if it has been captured. 222a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor Capture &getCXXThisCapture() { 223a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(isCXXThisCaptured() && "this has not been captured"); 224a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[CXXThisCaptureIndex - 1]; 225a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 226a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 227a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Determine whether the given variable has been captured. 228a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor bool isCaptured(VarDecl *Var) const { 229b11a7fd2f2204c7aadd74f870c98667d461997f5Aaron Ballman return CaptureMap.count(Var); 230a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 231a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 232a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Retrieve the capture of the given variable, if it has been 233a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// captured already. 234a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor Capture &getCapture(VarDecl *Var) { 235a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(isCaptured(Var) && "Variable has not been captured"); 236a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[CaptureMap[Var] - 1]; 237a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 238a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 239a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor const Capture &getCapture(VarDecl *Var) const { 240a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known 241a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor = CaptureMap.find(Var); 242a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(Known != CaptureMap.end() && "Variable has not been captured"); 243a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[Known->second - 1]; 244a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 245a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 246b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman static bool classof(const FunctionScopeInfo *FSI) { 247b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda; 248b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 249b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman static bool classof(const CapturingScopeInfo *BSI) { return true; } 250b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman}; 251b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 252781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a block that is currently being parsed. 253b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass BlockScopeInfo : public CapturingScopeInfo { 254781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic: 255781472fe99a120098c631b0cbe33c89f8cef5e70John McCall BlockDecl *TheDecl; 256781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 257781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// TheScope - This is the scope for the block itself, which contains 258781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// arguments etc. 259781472fe99a120098c631b0cbe33c89f8cef5e70John McCall Scope *TheScope; 260781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 261781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// BlockType - The function type of the block, if one was given. 262781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// Its return type may be BuiltinType::Dependent. 263781472fe99a120098c631b0cbe33c89f8cef5e70John McCall QualType FunctionType; 264781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 265d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) 266b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block), 267b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman TheScope(BlockScope) 268781472fe99a120098c631b0cbe33c89f8cef5e70John McCall { 269ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman Kind = SK_Block; 270781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 271781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 272781472fe99a120098c631b0cbe33c89f8cef5e70John McCall virtual ~BlockScopeInfo(); 273781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 274ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman static bool classof(const FunctionScopeInfo *FSI) { 275ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman return FSI->Kind == SK_Block; 276ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 277781472fe99a120098c631b0cbe33c89f8cef5e70John McCall static bool classof(const BlockScopeInfo *BSI) { return true; } 278781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}; 279781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 280b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass LambdaScopeInfo : public CapturingScopeInfo { 281ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanpublic: 282ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// \brief The class that describes the lambda. 283ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman CXXRecordDecl *Lambda; 28401d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 28576e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor /// \brief The class that describes the lambda. 28676e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor CXXMethodDecl *CallOperator; 28776e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor 28801d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor /// \brief Source range covering the lambda introducer [...]. 28901d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor SourceRange IntroducerRange; 29001d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 291ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// \brief The number of captures in the \c Captures list that are 292ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// explicit captures. 293ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman unsigned NumExplicitCaptures; 29472899c34e3d1abfffa241ad0ce5c4bf175e5ea51Eli Friedman 295503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor /// \brief Whether this is a mutable lambda. 296d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman bool Mutable; 29701d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 29801d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor /// \brief Whether the (empty) parameter list is explicit. 29901d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor bool ExplicitParams; 300d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman 301503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor /// \brief Whether any of the capture expressions requires cleanups. 302503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor bool ExprNeedsCleanups; 303503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor 30476e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda, 30576e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor CXXMethodDecl *CallOperator) 306b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda), 307503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false), 308503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor ExprNeedsCleanups(false) 309ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman { 310ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman Kind = SK_Lambda; 311ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 312b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 313ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman virtual ~LambdaScopeInfo(); 314b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 315a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Note when 316a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor void finishedExplicitCaptures() { 317a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor NumExplicitCaptures = Captures.size(); 318a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 319a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 320ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman static bool classof(const FunctionScopeInfo *FSI) { 321ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman return FSI->Kind == SK_Lambda; 322ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 323ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman static bool classof(const LambdaScopeInfo *BSI) { return true; } 324ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman 325ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman}; 326ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman 327781472fe99a120098c631b0cbe33c89f8cef5e70John McCall} 328781472fe99a120098c631b0cbe33c89f8cef5e70John McCall} 329781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 330781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#endif 331