ScopeInfo.h revision c0e44454bd78b8b4f3d70f08cf1edd5466b0c798
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// 10a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// This file defines FunctionScopeInfo and its subclasses, which contain 11a55d32d1b8f799bf58c02540983976368c42d895Jordan Rose// information about a single function, block, lambda, or method body. 12781472fe99a120098c631b0cbe33c89f8cef5e70John McCall// 13781472fe99a120098c631b0cbe33c89f8cef5e70John McCall//===----------------------------------------------------------------------===// 14781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 15781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#ifndef LLVM_CLANG_SEMA_SCOPE_INFO_H 16781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#define LLVM_CLANG_SEMA_SCOPE_INFO_H 17781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 18781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "clang/AST/Type.h" 19351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Basic/PartialDiagnostic.h" 20781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/DenseMap.h" 21781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/SmallVector.h" 22781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 23781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace clang { 24781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 2558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseclass Decl; 26781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass BlockDecl; 27f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass CXXMethodDecl; 287fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Roseclass ObjCPropertyDecl; 29781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass IdentifierInfo; 30ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnerclass LabelDecl; 31781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass ReturnStmt; 32781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass Scope; 33781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass SwitchStmt; 34f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass VarDecl; 357a2704800943fbb69207e125d28186278712af36Jordan Roseclass DeclRefExpr; 367a2704800943fbb69207e125d28186278712af36Jordan Roseclass ObjCIvarRefExpr; 3758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseclass ObjCPropertyRefExpr; 387fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Roseclass ObjCMessageExpr; 39781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 40781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace sema { 41781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 42625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// \brief Contains information about the compound statement currently being 43625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// parsed. 44625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkoclass CompoundScopeInfo { 45625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkopublic: 46625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko CompoundScopeInfo() 47625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko : HasEmptyLoopBodies(false) { } 48625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 49625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// \brief Whether this compound stamement contains `for' or `while' loops 50625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// with empty bodies. 51625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko bool HasEmptyLoopBodies; 52625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 53625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko void setHasEmptyLoopBodies() { 54625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko HasEmptyLoopBodies = true; 55625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko } 56625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko}; 57625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 58351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekclass PossiblyUnreachableDiag { 59351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekpublic: 60351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek PartialDiagnostic PD; 61351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek SourceLocation Loc; 62351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek const Stmt *stmt; 63351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 64351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, 65351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek const Stmt *stmt) 66351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek : PD(PD), Loc(Loc), stmt(stmt) {} 67351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek}; 68351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 69781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a function, method, or block that is 70781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// currently being parsed. 71781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass FunctionScopeInfo { 72ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanprotected: 73ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman enum ScopeKind { 74ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman SK_Function, 75ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman SK_Block, 76ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman SK_Lambda 77ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman }; 78ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman 79781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic: 80ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// \brief What kind of scope we are describing. 81ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// 82ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman ScopeKind Kind; 83781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 84809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett /// \brief Whether this function contains a VLA, \@try, try, C++ 85781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// initializer, or anything else that can't be jumped past. 86781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasBranchProtectedScope; 87781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 88781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Whether this function contains any switches or direct gotos. 89781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasBranchIntoScope; 90781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 91781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Whether this function contains any indirect gotos. 92781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasIndirectGoto; 93781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 94535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose /// A flag that is set when parsing a method that must call super's 95535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose /// implementation, such as \c -dealloc, \c -finalize, or any method marked 96535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose /// with \c __attribute__((objc_requires_super)). 97535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose bool ObjCShouldCallSuper; 9895aac15936e8362aeb4813f95bc255dee6473592Eli Friedman 998fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis /// \brief Used to determine if errors occurred in this function or block. 1008fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis DiagnosticErrorTrap ErrorTrap; 101781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 102781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// SwitchStack - This is the current set of active switch statements in the 103781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// block. 104686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<SwitchStmt*, 8> SwitchStack; 105781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 106781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief The list of return statements that occur within the function or 107781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// block, if there is any chance of applying the named return value 1087dd900ed308506f9cf1cb72c70db1652f94cab37Jordan Rose /// optimization, or if we need to infer a return type. 109686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<ReturnStmt*, 4> Returns; 110625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 111625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// \brief The stack of currently active compound stamement scopes in the 112625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// function. 113625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko SmallVector<CompoundScopeInfo, 4> CompoundScopes; 114625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 115351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// \brief A list of PartialDiagnostics created but delayed within the 116351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// current function scope. These diagnostics are vetted for reachability 117351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// prior to being emitted. 118686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; 119781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 12058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosepublic: 12158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Represents a simple identification of a weak object. 12258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 12358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 12458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 12558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// This is used to determine if two weak accesses refer to the same object. 12658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Here are some examples of how various accesses are "profiled": 12758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 12858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Access Expression | "Base" Decl | "Property" Decl 12958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// :---------------: | :-----------------: | :------------------------------: 13058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// self.property | self (VarDecl) | property (ObjCPropertyDecl) 13158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl) 13258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl) 13358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl) 13458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl) 13558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl) 13658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl) 1377a2704800943fbb69207e125d28186278712af36Jordan Rose /// weakVar | 0 (known) | weakVar (VarDecl) 1387a2704800943fbb69207e125d28186278712af36Jordan Rose /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl) 13958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 14058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Objects are identified with only two Decls to make it reasonably fast to 14158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// compare them. 14258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose class WeakObjectProfileTy { 14358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// The base object decl, as described in the class documentation. 14458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 14558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// The extra flag is "true" if the Base and Property are enough to uniquely 14658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// identify the object in memory. 14758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 14858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// \sa isExactProfile() 14958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy; 15058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose BaseInfoTy Base; 15158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 15258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// The "property" decl, as described in the class documentation. 15358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 15458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the 15558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// case of "implicit" properties (regular methods accessed via dot syntax). 15658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const NamedDecl *Property; 15758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 1587a2704800943fbb69207e125d28186278712af36Jordan Rose /// Used to find the proper base profile for a given base expression. 1597a2704800943fbb69207e125d28186278712af36Jordan Rose static BaseInfoTy getBaseInfo(const Expr *BaseE); 1607a2704800943fbb69207e125d28186278712af36Jordan Rose 16158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // For use in DenseMap. 162b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose friend class DenseMapInfo; 16358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose inline WeakObjectProfileTy(); 16458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose static inline WeakObjectProfileTy getSentinel(); 16558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 16658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose public: 16758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose WeakObjectProfileTy(const ObjCPropertyRefExpr *RE); 1687fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property); 1697a2704800943fbb69207e125d28186278712af36Jordan Rose WeakObjectProfileTy(const DeclRefExpr *RE); 1707a2704800943fbb69207e125d28186278712af36Jordan Rose WeakObjectProfileTy(const ObjCIvarRefExpr *RE); 17158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 172c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose const NamedDecl *getBase() const { return Base.getPointer(); } 17358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const NamedDecl *getProperty() const { return Property; } 17458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 17558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Returns true if the object base specifies a known object in memory, 17658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// rather than, say, an instance variable or property of another object. 17758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 17858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Note that this ignores the effects of aliasing; that is, \c foo.bar is 17958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// considered an exact profile if \c foo is a local variable, even if 18058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// another variable \c foo2 refers to the same object as \c foo. 18158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 18258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// For increased precision, accesses with base variables that are 18358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to 18458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// be exact, though this is not true for arbitrary variables 18558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// (foo.prop1.prop2). 18658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose bool isExactProfile() const { 18758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return Base.getInt(); 18858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 18958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 19058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose bool operator==(const WeakObjectProfileTy &Other) const { 19158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return Base == Other.Base && Property == Other.Property; 19258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 193b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose 194b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose // For use in DenseMap. 195b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose // We can't specialize the usual llvm::DenseMapInfo at the end of the file 196b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose // because by that point the DenseMap in FunctionScopeInfo has already been 197b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose // instantiated. 198b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose class DenseMapInfo { 199b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose public: 200b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose static inline WeakObjectProfileTy getEmptyKey() { 201b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose return WeakObjectProfileTy(); 202b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose } 203b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose static inline WeakObjectProfileTy getTombstoneKey() { 204b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose return WeakObjectProfileTy::getSentinel(); 205b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose } 206b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose 207b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose static unsigned getHashValue(const WeakObjectProfileTy &Val) { 208b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose typedef std::pair<BaseInfoTy, const NamedDecl *> Pair; 209b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base, 210b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose Val.Property)); 211b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose } 212b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose 213b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose static bool isEqual(const WeakObjectProfileTy &LHS, 214b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose const WeakObjectProfileTy &RHS) { 215b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose return LHS == RHS; 216b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose } 217b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose }; 21858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose }; 21958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 22058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Represents a single use of a weak object. 22158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 22258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Stores both the expression and whether the access is potentially unsafe 22358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// (i.e. it could potentially be warned about). 22458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 22558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 22658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose class WeakUseTy { 22758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose llvm::PointerIntPair<const Expr *, 1, bool> Rep; 22858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose public: 22958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {} 23058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 23158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const Expr *getUseExpr() const { return Rep.getPointer(); } 23258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose bool isUnsafe() const { return Rep.getInt(); } 23358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose void markSafe() { Rep.setInt(false); } 23458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 23558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose bool operator==(const WeakUseTy &Other) const { 23658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return Rep == Other.Rep; 23758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 23858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose }; 23958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 24058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Used to collect uses of a particular weak object in a function body. 24158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 24258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 24358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose typedef SmallVector<WeakUseTy, 4> WeakUseVector; 24458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 24558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Used to collect all uses of weak objects in a function body. 24658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 24758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 248b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8, 249b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose WeakObjectProfileTy::DenseMapInfo> 25058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose WeakObjectUseMap; 25158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 25258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseprivate: 25358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Used to collect all uses of weak objects in this function body. 25458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 25558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 25658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose WeakObjectUseMap WeakObjectUses; 25758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 25858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosepublic: 2597a2704800943fbb69207e125d28186278712af36Jordan Rose /// Record that a weak object was accessed. 26058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 26158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 2627a2704800943fbb69207e125d28186278712af36Jordan Rose template <typename ExprT> 2637a2704800943fbb69207e125d28186278712af36Jordan Rose inline void recordUseOfWeak(const ExprT *E, bool IsRead = true); 26458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 2657fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose void recordUseOfWeak(const ObjCMessageExpr *Msg, 2667fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose const ObjCPropertyDecl *Prop); 2677fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose 26858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Record that a given expression is a "safe" access of a weak object (e.g. 26958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// assigning it to a strong variable.) 27058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 27158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 27258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose void markSafeWeakUse(const Expr *E); 27358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 27458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const WeakObjectUseMap &getWeakObjectUses() const { 27558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return WeakObjectUses; 27658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 27758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 278781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasBranchIntoScope() { 279781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchIntoScope = true; 280781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 281781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 282781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasBranchProtectedScope() { 283781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchProtectedScope = true; 284781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 285781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 286781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasIndirectGoto() { 287781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasIndirectGoto = true; 288781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 289781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 290781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool NeedsScopeChecking() const { 291781472fe99a120098c631b0cbe33c89f8cef5e70John McCall return HasIndirectGoto || 292781472fe99a120098c631b0cbe33c89f8cef5e70John McCall (HasBranchProtectedScope && HasBranchIntoScope); 293781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 294781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 295d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie FunctionScopeInfo(DiagnosticsEngine &Diag) 296ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman : Kind(SK_Function), 297781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchProtectedScope(false), 298781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchIntoScope(false), 299781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasIndirectGoto(false), 300535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose ObjCShouldCallSuper(false), 3018fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis ErrorTrap(Diag) { } 302781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 303781472fe99a120098c631b0cbe33c89f8cef5e70John McCall virtual ~FunctionScopeInfo(); 304781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 305781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Clear out the information in this function scope, making it 306781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// suitable for reuse. 3078fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis void Clear(); 308781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}; 309781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 310b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass CapturingScopeInfo : public FunctionScopeInfo { 311b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanpublic: 312b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum ImplicitCaptureStyle { 313b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block 314b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 315b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 316b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman ImplicitCaptureStyle ImpCaptureStyle; 317b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 318b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman class Capture { 319b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // There are two categories of capture: capturing 'this', and capturing 320b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // local variables. There are three ways to capture a local variable: 321b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // capture by copy in the C++11 sense, capture by reference 322b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // in the C++11 sense, and __block capture. Lambdas explicitly specify 323b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // capture by copy or capture by reference. For blocks, __block capture 324b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // applies to variables with that annotation, variables of reference type 325b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman // are captured by reference, and other variables are captured by copy. 326b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum CaptureKind { 327b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman Cap_This, Cap_ByCopy, Cap_ByRef, Cap_Block 328b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 329b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 330b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // The variable being captured (if we are not capturing 'this'), 331b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // and misc bits descibing the capture. 332b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman llvm::PointerIntPair<VarDecl*, 2, CaptureKind> VarAndKind; 333b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 334b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // Expression to initialize a field of the given type, and whether this 335b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // is a nested capture; the expression is only required if we are 336b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // capturing ByVal and the variable's type has a non-trivial 337b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman // copy constructor. 338b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman llvm::PointerIntPair<Expr*, 1, bool> CopyExprAndNested; 339b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 34093962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor /// \brief The source location at which the first capture occurred.. 34193962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor SourceLocation Loc; 34293962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor 343a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor /// \brief The location of the ellipsis that expands a parameter pack. 344a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor SourceLocation EllipsisLoc; 345a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor 346999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// \brief The type as it was captured, which is in effect the type of the 347999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// non-static data member that would hold the capture. 348999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType; 349999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor 350b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman public: 351b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman Capture(VarDecl *Var, bool block, bool byRef, bool isNested, 352999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor SourceLocation Loc, SourceLocation EllipsisLoc, 353999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType, Expr *Cpy) 354b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman : VarAndKind(Var, block ? Cap_Block : byRef ? Cap_ByRef : Cap_ByCopy), 355999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor CopyExprAndNested(Cpy, isNested), Loc(Loc), EllipsisLoc(EllipsisLoc), 356999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor CaptureType(CaptureType){} 357b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 358b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum IsThisCapture { ThisCapture }; 359999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor Capture(IsThisCapture, bool isNested, SourceLocation Loc, 360999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType, Expr *Cpy) 361a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor : VarAndKind(0, Cap_This), CopyExprAndNested(Cpy, isNested), Loc(Loc), 362999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor EllipsisLoc(), CaptureType(CaptureType) { } 363b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 364b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isThisCapture() const { return VarAndKind.getInt() == Cap_This; } 365b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isVariableCapture() const { return !isThisCapture(); } 366b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman bool isCopyCapture() const { return VarAndKind.getInt() == Cap_ByCopy; } 367b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isReferenceCapture() const { return VarAndKind.getInt() == Cap_ByRef; } 368b942cb24a060435b18fef5b43eb33d77afc0d03aEli Friedman bool isBlockCapture() const { return VarAndKind.getInt() == Cap_Block; } 369b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman bool isNested() { return CopyExprAndNested.getInt(); } 370b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 371b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman VarDecl *getVariable() const { 372b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman return VarAndKind.getPointer(); 373b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 37493962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor 37593962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor /// \brief Retrieve the location at which this variable was captured. 37693962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor SourceLocation getLocation() const { return Loc; } 37793962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor 378a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor /// \brief Retrieve the source location of the ellipsis, whose presence 379a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor /// indicates that the capture is a pack expansion. 380a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 381a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor 382999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// \brief Retrieve the capture type for this capture, which is effectively 383999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// the type of the non-static data member in the lambda/block structure 384999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// that would store this capture. 385999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType getCaptureType() const { return CaptureType; } 386999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor 387b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman Expr *getCopyExpr() const { 388b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman return CopyExprAndNested.getPointer(); 389b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 390b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 391b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 392b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style) 39384b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0), 39484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman HasImplicitReturnType(false) 395b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman {} 396b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 397b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// CaptureMap - A map of captured variables to (index+1) into Captures. 398b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman llvm::DenseMap<VarDecl*, unsigned> CaptureMap; 399b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 400b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// CXXThisCaptureIndex - The (index+1) of the capture of 'this'; 401b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// zero if 'this' is not captured. 402b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman unsigned CXXThisCaptureIndex; 403b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 404b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// Captures - The captures. 405b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman SmallVector<Capture, 4> Captures; 406b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 40784b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// \brief - Whether the target type of return statements in this context 40884b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// is deduced (e.g. a lambda or block with omitted return type). 40984b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman bool HasImplicitReturnType; 41084b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman 41184b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// ReturnType - The target type of return statements in this context, 41284b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// or null if unknown. 41384b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman QualType ReturnType; 41484b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman 415999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, 416999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor SourceLocation Loc, SourceLocation EllipsisLoc, 417999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType, Expr *Cpy) { 418a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, 419999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor EllipsisLoc, CaptureType, Cpy)); 420b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman CaptureMap[Var] = Captures.size(); 421b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 422b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 423999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, 424c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor Expr *Cpy); 425b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 426a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Determine whether the C++ 'this' is captured. 427a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } 428a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 429a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Retrieve the capture of C++ 'this', if it has been captured. 430a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor Capture &getCXXThisCapture() { 431a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(isCXXThisCaptured() && "this has not been captured"); 432a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[CXXThisCaptureIndex - 1]; 433a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 434a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 435a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Determine whether the given variable has been captured. 436a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor bool isCaptured(VarDecl *Var) const { 437b11a7fd2f2204c7aadd74f870c98667d461997f5Aaron Ballman return CaptureMap.count(Var); 438a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 439a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 440a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Retrieve the capture of the given variable, if it has been 441a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// captured already. 442a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor Capture &getCapture(VarDecl *Var) { 443a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(isCaptured(Var) && "Variable has not been captured"); 444a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[CaptureMap[Var] - 1]; 445a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 446a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 447a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor const Capture &getCapture(VarDecl *Var) const { 448a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known 449a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor = CaptureMap.find(Var); 450a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(Known != CaptureMap.end() && "Variable has not been captured"); 451a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[Known->second - 1]; 452a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 453a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 454b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman static bool classof(const FunctionScopeInfo *FSI) { 455b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda; 456b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 457b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman}; 458b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 459781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a block that is currently being parsed. 460b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass BlockScopeInfo : public CapturingScopeInfo { 461781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic: 462781472fe99a120098c631b0cbe33c89f8cef5e70John McCall BlockDecl *TheDecl; 463781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 464781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// TheScope - This is the scope for the block itself, which contains 465781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// arguments etc. 466781472fe99a120098c631b0cbe33c89f8cef5e70John McCall Scope *TheScope; 467781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 468781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// BlockType - The function type of the block, if one was given. 469781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// Its return type may be BuiltinType::Dependent. 470781472fe99a120098c631b0cbe33c89f8cef5e70John McCall QualType FunctionType; 471781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 472d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) 473b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block), 474b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman TheScope(BlockScope) 475781472fe99a120098c631b0cbe33c89f8cef5e70John McCall { 476ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman Kind = SK_Block; 477781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 478781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 479781472fe99a120098c631b0cbe33c89f8cef5e70John McCall virtual ~BlockScopeInfo(); 480781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 481ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman static bool classof(const FunctionScopeInfo *FSI) { 482ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman return FSI->Kind == SK_Block; 483ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 484781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}; 485781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 486b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass LambdaScopeInfo : public CapturingScopeInfo { 487ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanpublic: 488ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// \brief The class that describes the lambda. 489ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman CXXRecordDecl *Lambda; 49001d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 49176e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor /// \brief The class that describes the lambda. 49276e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor CXXMethodDecl *CallOperator; 49376e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor 49401d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor /// \brief Source range covering the lambda introducer [...]. 49501d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor SourceRange IntroducerRange; 49601d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 497ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// \brief The number of captures in the \c Captures list that are 498ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// explicit captures. 499ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman unsigned NumExplicitCaptures; 50072899c34e3d1abfffa241ad0ce5c4bf175e5ea51Eli Friedman 501503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor /// \brief Whether this is a mutable lambda. 502d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman bool Mutable; 50301d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 50401d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor /// \brief Whether the (empty) parameter list is explicit. 50501d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor bool ExplicitParams; 506d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman 507503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor /// \brief Whether any of the capture expressions requires cleanups. 508503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor bool ExprNeedsCleanups; 509503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor 510612409ece080e814f79e06772c690d603f45fbd6Richard Smith /// \brief Whether the lambda contains an unexpanded parameter pack. 511612409ece080e814f79e06772c690d603f45fbd6Richard Smith bool ContainsUnexpandedParameterPack; 512612409ece080e814f79e06772c690d603f45fbd6Richard Smith 5139daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor /// \brief Variables used to index into by-copy array captures. 5149daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor llvm::SmallVector<VarDecl *, 4> ArrayIndexVars; 5159daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor 5169daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor /// \brief Offsets into the ArrayIndexVars array at which each capture starts 5179daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor /// its list of array index variables. 5189daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor llvm::SmallVector<unsigned, 4> ArrayIndexStarts; 5199daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor 52076e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor LambdaScopeInfo(DiagnosticsEngine &Diag, CXXRecordDecl *Lambda, 52176e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor CXXMethodDecl *CallOperator) 522b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda), 523503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false), 524612409ece080e814f79e06772c690d603f45fbd6Richard Smith ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false) 525ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman { 526ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman Kind = SK_Lambda; 527ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 528b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 529ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman virtual ~LambdaScopeInfo(); 530b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 531a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Note when 532a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor void finishedExplicitCaptures() { 533a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor NumExplicitCaptures = Captures.size(); 534a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 535c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor 536c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor static bool classof(const FunctionScopeInfo *FSI) { 537ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman return FSI->Kind == SK_Lambda; 538ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 539ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman}; 540ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman 541c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor 54258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy() 54358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose : Base(0, false), Property(0) {} 54458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 54558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy 54658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy::getSentinel() { 54758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose FunctionScopeInfo::WeakObjectProfileTy Result; 54858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose Result.Base.setInt(true); 54958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return Result; 55058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose} 55158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 5527a2704800943fbb69207e125d28186278712af36Jordan Rosetemplate <typename ExprT> 5537a2704800943fbb69207e125d28186278712af36Jordan Rosevoid FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) { 5547a2704800943fbb69207e125d28186278712af36Jordan Rose assert(E); 5557a2704800943fbb69207e125d28186278712af36Jordan Rose WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)]; 5567a2704800943fbb69207e125d28186278712af36Jordan Rose Uses.push_back(WeakUseTy(E, IsRead)); 557781472fe99a120098c631b0cbe33c89f8cef5e70John McCall} 5587a2704800943fbb69207e125d28186278712af36Jordan Rose 559c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregorinline void 560c3f1742bdd1ae0091d51168e111cd63861587b13Douglas GregorCapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc, 561c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor QualType CaptureType, Expr *Cpy) { 562c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, 563c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor Cpy)); 564c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor CXXThisCaptureIndex = Captures.size(); 565c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor 566c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this)) 567c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size()); 568c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor} 569c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor 5707a2704800943fbb69207e125d28186278712af36Jordan Rose} // end namespace sema 5717a2704800943fbb69207e125d28186278712af36Jordan Rose} // end namespace clang 572781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 573781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#endif 574