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 35625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// \brief Contains information about the compound statement currently being 36625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// parsed. 37625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkoclass CompoundScopeInfo { 38625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkopublic: 39625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko CompoundScopeInfo() 40625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko : HasEmptyLoopBodies(false) { } 41625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 42625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// \brief Whether this compound stamement contains `for' or `while' loops 43625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// with empty bodies. 44625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko bool HasEmptyLoopBodies; 45625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 46625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko void setHasEmptyLoopBodies() { 47625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko HasEmptyLoopBodies = true; 48625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko } 49625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko}; 50625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 51351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekclass PossiblyUnreachableDiag { 52351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekpublic: 53351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek PartialDiagnostic PD; 54351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek SourceLocation Loc; 55351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek const Stmt *stmt; 56351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 57351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, 58351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek const Stmt *stmt) 59351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek : PD(PD), Loc(Loc), stmt(stmt) {} 60351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek}; 61351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 62781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a function, method, or block that is 63781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// currently being parsed. 64781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass FunctionScopeInfo { 65ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanprotected: 66ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman enum ScopeKind { 67ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman SK_Function, 68ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman SK_Block, 69ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman SK_Lambda 70ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman }; 71ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman 72781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic: 73ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// \brief What kind of scope we are describing. 74ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// 75ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman ScopeKind Kind; 76781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 77809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett /// \brief Whether this function contains a VLA, \@try, try, C++ 78781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// initializer, or anything else that can't be jumped past. 79781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasBranchProtectedScope; 80781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 81781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Whether this function contains any switches or direct gotos. 82781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasBranchIntoScope; 83781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 84781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Whether this function contains any indirect gotos. 85781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasIndirectGoto; 86781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 8795aac15936e8362aeb4813f95bc255dee6473592Eli Friedman /// A flag that is set when parsing a -dealloc method and no [super dealloc] 8895aac15936e8362aeb4813f95bc255dee6473592Eli Friedman /// call was found yet. 8995aac15936e8362aeb4813f95bc255dee6473592Eli Friedman bool ObjCShouldCallSuperDealloc; 9095aac15936e8362aeb4813f95bc255dee6473592Eli Friedman 9195aac15936e8362aeb4813f95bc255dee6473592Eli Friedman /// A flag that is set when parsing a -finalize method and no [super finalize] 9295aac15936e8362aeb4813f95bc255dee6473592Eli Friedman /// call was found yet. 9395aac15936e8362aeb4813f95bc255dee6473592Eli Friedman bool ObjCShouldCallSuperFinalize; 9495aac15936e8362aeb4813f95bc255dee6473592Eli Friedman 958fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis /// \brief Used to determine if errors occurred in this function or block. 968fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis DiagnosticErrorTrap ErrorTrap; 97781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 98781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// SwitchStack - This is the current set of active switch statements in the 99781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// block. 100686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<SwitchStmt*, 8> SwitchStack; 101781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 102781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief The list of return statements that occur within the function or 103781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// block, if there is any chance of applying the named return value 1047dd900ed308506f9cf1cb72c70db1652f94cab37Jordan Rose /// optimization, or if we need to infer a return type. 105686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<ReturnStmt*, 4> Returns; 106625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 107625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// \brief The stack of currently active compound stamement scopes in the 108625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// function. 109625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko SmallVector<CompoundScopeInfo, 4> CompoundScopes; 110625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 111351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// \brief A list of PartialDiagnostics created but delayed within the 112351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// current function scope. These diagnostics are vetted for reachability 113351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// prior to being emitted. 114686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; 115781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 116781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasBranchIntoScope() { 117781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchIntoScope = true; 118781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 119781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 120781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasBranchProtectedScope() { 121781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchProtectedScope = true; 122781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 123781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 124781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasIndirectGoto() { 125781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasIndirectGoto = true; 126781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 127781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 128781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool NeedsScopeChecking() const { 129781472fe99a120098c631b0cbe33c89f8cef5e70John McCall return HasIndirectGoto || 130781472fe99a120098c631b0cbe33c89f8cef5e70John McCall (HasBranchProtectedScope && HasBranchIntoScope); 131781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 132781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 133d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie FunctionScopeInfo(DiagnosticsEngine &Diag) 134ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman : Kind(SK_Function), 135781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchProtectedScope(false), 136781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchIntoScope(false), 137781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasIndirectGoto(false), 13895aac15936e8362aeb4813f95bc255dee6473592Eli Friedman ObjCShouldCallSuperDealloc(false), 13995aac15936e8362aeb4813f95bc255dee6473592Eli Friedman ObjCShouldCallSuperFinalize(false), 1408fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis ErrorTrap(Diag) { } 141781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 142781472fe99a120098c631b0cbe33c89f8cef5e70John McCall virtual ~FunctionScopeInfo(); 143781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 144781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Clear out the information in this function scope, making it 145781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// suitable for reuse. 1468fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis void Clear(); 147781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 148781472fe99a120098c631b0cbe33c89f8cef5e70John McCall static bool classof(const FunctionScopeInfo *FSI) { return true; } 149781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}; 150781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 151b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass CapturingScopeInfo : public FunctionScopeInfo { 152b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanpublic: 153b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum ImplicitCaptureStyle { 154b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block 155b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 156b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 157b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman ImplicitCaptureStyle ImpCaptureStyle; 158b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 159b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman class Capture { 160b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // There are two categories of capture: capturing 'this', and capturing 161b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // local variables. There are three ways to capture a local variable: 162b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // capture by copy in the C++11 sense, capture by reference 163b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // in the C++11 sense, and __block capture. Lambdas explicitly specify 164b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // capture by copy or capture by reference. For blocks, __block capture 165b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // applies to variables with that annotation, variables of reference type 166b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // are captured by reference, and other variables are captured by copy. 167b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum CaptureKind { 168b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block 169b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 170b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 171b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // The variable being captured (if we are not capturing 'this'), 172b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // and misc bits descibing the capture. 173b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind; 174b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 175b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // Expression to initialize a field of the given type, and whether this 176b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // is a nested capture; the expression is only required if we are 177b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // capturing ByVal and the variable's type has a non-trivial 178b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // copy constructor. 179b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested; 180b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 18193962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor /// \brief The source location at which the first capture occurred.. 18293962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor SourceLocation Loc; 18393962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor 184a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor /// \brief The location of the ellipsis that expands a parameter pack. 185a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor SourceLocation EllipsisLoc; 186a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor 187999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// \brief The type as it was captured, which is in effect the type of the 188999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// non-static data member that would hold the capture. 189999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType; 190999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor 191b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman public: 192b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman Capture(VarDecl *Var, bool block, bool byRef, bool isNested, 193999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor SourceLocation Loc, SourceLocation EllipsisLoc, 194999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType, Expr *Cpy) 195b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy), 196999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc), 197999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor CaptureType(CaptureType){} 198b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 199b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum IsThisCapture { ThisCapture }; 200999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor Capture(IsThisCapture, bool isNested, SourceLocation Loc, 201999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType, Expr *Cpy) 202a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc), 203999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor EllipsisLoc(), CaptureType(CaptureType) { } 204b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 205b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; } 206b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isVariableCapture() const { return !isThisCapture(); } 207b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; } 208b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; } 209b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; } 210b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isNested() { return CopyExprAndNested.getInt(); } 211b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 212b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman VarDecl *getVariable() const { 213b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman return VarAndKind.getPointer(); 214b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 21593962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor 21693962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor /// \brief Retrieve the location at which this variable was captured. 21793962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor SourceLocation getLocation() const { return Loc; } 21893962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor 219a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor /// \brief Retrieve the source location of the ellipsis, whose presence 220a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor /// indicates that the capture is a pack expansion. 221a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 222a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor 223999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// \brief Retrieve the capture type for this capture, which is effectively 224999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// the type of the non-static data member in the lambda/block structure 225999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// that would store this capture. 226999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType getCaptureType() const { return CaptureType; } 227999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor 228b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman Expr *getCopyExpr() const { 229b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman return CopyExprAndNested.getPointer(); 230b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 231b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 232b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 233b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style) 23484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0), 23584b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman HasImplicitReturnType(false) 236b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman {} 237b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 238b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// CaptureMap - A map of captured variables to (index+1) into Captures. 239b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman llvm::DenseMap<VarDecl*, unsigned> CaptureMap; 240b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 241b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// CXXThisCaptureIndex - The (index+1) of the capture of 'this'; 242b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// zero if 'this' is not captured. 243b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman unsigned CXXThisCaptureIndex; 244b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 245b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// Captures - The captures. 246b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman SmallVector<Capture, 4> Captures; 247b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 24884b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// \brief - Whether the target type of return statements in this context 24984b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// is deduced (e.g. a lambda or block with omitted return type). 25084b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman bool HasImplicitReturnType; 25184b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman 25284b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// ReturnType - The target type of return statements in this context, 25384b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// or null if unknown. 25484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman QualType ReturnType; 25584b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman 256999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, 257999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor SourceLocation Loc, SourceLocation EllipsisLoc, 258999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType, Expr *Cpy) { 259a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, 260999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor EllipsisLoc, CaptureType, Cpy)); 261b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman CaptureMap[Var] = Captures.size(); 262b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 263b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 264999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, 265999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor Expr *Cpy) { 266999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, 267999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor Cpy)); 268b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman CXXThisCaptureIndex = Captures.size(); 269b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 270b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 271a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Determine whether the C++ 'this' is captured. 272a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } 273a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 274a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Retrieve the capture of C++ 'this', if it has been captured. 275a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor Capture &getCXXThisCapture() { 276a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(isCXXThisCaptured() && "this has not been captured"); 277a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[CXXThisCaptureIndex - 1]; 278a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 279a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 280a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Determine whether the given variable has been captured. 281a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor bool isCaptured(VarDecl *Var) const { 282b11a7fd2f2204c7aadd74f870c98667d461997f5Aaron Ballman return CaptureMap.count(Var); 283a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 284a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 285a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Retrieve the capture of the given variable, if it has been 286a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// captured already. 287a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor Capture &getCapture(VarDecl *Var) { 288a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(isCaptured(Var) && "Variable has not been captured"); 289a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[CaptureMap[Var] - 1]; 290a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 291a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 292a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor const Capture &getCapture(VarDecl *Var) const { 293a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known 294a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor = CaptureMap.find(Var); 295a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(Known != CaptureMap.end() && "Variable has not been captured"); 296a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[Known->second - 1]; 297a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 298a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 299b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman static bool classof(const FunctionScopeInfo *FSI) { 300b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda; 301b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 302b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman static bool classof(const CapturingScopeInfo *BSI) { return true; } 303b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman}; 304b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 305781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a block that is currently being parsed. 306b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass BlockScopeInfo : public CapturingScopeInfo { 307781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic: 308781472fe99a120098c631b0cbe33c89f8cef5e70John McCall BlockDecl *TheDecl; 309781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 310781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// TheScope - This is the scope for the block itself, which contains 311781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// arguments etc. 312781472fe99a120098c631b0cbe33c89f8cef5e70John McCall Scope *TheScope; 313781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 314781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// BlockType - The function type of the block, if one was given. 315781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// Its return type may be BuiltinType::Dependent. 316781472fe99a120098c631b0cbe33c89f8cef5e70John McCall QualType FunctionType; 317781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 318d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) 319b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block), 320b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman TheScope(BlockScope) 321781472fe99a120098c631b0cbe33c89f8cef5e70John McCall { 322ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman Kind = SK_Block; 323781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 324781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 325781472fe99a120098c631b0cbe33c89f8cef5e70John McCall virtual ~BlockScopeInfo(); 326781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 327ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman static bool classof(const FunctionScopeInfo *FSI) { 328ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman return FSI->Kind == SK_Block; 329ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 330781472fe99a120098c631b0cbe33c89f8cef5e70John McCall static bool classof(const BlockScopeInfo *BSI) { return true; } 331781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}; 332781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 333b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass LambdaScopeInfo : public CapturingScopeInfo { 334ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanpublic: 335ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// \brief The class that describes the lambda. 336ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman CXXRecordDecl *Lambda; 33701d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 33876e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor /// \brief The class that describes the lambda. 33976e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor CXXMethodDecl *CallOperator; 34076e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor 34101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor /// \brief Source range covering the lambda introducer [...]. 34201d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor SourceRange IntroducerRange; 34301d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 344ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// \brief The number of captures in the \c Captures list that are 345ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// explicit captures. 346ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman unsigned NumExplicitCaptures; 34772899c34e3d1abfffa241ad0ce5c4bf175e5ea51Eli Friedman 348503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor /// \brief Whether this is a mutable lambda. 349d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman bool Mutable; 35001d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 35101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor /// \brief Whether the (empty) parameter list is explicit. 35201d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor bool ExplicitParams; 353d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman 354503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor /// \brief Whether any of the capture expressions requires cleanups. 355503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor bool ExprNeedsCleanups; 356503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor 357612409ece080e814f79e06772c690d603f45fbd6Richard Smith /// \brief Whether the lambda contains an unexpanded parameter pack. 358612409ece080e814f79e06772c690d603f45fbd6Richard Smith bool ContainsUnexpandedParameterPack; 359612409ece080e814f79e06772c690d603f45fbd6Richard Smith 3609daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor /// \brief Variables used to index into by-copy array captures. 3619daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor llvm::SmallVector<VarDecl *, 4> ArrayIndexVars; 3629daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor 3639daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor /// \brief Offsets into the ArrayIndexVars array at which each capture starts 3649daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor /// its list of array index variables. 3659daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor llvm::SmallVector<unsigned, 4> ArrayIndexStarts; 3669daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor 36776e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda, 36876e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor CXXMethodDecl *CallOperator) 369b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda), 370503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false), 371612409ece080e814f79e06772c690d603f45fbd6Richard Smith ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false) 372ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman { 373ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman Kind = SK_Lambda; 374ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 375b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 376ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman virtual ~LambdaScopeInfo(); 377b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 378a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Note when 379a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor void finishedExplicitCaptures() { 380a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor NumExplicitCaptures = Captures.size(); 381a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 382a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 383ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman static bool classof(const FunctionScopeInfo *FSI) { 384ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman return FSI->Kind == SK_Lambda; 385ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 386ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman static bool classof(const LambdaScopeInfo *BSI) { return true; } 387ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman 388ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman}; 389ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman 390781472fe99a120098c631b0cbe33c89f8cef5e70John McCall} 391781472fe99a120098c631b0cbe33c89f8cef5e70John McCall} 392781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 393781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#endif 394