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" 193a2f91280a49f4747063f983dc6a3296bd9359d2Ben Langmuir#include "clang/Basic/CapturedStmt.h" 20351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek#include "clang/Basic/PartialDiagnostic.h" 21c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali#include "clang/Sema/Ownership.h" 22781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/DenseMap.h" 23c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali#include "llvm/ADT/SmallSet.h" 24781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#include "llvm/ADT/SmallVector.h" 25c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali#include <algorithm> 26781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 27781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace clang { 28781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 2958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseclass Decl; 30781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass BlockDecl; 316afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Sirajclass CapturedDecl; 32f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass CXXMethodDecl; 330d8e9646bc000bab521ce52ed294209a92298cefRichard Smithclass FieldDecl; 347fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Roseclass ObjCPropertyDecl; 35781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass IdentifierInfo; 368c045ace381972f41d385b0a661ccf172834f459Ben Langmuirclass ImplicitParamDecl; 37ad8dcf4a9df0e24051dc31bf9e6f3cd138a34298Chris Lattnerclass LabelDecl; 38781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass ReturnStmt; 39781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass Scope; 40781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass SwitchStmt; 41fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Valiclass TemplateTypeParmDecl; 42fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Valiclass TemplateParameterList; 43f8af98286022f72157d84951b48fde5fb369ab29Douglas Gregorclass VarDecl; 447a2704800943fbb69207e125d28186278712af36Jordan Roseclass DeclRefExpr; 45c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Valiclass MemberExpr; 467a2704800943fbb69207e125d28186278712af36Jordan Roseclass ObjCIvarRefExpr; 4758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseclass ObjCPropertyRefExpr; 487fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Roseclass ObjCMessageExpr; 49781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 50781472fe99a120098c631b0cbe33c89f8cef5e70John McCallnamespace sema { 51781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 52625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// \brief Contains information about the compound statement currently being 53625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko/// parsed. 54625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkoclass CompoundScopeInfo { 55625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenkopublic: 56625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko CompoundScopeInfo() 57625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko : HasEmptyLoopBodies(false) { } 58625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 59625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// \brief Whether this compound stamement contains `for' or `while' loops 60625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// with empty bodies. 61625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko bool HasEmptyLoopBodies; 62625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 63625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko void setHasEmptyLoopBodies() { 64625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko HasEmptyLoopBodies = true; 65625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko } 66625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko}; 67625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 68351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekclass PossiblyUnreachableDiag { 69351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenekpublic: 70351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek PartialDiagnostic PD; 71351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek SourceLocation Loc; 72351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek const Stmt *stmt; 73351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 74351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, 75351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek const Stmt *stmt) 76351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek : PD(PD), Loc(Loc), stmt(stmt) {} 77351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek}; 78351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek 79781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a function, method, or block that is 80781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// currently being parsed. 81781472fe99a120098c631b0cbe33c89f8cef5e70John McCallclass FunctionScopeInfo { 82ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanprotected: 83ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman enum ScopeKind { 84ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman SK_Function, 85ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman SK_Block, 866afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj SK_Lambda, 876afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj SK_CapturedRegion 88ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman }; 89ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman 90781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic: 91ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// \brief What kind of scope we are describing. 92ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// 93ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman ScopeKind Kind; 94781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 95809d1be9820039b4cf6efa48246a0d70ffa13394James Dennett /// \brief Whether this function contains a VLA, \@try, try, C++ 96781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// initializer, or anything else that can't be jumped past. 97781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasBranchProtectedScope; 98781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 99781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Whether this function contains any switches or direct gotos. 100781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasBranchIntoScope; 101781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 102781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Whether this function contains any indirect gotos. 103781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool HasIndirectGoto; 104781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 105820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis /// \brief Whether a statement was dropped because it was invalid. 106820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis bool HasDroppedStmt; 107820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis 108535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose /// A flag that is set when parsing a method that must call super's 109535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose /// implementation, such as \c -dealloc, \c -finalize, or any method marked 110535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose /// with \c __attribute__((objc_requires_super)). 111535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose bool ObjCShouldCallSuper; 11295aac15936e8362aeb4813f95bc255dee6473592Eli Friedman 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// True when this is a method marked as a designated initializer. 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool ObjCIsDesignatedInit; 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// This starts true for a method marked as designated initializer and will 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// be set to false if there is an invocation to a designated initializer of 117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// the super class. 118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool ObjCWarnForNoDesignatedInitChain; 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// True when this is an initializer method not marked as a designated 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// initializer within a class that has at least one initializer marked as a 122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// designated initializer. 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool ObjCIsSecondaryInit; 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// This starts true for a secondary initializer method and will be set to 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// false if there is an invocation of an initializer on 'self'. 126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool ObjCWarnForNoInitDelegation; 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 1288fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis /// \brief Used to determine if errors occurred in this function or block. 1298fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis DiagnosticErrorTrap ErrorTrap; 130781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 131781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// SwitchStack - This is the current set of active switch statements in the 132781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// block. 133686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<SwitchStmt*, 8> SwitchStack; 134781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 135781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief The list of return statements that occur within the function or 136781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// block, if there is any chance of applying the named return value 1377dd900ed308506f9cf1cb72c70db1652f94cab37Jordan Rose /// optimization, or if we need to infer a return type. 138686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<ReturnStmt*, 4> Returns; 139625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 140625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// \brief The stack of currently active compound stamement scopes in the 141625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko /// function. 142625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko SmallVector<CompoundScopeInfo, 4> CompoundScopes; 143625bb569df0c34feec0d52c0ec5215f21ef2e054Dmitri Gribenko 144351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// \brief A list of PartialDiagnostics created but delayed within the 145351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// current function scope. These diagnostics are vetted for reachability 146351ba91eaa6d30e523587b2d7ed676a5172c6e56Ted Kremenek /// prior to being emitted. 147686775deca8b8685eb90801495880e3abdd844c2Chris Lattner SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; 148781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 14958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosepublic: 15058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Represents a simple identification of a weak object. 15158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 15258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 15358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 15458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// This is used to determine if two weak accesses refer to the same object. 15558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Here are some examples of how various accesses are "profiled": 15658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 15758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Access Expression | "Base" Decl | "Property" Decl 15858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// :---------------: | :-----------------: | :------------------------------: 15958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// self.property | self (VarDecl) | property (ObjCPropertyDecl) 16058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl) 16158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl) 16258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl) 16358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl) 16458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl) 16558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl) 1667a2704800943fbb69207e125d28186278712af36Jordan Rose /// weakVar | 0 (known) | weakVar (VarDecl) 1677a2704800943fbb69207e125d28186278712af36Jordan Rose /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl) 16858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 16958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Objects are identified with only two Decls to make it reasonably fast to 17058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// compare them. 17158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose class WeakObjectProfileTy { 17258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// The base object decl, as described in the class documentation. 17358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 17458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// The extra flag is "true" if the Base and Property are enough to uniquely 17558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// identify the object in memory. 17658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 17758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// \sa isExactProfile() 17858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy; 17958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose BaseInfoTy Base; 18058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 18158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// The "property" decl, as described in the class documentation. 18258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 18358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the 18458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// case of "implicit" properties (regular methods accessed via dot syntax). 18558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const NamedDecl *Property; 18658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 1877a2704800943fbb69207e125d28186278712af36Jordan Rose /// Used to find the proper base profile for a given base expression. 1887a2704800943fbb69207e125d28186278712af36Jordan Rose static BaseInfoTy getBaseInfo(const Expr *BaseE); 1897a2704800943fbb69207e125d28186278712af36Jordan Rose 19058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose // For use in DenseMap. 191b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose friend class DenseMapInfo; 19258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose inline WeakObjectProfileTy(); 19358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose static inline WeakObjectProfileTy getSentinel(); 19458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 19558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose public: 19658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose WeakObjectProfileTy(const ObjCPropertyRefExpr *RE); 1977fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property); 1987a2704800943fbb69207e125d28186278712af36Jordan Rose WeakObjectProfileTy(const DeclRefExpr *RE); 1997a2704800943fbb69207e125d28186278712af36Jordan Rose WeakObjectProfileTy(const ObjCIvarRefExpr *RE); 20058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 201c0e44454bd78b8b4f3d70f08cf1edd5466b0c798Jordan Rose const NamedDecl *getBase() const { return Base.getPointer(); } 20258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const NamedDecl *getProperty() const { return Property; } 20358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 20458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Returns true if the object base specifies a known object in memory, 20558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// rather than, say, an instance variable or property of another object. 20658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 20758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Note that this ignores the effects of aliasing; that is, \c foo.bar is 20858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// considered an exact profile if \c foo is a local variable, even if 20958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// another variable \c foo2 refers to the same object as \c foo. 21058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 21158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// For increased precision, accesses with base variables that are 21258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to 21358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// be exact, though this is not true for arbitrary variables 21458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// (foo.prop1.prop2). 21558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose bool isExactProfile() const { 21658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return Base.getInt(); 21758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 21858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 21958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose bool operator==(const WeakObjectProfileTy &Other) const { 22058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return Base == Other.Base && Property == Other.Property; 22158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 222b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose 223b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose // For use in DenseMap. 224b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose // We can't specialize the usual llvm::DenseMapInfo at the end of the file 225b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose // because by that point the DenseMap in FunctionScopeInfo has already been 226b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose // instantiated. 227b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose class DenseMapInfo { 228b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose public: 229b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose static inline WeakObjectProfileTy getEmptyKey() { 230b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose return WeakObjectProfileTy(); 231b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose } 232b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose static inline WeakObjectProfileTy getTombstoneKey() { 233b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose return WeakObjectProfileTy::getSentinel(); 234b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose } 235b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose 236b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose static unsigned getHashValue(const WeakObjectProfileTy &Val) { 237b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose typedef std::pair<BaseInfoTy, const NamedDecl *> Pair; 238b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base, 239b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose Val.Property)); 240b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose } 241b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose 242b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose static bool isEqual(const WeakObjectProfileTy &LHS, 243b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose const WeakObjectProfileTy &RHS) { 244b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose return LHS == RHS; 245b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose } 246b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose }; 24758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose }; 24858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 24958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Represents a single use of a weak object. 25058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 25158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Stores both the expression and whether the access is potentially unsafe 25258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// (i.e. it could potentially be warned about). 25358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 25458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 25558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose class WeakUseTy { 25658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose llvm::PointerIntPair<const Expr *, 1, bool> Rep; 25758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose public: 25858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {} 25958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 26058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const Expr *getUseExpr() const { return Rep.getPointer(); } 26158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose bool isUnsafe() const { return Rep.getInt(); } 26258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose void markSafe() { Rep.setInt(false); } 26358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 26458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose bool operator==(const WeakUseTy &Other) const { 26558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return Rep == Other.Rep; 26658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 26758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose }; 26858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 26958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Used to collect uses of a particular weak object in a function body. 27058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 27158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 27258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose typedef SmallVector<WeakUseTy, 4> WeakUseVector; 27358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 27458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Used to collect all uses of weak objects in a function body. 27558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 27658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 277b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8, 278b6d80fe68d30ebd14b20c96643c252c36041df8dJordan Rose WeakObjectProfileTy::DenseMapInfo> 27958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose WeakObjectUseMap; 28058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 28158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Roseprivate: 28258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Used to collect all uses of weak objects in this function body. 28358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 28458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 28558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose WeakObjectUseMap WeakObjectUses; 28658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 28758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rosepublic: 2887a2704800943fbb69207e125d28186278712af36Jordan Rose /// Record that a weak object was accessed. 28958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 29058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 2917a2704800943fbb69207e125d28186278712af36Jordan Rose template <typename ExprT> 2927a2704800943fbb69207e125d28186278712af36Jordan Rose inline void recordUseOfWeak(const ExprT *E, bool IsRead = true); 29358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 2947fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose void recordUseOfWeak(const ObjCMessageExpr *Msg, 2957fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose const ObjCPropertyDecl *Prop); 2967fffce781e6ecbf4058b24df7e5ae3037569aa56Jordan Rose 29758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Record that a given expression is a "safe" access of a weak object (e.g. 29858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// assigning it to a strong variable.) 29958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// 30058b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose /// Part of the implementation of -Wrepeated-use-of-weak. 30158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose void markSafeWeakUse(const Expr *E); 30258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 30358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose const WeakObjectUseMap &getWeakObjectUses() const { 30458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return WeakObjectUses; 30558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose } 30658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 307781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasBranchIntoScope() { 308781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchIntoScope = true; 309781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 310781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 311781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasBranchProtectedScope() { 312781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchProtectedScope = true; 313781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 314781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 315781472fe99a120098c631b0cbe33c89f8cef5e70John McCall void setHasIndirectGoto() { 316781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasIndirectGoto = true; 317781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 318781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 319820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis void setHasDroppedStmt() { 320820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis HasDroppedStmt = true; 321820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis } 322820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis 323781472fe99a120098c631b0cbe33c89f8cef5e70John McCall bool NeedsScopeChecking() const { 324820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis return !HasDroppedStmt && 325820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis (HasIndirectGoto || 326820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis (HasBranchProtectedScope && HasBranchIntoScope)); 327781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 328781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 329d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie FunctionScopeInfo(DiagnosticsEngine &Diag) 330ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman : Kind(SK_Function), 331781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchProtectedScope(false), 332781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasBranchIntoScope(false), 333781472fe99a120098c631b0cbe33c89f8cef5e70John McCall HasIndirectGoto(false), 334820b23dc924a4ae7af07d5a75d6b1d781c267d57Argyrios Kyrtzidis HasDroppedStmt(false), 335535a5d001b2035a7aa68ee368fbe44ec90e33740Jordan Rose ObjCShouldCallSuper(false), 336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCIsDesignatedInit(false), 337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCWarnForNoDesignatedInitChain(false), 338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCIsSecondaryInit(false), 339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ObjCWarnForNoInitDelegation(false), 3408fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis ErrorTrap(Diag) { } 341781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 342781472fe99a120098c631b0cbe33c89f8cef5e70John McCall virtual ~FunctionScopeInfo(); 343781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 344781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// \brief Clear out the information in this function scope, making it 345781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// suitable for reuse. 3468fc32d272bd57b0a59f61c874cb7b56d9005e89eArgyrios Kyrtzidis void Clear(); 347781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}; 348781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 349b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass CapturingScopeInfo : public FunctionScopeInfo { 350b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanpublic: 351b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum ImplicitCaptureStyle { 3526afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block, 3536afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj ImpCap_CapturedRegion 354b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 355b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 356b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman ImplicitCaptureStyle ImpCaptureStyle; 357b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 358b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman class Capture { 3590d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // There are three categories of capture: capturing 'this', capturing 3600d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // local variables, and C++1y initialized captures (which can have an 3610d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // arbitrary initializer, and don't really capture in the traditional 3620d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // sense at all). 3630d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // 3640d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // There are three ways to capture a local variable: 3650d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // - capture by copy in the C++11 sense, 3660d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // - capture by reference in the C++11 sense, and 3670d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // - __block capture. 3680d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // Lambdas explicitly specify capture by copy or capture by reference. 3690d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // For blocks, __block capture applies to variables with that annotation, 3700d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // variables of reference type are captured by reference, and other 3710d8e9646bc000bab521ce52ed294209a92298cefRichard Smith // variables are captured by copy. 372b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum CaptureKind { 37304fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_This 374b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 375b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 37604fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith /// The variable being captured (if we are not capturing 'this') and whether 37704fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith /// this is a nested capture. 37804fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith llvm::PointerIntPair<VarDecl*, 1, bool> VarAndNested; 379b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 38004fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith /// Expression to initialize a field of the given type, and the kind of 38104fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith /// capture (if this is a capture and not an init-capture). The expression 38204fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith /// is only required if we are capturing ByVal and the variable's type has 38304fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith /// a non-trivial copy constructor. 3840d8e9646bc000bab521ce52ed294209a92298cefRichard Smith llvm::PointerIntPair<Expr*, 2, CaptureKind> InitExprAndCaptureKind; 3850d8e9646bc000bab521ce52ed294209a92298cefRichard Smith 3860d8e9646bc000bab521ce52ed294209a92298cefRichard Smith /// \brief The source location at which the first capture occurred. 38793962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor SourceLocation Loc; 3880d8e9646bc000bab521ce52ed294209a92298cefRichard Smith 389a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor /// \brief The location of the ellipsis that expands a parameter pack. 390a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor SourceLocation EllipsisLoc; 3910d8e9646bc000bab521ce52ed294209a92298cefRichard Smith 392999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// \brief The type as it was captured, which is in effect the type of the 393999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// non-static data member that would hold the capture. 394999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType; 3950d8e9646bc000bab521ce52ed294209a92298cefRichard Smith 396b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman public: 3970d8e9646bc000bab521ce52ed294209a92298cefRichard Smith Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, 3980d8e9646bc000bab521ce52ed294209a92298cefRichard Smith SourceLocation Loc, SourceLocation EllipsisLoc, 399999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType, Expr *Cpy) 40004fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith : VarAndNested(Var, IsNested), 4010d8e9646bc000bab521ce52ed294209a92298cefRichard Smith InitExprAndCaptureKind(Cpy, Block ? Cap_Block : 4020d8e9646bc000bab521ce52ed294209a92298cefRichard Smith ByRef ? Cap_ByRef : Cap_ByCopy), 4030d8e9646bc000bab521ce52ed294209a92298cefRichard Smith Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {} 404b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 405b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman enum IsThisCapture { ThisCapture }; 4060d8e9646bc000bab521ce52ed294209a92298cefRichard Smith Capture(IsThisCapture, bool IsNested, SourceLocation Loc, 407999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType, Expr *Cpy) 4086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : VarAndNested(nullptr, IsNested), 40904fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith InitExprAndCaptureKind(Cpy, Cap_This), 4100d8e9646bc000bab521ce52ed294209a92298cefRichard Smith Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {} 411b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 4120d8e9646bc000bab521ce52ed294209a92298cefRichard Smith bool isThisCapture() const { 41304fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith return InitExprAndCaptureKind.getInt() == Cap_This; 4140d8e9646bc000bab521ce52ed294209a92298cefRichard Smith } 4150d8e9646bc000bab521ce52ed294209a92298cefRichard Smith bool isVariableCapture() const { 41604fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith return InitExprAndCaptureKind.getInt() != Cap_This; 4170d8e9646bc000bab521ce52ed294209a92298cefRichard Smith } 4180d8e9646bc000bab521ce52ed294209a92298cefRichard Smith bool isCopyCapture() const { 4190d8e9646bc000bab521ce52ed294209a92298cefRichard Smith return InitExprAndCaptureKind.getInt() == Cap_ByCopy; 4200d8e9646bc000bab521ce52ed294209a92298cefRichard Smith } 4210d8e9646bc000bab521ce52ed294209a92298cefRichard Smith bool isReferenceCapture() const { 4220d8e9646bc000bab521ce52ed294209a92298cefRichard Smith return InitExprAndCaptureKind.getInt() == Cap_ByRef; 4230d8e9646bc000bab521ce52ed294209a92298cefRichard Smith } 4240d8e9646bc000bab521ce52ed294209a92298cefRichard Smith bool isBlockCapture() const { 4250d8e9646bc000bab521ce52ed294209a92298cefRichard Smith return InitExprAndCaptureKind.getInt() == Cap_Block; 4260d8e9646bc000bab521ce52ed294209a92298cefRichard Smith } 42704fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith bool isNested() { return VarAndNested.getInt(); } 428b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 429b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman VarDecl *getVariable() const { 43004fa7a33279808dc3e5117c41b5f84c40eeb7362Richard Smith return VarAndNested.getPointer(); 431b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 43293962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor 43393962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor /// \brief Retrieve the location at which this variable was captured. 43493962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor SourceLocation getLocation() const { return Loc; } 43593962e5360a43200faa70939571afc4fb9326cf7Douglas Gregor 436a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor /// \brief Retrieve the source location of the ellipsis, whose presence 437a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor /// indicates that the capture is a pack expansion. 438a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 439a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor 440999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// \brief Retrieve the capture type for this capture, which is effectively 441999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// the type of the non-static data member in the lambda/block structure 442999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor /// that would store this capture. 443999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType getCaptureType() const { return CaptureType; } 444999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor 4450d8e9646bc000bab521ce52ed294209a92298cefRichard Smith Expr *getInitExpr() const { 4460d8e9646bc000bab521ce52ed294209a92298cefRichard Smith return InitExprAndCaptureKind.getPointer(); 447b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 448b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman }; 449b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 450b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style) 45184b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0), 45284b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman HasImplicitReturnType(false) 453b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman {} 454b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 455b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// CaptureMap - A map of captured variables to (index+1) into Captures. 456b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman llvm::DenseMap<VarDecl*, unsigned> CaptureMap; 457b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 458b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// CXXThisCaptureIndex - The (index+1) of the capture of 'this'; 459b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// zero if 'this' is not captured. 460b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman unsigned CXXThisCaptureIndex; 461b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 462b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman /// Captures - The captures. 463b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman SmallVector<Capture, 4> Captures; 464b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 46584b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// \brief - Whether the target type of return statements in this context 46684b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// is deduced (e.g. a lambda or block with omitted return type). 46784b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman bool HasImplicitReturnType; 46884b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman 46984b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// ReturnType - The target type of return statements in this context, 47084b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman /// or null if unknown. 47184b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman QualType ReturnType; 47284b007fae6c0cd30fa07074d34fbe2bf61fa44f9Eli Friedman 473999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, 474999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor SourceLocation Loc, SourceLocation EllipsisLoc, 475999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor QualType CaptureType, Expr *Cpy) { 476a73652465bcc4c0f6cb7d933ad84e002b527a643Douglas Gregor Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, 477999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor EllipsisLoc, CaptureType, Cpy)); 478b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman CaptureMap[Var] = Captures.size(); 479b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 480b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 481999713eea940f4e087cc3ac878689c5c5c7a7225Douglas Gregor void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, 482c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor Expr *Cpy); 483b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 484a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Determine whether the C++ 'this' is captured. 485a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } 486a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 487a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Retrieve the capture of C++ 'this', if it has been captured. 488a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor Capture &getCXXThisCapture() { 489a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(isCXXThisCaptured() && "this has not been captured"); 490a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[CXXThisCaptureIndex - 1]; 491a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 492a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 493a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Determine whether the given variable has been captured. 494a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor bool isCaptured(VarDecl *Var) const { 495b11a7fd2f2204c7aadd74f870c98667d461997f5Aaron Ballman return CaptureMap.count(Var); 496a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 497a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 498a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// \brief Retrieve the capture of the given variable, if it has been 499a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor /// captured already. 500a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor Capture &getCapture(VarDecl *Var) { 501a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(isCaptured(Var) && "Variable has not been captured"); 502a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[CaptureMap[Var] - 1]; 503a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 504a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 505a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor const Capture &getCapture(VarDecl *Var) const { 506a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known 507a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor = CaptureMap.find(Var); 508a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor assert(Known != CaptureMap.end() && "Variable has not been captured"); 509a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor return Captures[Known->second - 1]; 510a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 511a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor 512b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman static bool classof(const FunctionScopeInfo *FSI) { 5136afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda 5146afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj || FSI->Kind == SK_CapturedRegion; 515b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman } 516b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman}; 517b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 518781472fe99a120098c631b0cbe33c89f8cef5e70John McCall/// \brief Retains information about a block that is currently being parsed. 519b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass BlockScopeInfo : public CapturingScopeInfo { 520781472fe99a120098c631b0cbe33c89f8cef5e70John McCallpublic: 521781472fe99a120098c631b0cbe33c89f8cef5e70John McCall BlockDecl *TheDecl; 522781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 523781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// TheScope - This is the scope for the block itself, which contains 524781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// arguments etc. 525781472fe99a120098c631b0cbe33c89f8cef5e70John McCall Scope *TheScope; 526781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 527781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// BlockType - The function type of the block, if one was given. 528781472fe99a120098c631b0cbe33c89f8cef5e70John McCall /// Its return type may be BuiltinType::Dependent. 529781472fe99a120098c631b0cbe33c89f8cef5e70John McCall QualType FunctionType; 530781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 531d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) 532b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block), 533b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman TheScope(BlockScope) 534781472fe99a120098c631b0cbe33c89f8cef5e70John McCall { 535ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman Kind = SK_Block; 536781472fe99a120098c631b0cbe33c89f8cef5e70John McCall } 537781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 538781472fe99a120098c631b0cbe33c89f8cef5e70John McCall virtual ~BlockScopeInfo(); 539781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 540ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman static bool classof(const FunctionScopeInfo *FSI) { 541ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman return FSI->Kind == SK_Block; 542ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 543781472fe99a120098c631b0cbe33c89f8cef5e70John McCall}; 544781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 5456afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj/// \brief Retains information about a captured region. 5466afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Sirajclass CapturedRegionScopeInfo: public CapturingScopeInfo { 5476afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Sirajpublic: 5486afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj /// \brief The CapturedDecl for this statement. 5496afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj CapturedDecl *TheCapturedDecl; 5506afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj /// \brief The captured record type. 5516afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj RecordDecl *TheRecordDecl; 5526afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj /// \brief This is the enclosing scope of the captured region. 5536afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj Scope *TheScope; 5548c045ace381972f41d385b0a661ccf172834f459Ben Langmuir /// \brief The implicit parameter for the captured variables. 5558c045ace381972f41d385b0a661ccf172834f459Ben Langmuir ImplicitParamDecl *ContextParam; 5566afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj /// \brief The kind of captured region. 5576afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj CapturedRegionKind CapRegionKind; 5586afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj 5596afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, 5608c045ace381972f41d385b0a661ccf172834f459Ben Langmuir RecordDecl *RD, ImplicitParamDecl *Context, 5618c045ace381972f41d385b0a661ccf172834f459Ben Langmuir CapturedRegionKind K) 5626afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj : CapturingScopeInfo(Diag, ImpCap_CapturedRegion), 5638c045ace381972f41d385b0a661ccf172834f459Ben Langmuir TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S), 5648c045ace381972f41d385b0a661ccf172834f459Ben Langmuir ContextParam(Context), CapRegionKind(K) 5656afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj { 5666afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj Kind = SK_CapturedRegion; 5676afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj } 5686afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj 5696afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj virtual ~CapturedRegionScopeInfo(); 5706afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj 5716afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj /// \brief A descriptive name for the kind of captured region this is. 5726afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj StringRef getRegionName() const { 5736afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj switch (CapRegionKind) { 5746afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj case CR_Default: 5756afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj return "default captured statement"; 5760c018357b8bbb1f96bbf622a5807421e626b4228Alexey Bataev case CR_OpenMP: 5770c018357b8bbb1f96bbf622a5807421e626b4228Alexey Bataev return "OpenMP region"; 5786afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj } 5790579c165aa54840898956703ebd63bdd1f4dd907Benjamin Kramer llvm_unreachable("Invalid captured region kind!"); 5806afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj } 5816afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj 5826afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj static bool classof(const FunctionScopeInfo *FSI) { 5836afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj return FSI->Kind == SK_CapturedRegion; 5846afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj } 5856afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj}; 5866afcf8875d4e447645cd7bf3733dd8e2eb8455dcTareq A. Siraj 587b69b42c55d56815bab62991bf839cdb41634d3afEli Friedmanclass LambdaScopeInfo : public CapturingScopeInfo { 588ec9ea7200718478e8a976529defbe21942a11c9cEli Friedmanpublic: 589ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// \brief The class that describes the lambda. 590ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman CXXRecordDecl *Lambda; 59101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 592f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett /// \brief The lambda's compiler-generated \c operator(). 59376e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor CXXMethodDecl *CallOperator; 59476e3da57b0e8cf72d221f44d54566ef206341668Douglas Gregor 59501d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor /// \brief Source range covering the lambda introducer [...]. 59601d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor SourceRange IntroducerRange; 59701d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor 598f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett /// \brief Source location of the '&' or '=' specifying the default capture 599f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett /// type, if any. 600f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett SourceLocation CaptureDefaultLoc; 601f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett 602f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett /// \brief The number of captures in the \c Captures list that are 603ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman /// explicit captures. 604ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman unsigned NumExplicitCaptures; 60572899c34e3d1abfffa241ad0ce5c4bf175e5ea51Eli Friedman 606503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor /// \brief Whether this is a mutable lambda. 607d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman bool Mutable; 608f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett 60901d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor /// \brief Whether the (empty) parameter list is explicit. 61001d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor bool ExplicitParams; 611d67d0cc40f31956b40b44b6ee3619d17a0f73294Eli Friedman 612503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor /// \brief Whether any of the capture expressions requires cleanups. 613503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor bool ExprNeedsCleanups; 614503384f731b5abcbf870b0a5224eb920e631db0aDouglas Gregor 615612409ece080e814f79e06772c690d603f45fbd6Richard Smith /// \brief Whether the lambda contains an unexpanded parameter pack. 616612409ece080e814f79e06772c690d603f45fbd6Richard Smith bool ContainsUnexpandedParameterPack; 617612409ece080e814f79e06772c690d603f45fbd6Richard Smith 6189daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor /// \brief Variables used to index into by-copy array captures. 619cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<VarDecl *, 4> ArrayIndexVars; 6209daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor 6219daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor /// \brief Offsets into the ArrayIndexVars array at which each capture starts 6229daa7bfdff7256cef693d7bf10084881bcb9253cDouglas Gregor /// its list of array index variables. 623cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<unsigned, 4> ArrayIndexStarts; 624fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali 625fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali /// \brief If this is a generic lambda, use this as the depth of 626fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali /// each 'auto' parameter, during initial AST construction. 627fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali unsigned AutoTemplateParameterDepth; 628fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali 629fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali /// \brief Store the list of the auto parameters for a generic lambda. 630fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali /// If this is a generic lambda, store the list of the auto 631fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali /// parameters converted into TemplateTypeParmDecls into a vector 632fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali /// that can be used to construct the generic lambda's template 633fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali /// parameter list, during initial AST construction. 634fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams; 635fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali 636fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali /// If this is a generic lambda, and the template parameter 637fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali /// list has been created (from the AutoTemplateParams) then 638fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali /// store a reference to it (cache it to avoid reconstructing it). 639fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali TemplateParameterList *GLTemplateParameterList; 640c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali 641c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// \brief Contains all variable-referring-expressions (i.e. DeclRefExprs 642c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// or MemberExprs) that refer to local variables in a generic lambda 643c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// or a lambda in a potentially-evaluated-if-used context. 644c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// 645c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// Potentially capturable variables of a nested lambda that might need 646c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// to be captured by the lambda are housed here. 647c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// This is specifically useful for generic lambdas or 648c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// lambdas within a a potentially evaluated-if-used context. 649c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// If an enclosing variable is named in an expression of a lambda nested 650c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// within a generic lambda, we don't always know know whether the variable 651c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// will truly be odr-used (i.e. need to be captured) by that nested lambda, 652c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// until its instantiation. But we still need to capture it in the 653c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// enclosing lambda if all intervening lambdas can capture the variable. 654c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali 655c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs; 656c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali 657c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// \brief Contains all variable-referring-expressions that refer 658c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// to local variables that are usable as constant expressions and 659c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// do not involve an odr-use (they may still need to be captured 660c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// if the enclosing full-expression is instantiation dependent). 661c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali llvm::SmallSet<Expr*, 8> NonODRUsedCapturingExprs; 662c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali 663c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali SourceLocation PotentialThisCaptureLocation; 664fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali 665fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali LambdaScopeInfo(DiagnosticsEngine &Diag) 6666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr), 6676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false), 668fad9e13f3cb85198f0ee5af620ba81cd78574faaFaisal Vali ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false), 6696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines AutoTemplateParameterDepth(0), GLTemplateParameterList(nullptr) 670ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman { 671ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman Kind = SK_Lambda; 672ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 673b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 674ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman virtual ~LambdaScopeInfo(); 675b69b42c55d56815bab62991bf839cdb41634d3afEli Friedman 676f68af647dda5cca00b49be27d24f62b0a7fff986James Dennett /// \brief Note when all explicit captures have been added. 677a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor void finishedExplicitCaptures() { 678a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor NumExplicitCaptures = Captures.size(); 679a1f2114d9e81923c750f6b439302ac03552c37dbDouglas Gregor } 680c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor 681c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor static bool classof(const FunctionScopeInfo *FSI) { 682152b4e4652baedfceba1cd8115515629225e713fManuel Klimek return FSI->Kind == SK_Lambda; 683ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman } 684c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali 685c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// 686c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// \brief Add a variable that might potentially be captured by the 687c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// lambda and therefore the enclosing lambdas. 688c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// 689c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// This is also used by enclosing lambda's to speculatively capture 690c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// variables that nested lambda's - depending on their enclosing 691c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// specialization - might need to capture. 692c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// Consider: 693c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// void f(int, int); <-- don't capture 694c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// void f(const int&, double); <-- capture 695c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// void foo() { 696c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// const int x = 10; 697c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// auto L = [=](auto a) { // capture 'x' 698c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// return [=](auto b) { 699c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// f(x, a); // we may or may not need to capture 'x' 700c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// }; 701c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// }; 702c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// } 703c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali void addPotentialCapture(Expr *VarExpr) { 704c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr)); 705c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali PotentiallyCapturingExprs.push_back(VarExpr); 706c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali } 707c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali 708c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali void addPotentialThisCapture(SourceLocation Loc) { 709c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali PotentialThisCaptureLocation = Loc; 710c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali } 711c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali bool hasPotentialThisCapture() const { 712c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali return PotentialThisCaptureLocation.isValid(); 713c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali } 714c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali 715c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// \brief Mark a variable's reference in a lambda as non-odr using. 716c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// 717c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// For generic lambdas, if a variable is named in a potentially evaluated 718c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// expression, where the enclosing full expression is dependent then we 719c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// must capture the variable (given a default capture). 720c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// This is accomplished by recording all references to variables 721c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of 722c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// PotentialCaptures. All such variables have to be captured by that lambda, 723c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// except for as described below. 724c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// If that variable is usable as a constant expression and is named in a 725c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// manner that does not involve its odr-use (e.g. undergoes 726c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the 727c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// act of analyzing the enclosing full expression (ActOnFinishFullExpr) 728c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// if we can determine that the full expression is not instantiation- 729c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// dependent, then we can entirely avoid its capture. 730651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// 731651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// const int n = 0; 732651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// [&] (auto x) { 733651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// (void)+n + x; 734c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// }; 735c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// Interestingly, this strategy would involve a capture of n, even though 736c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// it's obviously not odr-used here, because the full-expression is 737c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// instantiation-dependent. It could be useful to avoid capturing such 738c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// variables, even when they are referred to in an instantiation-dependent 739c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// expression, if we can unambiguously determine that they shall never be 740c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// odr-used. This would involve removal of the variable-referring-expression 741c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// from the array of PotentialCaptures during the lvalue-to-rvalue 742c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// conversions. But per the working draft N3797, (post-chicago 2013) we must 743c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// capture such variables. 744c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// Before anyone is tempted to implement a strategy for not-capturing 'n', 745c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// consider the insightful warning in: 746c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// /cfe-commits/Week-of-Mon-20131104/092596.html 747651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// "The problem is that the set of captures for a lambda is part of the ABI 748651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// (since lambda layout can be made visible through inline functions and the 749651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// like), and there are no guarantees as to which cases we'll manage to build 750651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// an lvalue-to-rvalue conversion in, when parsing a template -- some 751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// seemingly harmless change elsewhere in Sema could cause us to start or stop 752651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines /// building such a node. So we need a rule that anyone can implement and get 753c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// exactly the same result". 754c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali /// 755c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) { 756c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali assert(isa<DeclRefExpr>(CapturingVarExpr) 757c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali || isa<MemberExpr>(CapturingVarExpr)); 758c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali NonODRUsedCapturingExprs.insert(CapturingVarExpr); 759c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali } 760651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const { 761c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali assert(isa<DeclRefExpr>(CapturingVarExpr) 762c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali || isa<MemberExpr>(CapturingVarExpr)); 763c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali return NonODRUsedCapturingExprs.count(CapturingVarExpr); 764c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali } 765c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali void removePotentialCapture(Expr *E) { 766c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali PotentiallyCapturingExprs.erase( 767c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali std::remove(PotentiallyCapturingExprs.begin(), 768c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali PotentiallyCapturingExprs.end(), E), 769c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali PotentiallyCapturingExprs.end()); 770c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali } 771c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali void clearPotentialCaptures() { 772c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali PotentiallyCapturingExprs.clear(); 773c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali PotentialThisCaptureLocation = SourceLocation(); 774c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali } 775c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali unsigned getNumPotentialVariableCaptures() const { 776c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali return PotentiallyCapturingExprs.size(); 777c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali } 778c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali 779c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali bool hasPotentialCaptures() const { 780c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali return getNumPotentialVariableCaptures() || 781c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali PotentialThisCaptureLocation.isValid(); 782c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali } 783651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 784651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // When passed the index, returns the VarDecl and Expr associated 785c00e4194296e994efab0e4bf64ca66737850bdf0Faisal Vali // with the index. 786651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const; 787ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman}; 788ec9ea7200718478e8a976529defbe21942a11c9cEli Friedman 78958b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy() 7906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines : Base(nullptr, false), Property(nullptr) {} 79158b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 79258b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy 79358b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan RoseFunctionScopeInfo::WeakObjectProfileTy::getSentinel() { 79458b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose FunctionScopeInfo::WeakObjectProfileTy Result; 79558b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose Result.Base.setInt(true); 79658b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose return Result; 79758b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose} 79858b6bdcdeb683a3504f2248a409e1f4e85876ceeJordan Rose 7997a2704800943fbb69207e125d28186278712af36Jordan Rosetemplate <typename ExprT> 8007a2704800943fbb69207e125d28186278712af36Jordan Rosevoid FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) { 8017a2704800943fbb69207e125d28186278712af36Jordan Rose assert(E); 8027a2704800943fbb69207e125d28186278712af36Jordan Rose WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)]; 8037a2704800943fbb69207e125d28186278712af36Jordan Rose Uses.push_back(WeakUseTy(E, IsRead)); 804781472fe99a120098c631b0cbe33c89f8cef5e70John McCall} 8057a2704800943fbb69207e125d28186278712af36Jordan Rose 806c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregorinline void 807c3f1742bdd1ae0091d51168e111cd63861587b13Douglas GregorCapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc, 808c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor QualType CaptureType, Expr *Cpy) { 809c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, 810c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor Cpy)); 811c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor CXXThisCaptureIndex = Captures.size(); 812c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor 813c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this)) 814c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size()); 815c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor} 816c3f1742bdd1ae0091d51168e111cd63861587b13Douglas Gregor 8177a2704800943fbb69207e125d28186278712af36Jordan Rose} // end namespace sema 8187a2704800943fbb69207e125d28186278712af36Jordan Rose} // end namespace clang 819781472fe99a120098c631b0cbe33c89f8cef5e70John McCall 820781472fe99a120098c631b0cbe33c89f8cef5e70John McCall#endif 821