1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===--- ScopeInfo.h - Information about a semantic context -----*- C++ -*-===// 2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// The LLVM Compiler Infrastructure 4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source 6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details. 7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===// 9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file defines FunctionScopeInfo and its subclasses, which contain 11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// information about a single function, block, lambda, or method body. 12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// 13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===// 14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_CLANG_SEMA_SCOPEINFO_H 16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_CLANG_SEMA_SCOPEINFO_H 17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "clang/AST/Expr.h" 19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "clang/AST/Type.h" 20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "clang/Basic/CapturedStmt.h" 21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "clang/Basic/PartialDiagnostic.h" 22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "clang/Sema/CleanupInfo.h" 23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "clang/Sema/Ownership.h" 24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/DenseMap.h" 25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/SmallSet.h" 26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/SmallVector.h" 27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/StringSwitch.h" 28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <algorithm> 29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace clang { 31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Decl; 33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass BlockDecl; 34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass CapturedDecl; 35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass CXXMethodDecl; 36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass FieldDecl; 37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ObjCPropertyDecl; 38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass IdentifierInfo; 39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ImplicitParamDecl; 40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass LabelDecl; 41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ReturnStmt; 42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Scope; 43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass SwitchStmt; 44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass TemplateTypeParmDecl; 45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass TemplateParameterList; 46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass VarDecl; 47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ObjCIvarRefExpr; 48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ObjCPropertyRefExpr; 49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass ObjCMessageExpr; 50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace sema { 52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Contains information about the compound statement currently being 54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// parsed. 55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass CompoundScopeInfo { 56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CompoundScopeInfo() 58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : HasEmptyLoopBodies(false) { } 59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether this compound stamement contains `for' or `while' loops 61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// with empty bodies. 62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool HasEmptyLoopBodies; 63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setHasEmptyLoopBodies() { 65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasEmptyLoopBodies = true; 66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass PossiblyUnreachableDiag { 70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PartialDiagnostic PD; 72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation Loc; 73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Stmt *stmt; 74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PossiblyUnreachableDiag(const PartialDiagnostic &PD, SourceLocation Loc, 76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Stmt *stmt) 77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : PD(PD), Loc(Loc), stmt(stmt) {} 78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Retains information about a function, method, or block that is 81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// currently being parsed. 82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass FunctionScopeInfo { 83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected: 84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot enum ScopeKind { 85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SK_Function, 86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SK_Block, 87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SK_Lambda, 88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SK_CapturedRegion 89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief What kind of scope we are describing. 93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ScopeKind Kind : 3; 95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether this function contains a VLA, \@try, try, C++ 97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// initializer, or anything else that can't be jumped past. 98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool HasBranchProtectedScope : 1; 99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether this function contains any switches or direct gotos. 101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool HasBranchIntoScope : 1; 102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether this function contains any indirect gotos. 104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool HasIndirectGoto : 1; 105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether a statement was dropped because it was invalid. 107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool HasDroppedStmt : 1; 108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief True if current scope is for OpenMP declare reduction combiner. 110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool HasOMPDeclareReductionCombiner : 1; 111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether there is a fallthrough statement in this function. 113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool HasFallthroughStmt : 1; 114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether we make reference to a declaration that could be 116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// unavailable. 117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool HasPotentialAvailabilityViolations : 1; 118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// A flag that is set when parsing a method that must call super's 120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// implementation, such as \c -dealloc, \c -finalize, or any method marked 121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// with \c __attribute__((objc_requires_super)). 122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool ObjCShouldCallSuper : 1; 123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// True when this is a method marked as a designated initializer. 125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool ObjCIsDesignatedInit : 1; 126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// This starts true for a method marked as designated initializer and will 127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// be set to false if there is an invocation to a designated initializer of 128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// the super class. 129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool ObjCWarnForNoDesignatedInitChain : 1; 130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// True when this is an initializer method not marked as a designated 132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// initializer within a class that has at least one initializer marked as a 133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// designated initializer. 134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool ObjCIsSecondaryInit : 1; 135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// This starts true for a secondary initializer method and will be set to 136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// false if there is an invocation of an initializer on 'self'. 137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool ObjCWarnForNoInitDelegation : 1; 138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief True only when this function has not already built, or attempted 140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// to build, the initial and final coroutine suspend points 141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool NeedsCoroutineSuspends : 1; 142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief An enumeration represeting the kind of the first coroutine statement 144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// in the function. One of co_return, co_await, or co_yield. 145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned char FirstCoroutineStmtKind : 2; 146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// First coroutine statement in the current function. 148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// (ex co_return, co_await, co_yield) 149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation FirstCoroutineStmtLoc; 150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// First 'return' statement in the current function. 152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation FirstReturnLoc; 153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// First C++ 'try' statement in the current function. 155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation FirstCXXTryLoc; 156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// First SEH '__try' statement in the current function. 158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation FirstSEHTryLoc; 159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Used to determine if errors occurred in this function or block. 161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot DiagnosticErrorTrap ErrorTrap; 162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// SwitchStack - This is the current set of active switch statements in the 164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// block. 165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SmallVector<SwitchStmt*, 8> SwitchStack; 166f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The list of return statements that occur within the function or 168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// block, if there is any chance of applying the named return value 169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// optimization, or if we need to infer a return type. 170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SmallVector<ReturnStmt*, 4> Returns; 171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The promise object for this coroutine, if any. 173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot VarDecl *CoroutinePromise = nullptr; 174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The initial and final coroutine suspend points. 176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot std::pair<Stmt *, Stmt *> CoroutineSuspends; 177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 178f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The stack of currently active compound stamement scopes in the 179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// function. 180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SmallVector<CompoundScopeInfo, 4> CompoundScopes; 181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief A list of PartialDiagnostics created but delayed within the 183f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// current function scope. These diagnostics are vetted for reachability 184f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// prior to being emitted. 185f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SmallVector<PossiblyUnreachableDiag, 4> PossiblyUnreachableDiags; 186f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 187f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief A list of parameters which have the nonnull attribute and are 188f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// modified in the function. 189f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot llvm::SmallPtrSet<const ParmVarDecl*, 8> ModifiedNonNullParams; 190f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 191f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 192f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Represents a simple identification of a weak object. 193f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 194f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Part of the implementation of -Wrepeated-use-of-weak. 195f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 196f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// This is used to determine if two weak accesses refer to the same object. 197f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Here are some examples of how various accesses are "profiled": 198f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 199f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Access Expression | "Base" Decl | "Property" Decl 200f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// :---------------: | :-----------------: | :------------------------------: 201f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// self.property | self (VarDecl) | property (ObjCPropertyDecl) 202f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// self.implicitProp | self (VarDecl) | -implicitProp (ObjCMethodDecl) 203f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// self->ivar.prop | ivar (ObjCIvarDecl) | prop (ObjCPropertyDecl) 204f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// cxxObj.obj.prop | obj (FieldDecl) | prop (ObjCPropertyDecl) 205f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl) 206f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl) 207f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl) 208f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// MyClass.foo.prop | +foo (ObjCMethodDecl) | -prop (ObjCPropertyDecl) 209f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// weakVar | 0 (known) | weakVar (VarDecl) 210f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl) 211f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 212f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Objects are identified with only two Decls to make it reasonably fast to 213f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// compare them. 214f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class WeakObjectProfileTy { 215f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// The base object decl, as described in the class documentation. 216f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 217f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// The extra flag is "true" if the Base and Property are enough to uniquely 218f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// identify the object in memory. 219f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 220f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \sa isExactProfile() 221f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot typedef llvm::PointerIntPair<const NamedDecl *, 1, bool> BaseInfoTy; 222f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot BaseInfoTy Base; 223f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 224f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// The "property" decl, as described in the class documentation. 225f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 226f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Note that this may not actually be an ObjCPropertyDecl, e.g. in the 227f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// case of "implicit" properties (regular methods accessed via dot syntax). 228f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const NamedDecl *Property; 229f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 230f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Used to find the proper base profile for a given base expression. 231f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static BaseInfoTy getBaseInfo(const Expr *BaseE); 232f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 233f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot inline WeakObjectProfileTy(); 234f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static inline WeakObjectProfileTy getSentinel(); 235f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 236f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot public: 237f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot WeakObjectProfileTy(const ObjCPropertyRefExpr *RE); 238f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot WeakObjectProfileTy(const Expr *Base, const ObjCPropertyDecl *Property); 239f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot WeakObjectProfileTy(const DeclRefExpr *RE); 240f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot WeakObjectProfileTy(const ObjCIvarRefExpr *RE); 241f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 242f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const NamedDecl *getBase() const { return Base.getPointer(); } 243f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const NamedDecl *getProperty() const { return Property; } 244f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 245f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Returns true if the object base specifies a known object in memory, 246f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// rather than, say, an instance variable or property of another object. 247f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 248f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Note that this ignores the effects of aliasing; that is, \c foo.bar is 249f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// considered an exact profile if \c foo is a local variable, even if 250f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// another variable \c foo2 refers to the same object as \c foo. 251f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 252f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// For increased precision, accesses with base variables that are 253f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// properties or ivars of 'self' (e.g. self.prop1.prop2) are considered to 254f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// be exact, though this is not true for arbitrary variables 255f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// (foo.prop1.prop2). 256f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isExactProfile() const { 257f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Base.getInt(); 258f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 259f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 260f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool operator==(const WeakObjectProfileTy &Other) const { 261f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Base == Other.Base && Property == Other.Property; 262f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 263f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 264f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // For use in DenseMap. 265f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // We can't specialize the usual llvm::DenseMapInfo at the end of the file 266f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // because by that point the DenseMap in FunctionScopeInfo has already been 267f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // instantiated. 268f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class DenseMapInfo { 269f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot public: 270f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static inline WeakObjectProfileTy getEmptyKey() { 271f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return WeakObjectProfileTy(); 272f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 273f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static inline WeakObjectProfileTy getTombstoneKey() { 274f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return WeakObjectProfileTy::getSentinel(); 275f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 276f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 277f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static unsigned getHashValue(const WeakObjectProfileTy &Val) { 278f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot typedef std::pair<BaseInfoTy, const NamedDecl *> Pair; 279f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return llvm::DenseMapInfo<Pair>::getHashValue(Pair(Val.Base, 280f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Val.Property)); 281f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 282f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 283f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static bool isEqual(const WeakObjectProfileTy &LHS, 284f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const WeakObjectProfileTy &RHS) { 285f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return LHS == RHS; 286f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 287f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 288f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 289f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 290f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Represents a single use of a weak object. 291f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 292f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Stores both the expression and whether the access is potentially unsafe 293f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// (i.e. it could potentially be warned about). 294f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 295f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Part of the implementation of -Wrepeated-use-of-weak. 296f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class WeakUseTy { 297f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot llvm::PointerIntPair<const Expr *, 1, bool> Rep; 298f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot public: 299f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot WeakUseTy(const Expr *Use, bool IsRead) : Rep(Use, IsRead) {} 300f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 301f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Expr *getUseExpr() const { return Rep.getPointer(); } 302f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isUnsafe() const { return Rep.getInt(); } 303f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void markSafe() { Rep.setInt(false); } 304f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 305f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool operator==(const WeakUseTy &Other) const { 306f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Rep == Other.Rep; 307f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 308f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 309f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 310f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Used to collect uses of a particular weak object in a function body. 311f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 312f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Part of the implementation of -Wrepeated-use-of-weak. 313f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot typedef SmallVector<WeakUseTy, 4> WeakUseVector; 314f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 315f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Used to collect all uses of weak objects in a function body. 316f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 317f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Part of the implementation of -Wrepeated-use-of-weak. 318f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot typedef llvm::SmallDenseMap<WeakObjectProfileTy, WeakUseVector, 8, 319f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot WeakObjectProfileTy::DenseMapInfo> 320f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot WeakObjectUseMap; 321f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 322f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate: 323f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Used to collect all uses of weak objects in this function body. 324f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 325f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Part of the implementation of -Wrepeated-use-of-weak. 326f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot WeakObjectUseMap WeakObjectUses; 327f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 328f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected: 329f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot FunctionScopeInfo(const FunctionScopeInfo&) = default; 330f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 331f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 332f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Record that a weak object was accessed. 333f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 334f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Part of the implementation of -Wrepeated-use-of-weak. 335f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot template <typename ExprT> 336f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot inline void recordUseOfWeak(const ExprT *E, bool IsRead = true); 337f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 338f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void recordUseOfWeak(const ObjCMessageExpr *Msg, 339f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const ObjCPropertyDecl *Prop); 340f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 341f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Record that a given expression is a "safe" access of a weak object (e.g. 342f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// assigning it to a strong variable.) 343f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 344f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Part of the implementation of -Wrepeated-use-of-weak. 345f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void markSafeWeakUse(const Expr *E); 346f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 347f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const WeakObjectUseMap &getWeakObjectUses() const { 348f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return WeakObjectUses; 349f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 350f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 351f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setHasBranchIntoScope() { 352f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasBranchIntoScope = true; 353f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 354f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 355f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setHasBranchProtectedScope() { 356f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasBranchProtectedScope = true; 357f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 358f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 359f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setHasIndirectGoto() { 360f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasIndirectGoto = true; 361f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 362f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 363f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setHasDroppedStmt() { 364f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasDroppedStmt = true; 365f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 366f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 367f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setHasOMPDeclareReductionCombiner() { 368f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasOMPDeclareReductionCombiner = true; 369f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 370f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 371f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setHasFallthroughStmt() { 372f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasFallthroughStmt = true; 373f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 374f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 375f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setHasCXXTry(SourceLocation TryLoc) { 376f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot setHasBranchProtectedScope(); 377f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot FirstCXXTryLoc = TryLoc; 378f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 379f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 380f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setHasSEHTry(SourceLocation TryLoc) { 381f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot setHasBranchProtectedScope(); 382f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot FirstSEHTryLoc = TryLoc; 383f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 384f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 385f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool NeedsScopeChecking() const { 386f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return !HasDroppedStmt && 387f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot (HasIndirectGoto || 388f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot (HasBranchProtectedScope && HasBranchIntoScope)); 389f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 390f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 391f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isCoroutine() const { return !FirstCoroutineStmtLoc.isInvalid(); } 392f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 393f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setFirstCoroutineStmt(SourceLocation Loc, StringRef Keyword) { 394f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(FirstCoroutineStmtLoc.isInvalid() && 395f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot "first coroutine statement location already set"); 396f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot FirstCoroutineStmtLoc = Loc; 397f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot FirstCoroutineStmtKind = llvm::StringSwitch<unsigned char>(Keyword) 398f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot .Case("co_return", 0) 399f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot .Case("co_await", 1) 400f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot .Case("co_yield", 2); 401f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 402f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 403f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot StringRef getFirstCoroutineStmtKeyword() const { 404f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(FirstCoroutineStmtLoc.isValid() 405f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot && "no coroutine statement available"); 406f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot switch (FirstCoroutineStmtKind) { 407f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot case 0: return "co_return"; 408f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot case 1: return "co_await"; 409f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot case 2: return "co_yield"; 410f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot default: 411f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot llvm_unreachable("FirstCoroutineStmtKind has an invalid value"); 412f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 413f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 414f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 415f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setNeedsCoroutineSuspends(bool value = true) { 416f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert((!value || CoroutineSuspends.first == nullptr) && 417f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot "we already have valid suspend points"); 418f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot NeedsCoroutineSuspends = value; 419f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 420f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 421f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool hasInvalidCoroutineSuspends() const { 422f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return !NeedsCoroutineSuspends && CoroutineSuspends.first == nullptr; 423f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 424f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 425f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void setCoroutineSuspends(Stmt *Initial, Stmt *Final) { 426f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(Initial && Final && "suspend points cannot be null"); 427f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(CoroutineSuspends.first == nullptr && "suspend points already set"); 428f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot NeedsCoroutineSuspends = false; 429f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CoroutineSuspends.first = Initial; 430f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CoroutineSuspends.second = Final; 431f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 432f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 433f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot FunctionScopeInfo(DiagnosticsEngine &Diag) 434f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : Kind(SK_Function), 435f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasBranchProtectedScope(false), 436f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasBranchIntoScope(false), 437f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasIndirectGoto(false), 438f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasDroppedStmt(false), 439f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasOMPDeclareReductionCombiner(false), 440f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasFallthroughStmt(false), 441f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasPotentialAvailabilityViolations(false), 442f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ObjCShouldCallSuper(false), 443f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ObjCIsDesignatedInit(false), 444f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ObjCWarnForNoDesignatedInitChain(false), 445f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ObjCIsSecondaryInit(false), 446f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ObjCWarnForNoInitDelegation(false), 447f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot NeedsCoroutineSuspends(true), 448f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ErrorTrap(Diag) { } 449f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 450f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot virtual ~FunctionScopeInfo(); 451f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 452f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Clear out the information in this function scope, making it 453f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// suitable for reuse. 454f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void Clear(); 455f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 456f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 457f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass CapturingScopeInfo : public FunctionScopeInfo { 458f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprotected: 459f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CapturingScopeInfo(const CapturingScopeInfo&) = default; 460f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 461f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 462f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot enum ImplicitCaptureStyle { 463f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block, 464f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ImpCap_CapturedRegion 465f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 466f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 467f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ImplicitCaptureStyle ImpCaptureStyle; 468f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 469f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot class Capture { 470f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // There are three categories of capture: capturing 'this', capturing 471f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // local variables, and C++1y initialized captures (which can have an 472f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // arbitrary initializer, and don't really capture in the traditional 473f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // sense at all). 474f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // 475f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // There are three ways to capture a local variable: 476f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // - capture by copy in the C++11 sense, 477f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // - capture by reference in the C++11 sense, and 478f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // - __block capture. 479f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Lambdas explicitly specify capture by copy or capture by reference. 480f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // For blocks, __block capture applies to variables with that annotation, 481f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // variables of reference type are captured by reference, and other 482f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // variables are captured by copy. 483f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot enum CaptureKind { 484f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA 485f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 486f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot enum { 487f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IsNestedCapture = 0x1, 488f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot IsThisCaptured = 0x2 489f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 490f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// The variable being captured (if we are not capturing 'this') and whether 491f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// this is a nested capture, and whether we are capturing 'this' 492f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis; 493f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Expression to initialize a field of the given type, and the kind of 494f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// capture (if this is a capture and not an init-capture). The expression 495f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// is only required if we are capturing ByVal and the variable's type has 496f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// a non-trivial copy constructor. 497f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind; 498f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 499f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The source location at which the first capture occurred. 500f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation Loc; 501f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 502f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The location of the ellipsis that expands a parameter pack. 503f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation EllipsisLoc; 504f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 505f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The type as it was captured, which is in effect the type of the 506f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// non-static data member that would hold the capture. 507f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot QualType CaptureType; 508f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 509f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether an explicit capture has been odr-used in the body of the 510f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// lambda. 511f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool ODRUsed; 512f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 513f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether an explicit capture has been non-odr-used in the body of 514f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// the lambda. 515f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool NonODRUsed; 516f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 517f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot public: 518f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, 519f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation Loc, SourceLocation EllipsisLoc, 520f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot QualType CaptureType, Expr *Cpy) 521f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0), 522f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot InitExprAndCaptureKind( 523f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef 524f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : Cap_ByCopy), 525f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType), 526f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ODRUsed(false), NonODRUsed(false) {} 527f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 528f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot enum IsThisCapture { ThisCapture }; 529f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Capture(IsThisCapture, bool IsNested, SourceLocation Loc, 530f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot QualType CaptureType, Expr *Cpy, const bool ByCopy) 531f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : VarAndNestedAndThis( 532f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))), 533f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef), 534f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Loc(Loc), EllipsisLoc(), CaptureType(CaptureType), ODRUsed(false), 535f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot NonODRUsed(false) {} 536f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 537f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isThisCapture() const { 538f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return VarAndNestedAndThis.getInt() & IsThisCaptured; 539f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 540f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isVariableCapture() const { 541f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return !isThisCapture() && !isVLATypeCapture(); 542f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 543f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isCopyCapture() const { 544f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return InitExprAndCaptureKind.getInt() == Cap_ByCopy; 545f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 546f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isReferenceCapture() const { 547f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return InitExprAndCaptureKind.getInt() == Cap_ByRef; 548f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 549f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isBlockCapture() const { 550f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return InitExprAndCaptureKind.getInt() == Cap_Block; 551f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 552f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isVLATypeCapture() const { 553f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return InitExprAndCaptureKind.getInt() == Cap_VLA; 554f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 555f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isNested() const { 556f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return VarAndNestedAndThis.getInt() & IsNestedCapture; 557f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 558f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isODRUsed() const { return ODRUsed; } 559f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isNonODRUsed() const { return NonODRUsed; } 560f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; } 561f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 562f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot VarDecl *getVariable() const { 563f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return VarAndNestedAndThis.getPointer(); 564f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 565f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 566f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Retrieve the location at which this variable was captured. 567f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation getLocation() const { return Loc; } 568f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 569f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Retrieve the source location of the ellipsis, whose presence 570f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// indicates that the capture is a pack expansion. 571f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 572f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 573f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Retrieve the capture type for this capture, which is effectively 574f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// the type of the non-static data member in the lambda/block structure 575f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// that would store this capture. 576f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot QualType getCaptureType() const { 577f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(!isThisCapture()); 578f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return CaptureType; 579f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 580f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 581f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Expr *getInitExpr() const { 582f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(!isVLATypeCapture() && "no init expression for type capture"); 583f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return static_cast<Expr *>(InitExprAndCaptureKind.getPointer()); 584f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 585f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 586f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 587f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style) 588f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : FunctionScopeInfo(Diag), ImpCaptureStyle(Style), CXXThisCaptureIndex(0), 589f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot HasImplicitReturnType(false) 590f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot {} 591f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 592f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// CaptureMap - A map of captured variables to (index+1) into Captures. 593f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot llvm::DenseMap<VarDecl*, unsigned> CaptureMap; 594f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 595f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// CXXThisCaptureIndex - The (index+1) of the capture of 'this'; 596f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// zero if 'this' is not captured. 597f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned CXXThisCaptureIndex; 598f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 599f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Captures - The captures. 600f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SmallVector<Capture, 4> Captures; 601f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 602f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief - Whether the target type of return statements in this context 603f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// is deduced (e.g. a lambda or block with omitted return type). 604f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool HasImplicitReturnType; 605f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 606f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// ReturnType - The target type of return statements in this context, 607f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// or null if unknown. 608f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot QualType ReturnType; 609f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 610f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void addCapture(VarDecl *Var, bool isBlock, bool isByref, bool isNested, 611f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation Loc, SourceLocation EllipsisLoc, 612f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot QualType CaptureType, Expr *Cpy) { 613f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Captures.push_back(Capture(Var, isBlock, isByref, isNested, Loc, 614f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot EllipsisLoc, CaptureType, Cpy)); 615f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CaptureMap[Var] = Captures.size(); 616f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 617f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 618f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void addVLATypeCapture(SourceLocation Loc, QualType CaptureType) { 619f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Captures.push_back(Capture(/*Var*/ nullptr, /*isBlock*/ false, 620f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /*isByref*/ false, /*isNested*/ false, Loc, 621f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /*EllipsisLoc*/ SourceLocation(), CaptureType, 622f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /*Cpy*/ nullptr)); 623f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 624f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 625f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // Note, we do not need to add the type of 'this' since that is always 626f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // retrievable from Sema::getCurrentThisType - and is also encoded within the 627f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // type of the corresponding FieldDecl. 628f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void addThisCapture(bool isNested, SourceLocation Loc, 629f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Expr *Cpy, bool ByCopy); 630f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 631f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Determine whether the C++ 'this' is captured. 632f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } 633f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 634f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Retrieve the capture of C++ 'this', if it has been captured. 635f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Capture &getCXXThisCapture() { 636f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(isCXXThisCaptured() && "this has not been captured"); 637f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Captures[CXXThisCaptureIndex - 1]; 638f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 639f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 640f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Determine whether the given variable has been captured. 641f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isCaptured(VarDecl *Var) const { 642f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return CaptureMap.count(Var); 643f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 644f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 645f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Determine whether the given variable-array type has been captured. 646f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isVLATypeCaptured(const VariableArrayType *VAT) const; 647f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 648f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Retrieve the capture of the given variable, if it has been 649f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// captured already. 650f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Capture &getCapture(VarDecl *Var) { 651f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(isCaptured(Var) && "Variable has not been captured"); 652f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Captures[CaptureMap[Var] - 1]; 653f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 654f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 655f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const Capture &getCapture(VarDecl *Var) const { 656f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot llvm::DenseMap<VarDecl*, unsigned>::const_iterator Known 657f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot = CaptureMap.find(Var); 658f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(Known != CaptureMap.end() && "Variable has not been captured"); 659f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Captures[Known->second - 1]; 660f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 661f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 662f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static bool classof(const FunctionScopeInfo *FSI) { 663f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda 664f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot || FSI->Kind == SK_CapturedRegion; 665f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 666f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 667f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 668f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Retains information about a block that is currently being parsed. 669f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass BlockScopeInfo final : public CapturingScopeInfo { 670f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 671f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot BlockDecl *TheDecl; 672f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 673f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// TheScope - This is the scope for the block itself, which contains 674f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// arguments etc. 675f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Scope *TheScope; 676f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 677f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// BlockType - The function type of the block, if one was given. 678f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Its return type may be BuiltinType::Dependent. 679f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot QualType FunctionType; 680f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 681f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot BlockScopeInfo(DiagnosticsEngine &Diag, Scope *BlockScope, BlockDecl *Block) 682f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : CapturingScopeInfo(Diag, ImpCap_Block), TheDecl(Block), 683f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot TheScope(BlockScope) 684f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot { 685f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Kind = SK_Block; 686f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 687f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 688f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ~BlockScopeInfo() override; 689f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 690f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static bool classof(const FunctionScopeInfo *FSI) { 691f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return FSI->Kind == SK_Block; 692f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 693f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 694f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 695f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot/// \brief Retains information about a captured region. 696f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass CapturedRegionScopeInfo final : public CapturingScopeInfo { 697f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 698f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The CapturedDecl for this statement. 699f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CapturedDecl *TheCapturedDecl; 700f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The captured record type. 701f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot RecordDecl *TheRecordDecl; 702f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief This is the enclosing scope of the captured region. 703f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Scope *TheScope; 704f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The implicit parameter for the captured variables. 705f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ImplicitParamDecl *ContextParam; 706f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The kind of captured region. 707f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned short CapRegionKind; 708f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned short OpenMPLevel; 709f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 710f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, 711f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot RecordDecl *RD, ImplicitParamDecl *Context, 712f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CapturedRegionKind K, unsigned OpenMPLevel) 713f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : CapturingScopeInfo(Diag, ImpCap_CapturedRegion), 714f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S), 715f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel) 716f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot { 717f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Kind = SK_CapturedRegion; 718f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 719f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 720f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ~CapturedRegionScopeInfo() override; 721f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 722f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief A descriptive name for the kind of captured region this is. 723f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot StringRef getRegionName() const { 724f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot switch (CapRegionKind) { 725f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot case CR_Default: 726f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return "default captured statement"; 727f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot case CR_OpenMP: 728f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return "OpenMP region"; 729f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 730f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot llvm_unreachable("Invalid captured region kind!"); 731f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 732f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 733f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static bool classof(const FunctionScopeInfo *FSI) { 734f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return FSI->Kind == SK_CapturedRegion; 735f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 736f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 737f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 738f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass LambdaScopeInfo final : public CapturingScopeInfo { 739f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic: 740f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The class that describes the lambda. 741f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CXXRecordDecl *Lambda; 742f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 743f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The lambda's compiler-generated \c operator(). 744f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CXXMethodDecl *CallOperator; 745f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 746f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Source range covering the lambda introducer [...]. 747f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceRange IntroducerRange; 748f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 749f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Source location of the '&' or '=' specifying the default capture 750f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// type, if any. 751f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation CaptureDefaultLoc; 752f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 753f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief The number of captures in the \c Captures list that are 754f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// explicit captures. 755f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned NumExplicitCaptures; 756f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 757f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether this is a mutable lambda. 758f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool Mutable; 759f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 760f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether the (empty) parameter list is explicit. 761f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool ExplicitParams; 762f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 763f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether any of the capture expressions requires cleanups. 764f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CleanupInfo Cleanup; 765f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 766f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Whether the lambda contains an unexpanded parameter pack. 767f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool ContainsUnexpandedParameterPack; 768f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 769f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief If this is a generic lambda, use this as the depth of 770f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// each 'auto' parameter, during initial AST construction. 771f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned AutoTemplateParameterDepth; 772f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 773f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Store the list of the auto parameters for a generic lambda. 774f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// If this is a generic lambda, store the list of the auto 775f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// parameters converted into TemplateTypeParmDecls into a vector 776f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// that can be used to construct the generic lambda's template 777f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// parameter list, during initial AST construction. 778f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SmallVector<TemplateTypeParmDecl*, 4> AutoTemplateParams; 779f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 780f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// If this is a generic lambda, and the template parameter 781f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// list has been created (from the AutoTemplateParams) then 782f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// store a reference to it (cache it to avoid reconstructing it). 783f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot TemplateParameterList *GLTemplateParameterList; 784f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 785f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Contains all variable-referring-expressions (i.e. DeclRefExprs 786f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// or MemberExprs) that refer to local variables in a generic lambda 787f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// or a lambda in a potentially-evaluated-if-used context. 788f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 789f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Potentially capturable variables of a nested lambda that might need 790f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// to be captured by the lambda are housed here. 791f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// This is specifically useful for generic lambdas or 792f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// lambdas within a a potentially evaluated-if-used context. 793f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// If an enclosing variable is named in an expression of a lambda nested 794f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// within a generic lambda, we don't always know know whether the variable 795f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// will truly be odr-used (i.e. need to be captured) by that nested lambda, 796f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// until its instantiation. But we still need to capture it in the 797f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// enclosing lambda if all intervening lambdas can capture the variable. 798f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 799f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot llvm::SmallVector<Expr*, 4> PotentiallyCapturingExprs; 800f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 801f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Contains all variable-referring-expressions that refer 802f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// to local variables that are usable as constant expressions and 803f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// do not involve an odr-use (they may still need to be captured 804f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// if the enclosing full-expression is instantiation dependent). 805f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot llvm::SmallSet<Expr *, 8> NonODRUsedCapturingExprs; 806f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 807f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Contains all of the variables defined in this lambda that shadow variables 808f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// that were defined in parent contexts. Used to avoid warnings when the 809f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// shadowed variables are uncaptured by this lambda. 810f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot struct ShadowedOuterDecl { 811f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const VarDecl *VD; 812f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const VarDecl *ShadowedDecl; 813f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot }; 814f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot llvm::SmallVector<ShadowedOuterDecl, 4> ShadowingDecls; 815f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 816f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot SourceLocation PotentialThisCaptureLocation; 817f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 818f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot LambdaScopeInfo(DiagnosticsEngine &Diag) 819f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr), 820f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false), 821f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ExplicitParams(false), Cleanup{}, 822f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot ContainsUnexpandedParameterPack(false), AutoTemplateParameterDepth(0), 823f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot GLTemplateParameterList(nullptr) { 824f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Kind = SK_Lambda; 825f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 826f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 827f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Note when all explicit captures have been added. 828f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void finishedExplicitCaptures() { 829f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot NumExplicitCaptures = Captures.size(); 830f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 831f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 832f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot static bool classof(const FunctionScopeInfo *FSI) { 833f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return FSI->Kind == SK_Lambda; 834f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 835f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 836f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Is this scope known to be for a generic lambda? (This will be false until 837f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// we parse the first 'auto'-typed parameter. 838f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isGenericLambda() const { 839f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return !AutoTemplateParams.empty() || GLTemplateParameterList; 840f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 841f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 842f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 843f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Add a variable that might potentially be captured by the 844f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// lambda and therefore the enclosing lambdas. 845f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 846f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// This is also used by enclosing lambda's to speculatively capture 847f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// variables that nested lambda's - depending on their enclosing 848f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// specialization - might need to capture. 849f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Consider: 850f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// void f(int, int); <-- don't capture 851f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// void f(const int&, double); <-- capture 852f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// void foo() { 853f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// const int x = 10; 854f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// auto L = [=](auto a) { // capture 'x' 855f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// return [=](auto b) { 856f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// f(x, a); // we may or may not need to capture 'x' 857f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// }; 858f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// }; 859f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// } 860f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void addPotentialCapture(Expr *VarExpr) { 861f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(isa<DeclRefExpr>(VarExpr) || isa<MemberExpr>(VarExpr)); 862f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PotentiallyCapturingExprs.push_back(VarExpr); 863f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 864f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 865f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void addPotentialThisCapture(SourceLocation Loc) { 866f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PotentialThisCaptureLocation = Loc; 867f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 868f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool hasPotentialThisCapture() const { 869f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PotentialThisCaptureLocation.isValid(); 870f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 871f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 872f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// \brief Mark a variable's reference in a lambda as non-odr using. 873f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 874f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// For generic lambdas, if a variable is named in a potentially evaluated 875f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// expression, where the enclosing full expression is dependent then we 876f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// must capture the variable (given a default capture). 877f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// This is accomplished by recording all references to variables 878f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// (DeclRefExprs or MemberExprs) within said nested lambda in its array of 879f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// PotentialCaptures. All such variables have to be captured by that lambda, 880f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// except for as described below. 881f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// If that variable is usable as a constant expression and is named in a 882f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// manner that does not involve its odr-use (e.g. undergoes 883f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// lvalue-to-rvalue conversion, or discarded) record that it is so. Upon the 884f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// act of analyzing the enclosing full expression (ActOnFinishFullExpr) 885f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// if we can determine that the full expression is not instantiation- 886f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// dependent, then we can entirely avoid its capture. 887f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 888f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// const int n = 0; 889f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// [&] (auto x) { 890f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// (void)+n + x; 891f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// }; 892f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Interestingly, this strategy would involve a capture of n, even though 893f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// it's obviously not odr-used here, because the full-expression is 894f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// instantiation-dependent. It could be useful to avoid capturing such 895f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// variables, even when they are referred to in an instantiation-dependent 896f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// expression, if we can unambiguously determine that they shall never be 897f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// odr-used. This would involve removal of the variable-referring-expression 898f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// from the array of PotentialCaptures during the lvalue-to-rvalue 899f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// conversions. But per the working draft N3797, (post-chicago 2013) we must 900f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// capture such variables. 901f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// Before anyone is tempted to implement a strategy for not-capturing 'n', 902f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// consider the insightful warning in: 903f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// /cfe-commits/Week-of-Mon-20131104/092596.html 904f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// "The problem is that the set of captures for a lambda is part of the ABI 905f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// (since lambda layout can be made visible through inline functions and the 906f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// like), and there are no guarantees as to which cases we'll manage to build 907f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// an lvalue-to-rvalue conversion in, when parsing a template -- some 908f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// seemingly harmless change elsewhere in Sema could cause us to start or stop 909f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// building such a node. So we need a rule that anyone can implement and get 910f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// exactly the same result". 911f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot /// 912f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) { 913f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(isa<DeclRefExpr>(CapturingVarExpr) 914f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot || isa<MemberExpr>(CapturingVarExpr)); 915f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot NonODRUsedCapturingExprs.insert(CapturingVarExpr); 916f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 917f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const { 918f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(isa<DeclRefExpr>(CapturingVarExpr) 919f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot || isa<MemberExpr>(CapturingVarExpr)); 920f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return NonODRUsedCapturingExprs.count(CapturingVarExpr); 921f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 922f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void removePotentialCapture(Expr *E) { 923f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PotentiallyCapturingExprs.erase( 924f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot std::remove(PotentiallyCapturingExprs.begin(), 925f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PotentiallyCapturingExprs.end(), E), 926f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PotentiallyCapturingExprs.end()); 927f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 928f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void clearPotentialCaptures() { 929f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PotentiallyCapturingExprs.clear(); 930f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PotentialThisCaptureLocation = SourceLocation(); 931f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 932f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot unsigned getNumPotentialVariableCaptures() const { 933f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return PotentiallyCapturingExprs.size(); 934f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 935f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 936f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot bool hasPotentialCaptures() const { 937f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return getNumPotentialVariableCaptures() || 938f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot PotentialThisCaptureLocation.isValid(); 939f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot } 940f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 941f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // When passed the index, returns the VarDecl and Expr associated 942f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot // with the index. 943f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const; 944f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}; 945f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 946f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotFunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy() 947f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot : Base(nullptr, false), Property(nullptr) {} 948f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 949f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotFunctionScopeInfo::WeakObjectProfileTy 950f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotFunctionScopeInfo::WeakObjectProfileTy::getSentinel() { 951f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot FunctionScopeInfo::WeakObjectProfileTy Result; 952f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Result.Base.setInt(true); 953f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot return Result; 954f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} 955f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 956f3014761c955345d6e05491608e73228d014afbandroid-build-team Robottemplate <typename ExprT> 957f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotvoid FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) { 958f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot assert(E); 959f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot WeakUseVector &Uses = WeakObjectUses[WeakObjectProfileTy(E)]; 960f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Uses.push_back(WeakUseTy(E, IsRead)); 961f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} 962f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 963f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline void 964f3014761c955345d6e05491608e73228d014afbandroid-build-team RobotCapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc, 965f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Expr *Cpy, 966f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot const bool ByCopy) { 967f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, QualType(), 968f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot Cpy, ByCopy)); 969f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot CXXThisCaptureIndex = Captures.size(); 970f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} 971f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 972f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace sema 973f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace clang 974f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot 975f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif 976