10b57cec5SDimitry Andric //===--- SemaLambda.cpp - Semantic Analysis for C++11 Lambdas -------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements semantic analysis for C++ lambda expressions. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0fca6ea1SDimitry Andric #include "clang/Sema/SemaLambda.h" 130b57cec5SDimitry Andric #include "TypeLocBuilder.h" 140b57cec5SDimitry Andric #include "clang/AST/ASTLambda.h" 15*0fca6ea1SDimitry Andric #include "clang/AST/CXXInheritance.h" 160b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h" 170b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 18*0fca6ea1SDimitry Andric #include "clang/Sema/DeclSpec.h" 190b57cec5SDimitry Andric #include "clang/Sema/Initialization.h" 200b57cec5SDimitry Andric #include "clang/Sema/Lookup.h" 210b57cec5SDimitry Andric #include "clang/Sema/Scope.h" 220b57cec5SDimitry Andric #include "clang/Sema/ScopeInfo.h" 23*0fca6ea1SDimitry Andric #include "clang/Sema/SemaCUDA.h" 240b57cec5SDimitry Andric #include "clang/Sema/SemaInternal.h" 25*0fca6ea1SDimitry Andric #include "clang/Sema/SemaOpenMP.h" 26feb5b0c7SDimitry Andric #include "clang/Sema/Template.h" 270b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 28bdd1243dSDimitry Andric #include <optional> 290b57cec5SDimitry Andric using namespace clang; 300b57cec5SDimitry Andric using namespace sema; 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric /// Examines the FunctionScopeInfo stack to determine the nearest 330b57cec5SDimitry Andric /// enclosing lambda (to the current lambda) that is 'capture-ready' for 340b57cec5SDimitry Andric /// the variable referenced in the current lambda (i.e. \p VarToCapture). 350b57cec5SDimitry Andric /// If successful, returns the index into Sema's FunctionScopeInfo stack 360b57cec5SDimitry Andric /// of the capture-ready lambda's LambdaScopeInfo. 370b57cec5SDimitry Andric /// 380b57cec5SDimitry Andric /// Climbs down the stack of lambdas (deepest nested lambda - i.e. current 390b57cec5SDimitry Andric /// lambda - is on top) to determine the index of the nearest enclosing/outer 400b57cec5SDimitry Andric /// lambda that is ready to capture the \p VarToCapture being referenced in 410b57cec5SDimitry Andric /// the current lambda. 420b57cec5SDimitry Andric /// As we climb down the stack, we want the index of the first such lambda - 430b57cec5SDimitry Andric /// that is the lambda with the highest index that is 'capture-ready'. 440b57cec5SDimitry Andric /// 450b57cec5SDimitry Andric /// A lambda 'L' is capture-ready for 'V' (var or this) if: 460b57cec5SDimitry Andric /// - its enclosing context is non-dependent 470b57cec5SDimitry Andric /// - and if the chain of lambdas between L and the lambda in which 480b57cec5SDimitry Andric /// V is potentially used (i.e. the lambda at the top of the scope info 490b57cec5SDimitry Andric /// stack), can all capture or have already captured V. 500b57cec5SDimitry Andric /// If \p VarToCapture is 'null' then we are trying to capture 'this'. 510b57cec5SDimitry Andric /// 520b57cec5SDimitry Andric /// Note that a lambda that is deemed 'capture-ready' still needs to be checked 530b57cec5SDimitry Andric /// for whether it is 'capture-capable' (see 540b57cec5SDimitry Andric /// getStackIndexOfNearestEnclosingCaptureCapableLambda), before it can truly 550b57cec5SDimitry Andric /// capture. 560b57cec5SDimitry Andric /// 570b57cec5SDimitry Andric /// \param FunctionScopes - Sema's stack of nested FunctionScopeInfo's (which a 580b57cec5SDimitry Andric /// LambdaScopeInfo inherits from). The current/deepest/innermost lambda 590b57cec5SDimitry Andric /// is at the top of the stack and has the highest index. 600b57cec5SDimitry Andric /// \param VarToCapture - the variable to capture. If NULL, capture 'this'. 610b57cec5SDimitry Andric /// 62bdd1243dSDimitry Andric /// \returns An std::optional<unsigned> Index that if evaluates to 'true' 63bdd1243dSDimitry Andric /// contains the index (into Sema's FunctionScopeInfo stack) of the innermost 64bdd1243dSDimitry Andric /// lambda which is capture-ready. If the return value evaluates to 'false' 65bdd1243dSDimitry Andric /// then no lambda is capture-ready for \p VarToCapture. 660b57cec5SDimitry Andric 67bdd1243dSDimitry Andric static inline std::optional<unsigned> 680b57cec5SDimitry Andric getStackIndexOfNearestEnclosingCaptureReadyLambda( 690b57cec5SDimitry Andric ArrayRef<const clang::sema::FunctionScopeInfo *> FunctionScopes, 70bdd1243dSDimitry Andric ValueDecl *VarToCapture) { 710b57cec5SDimitry Andric // Label failure to capture. 72bdd1243dSDimitry Andric const std::optional<unsigned> NoLambdaIsCaptureReady; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric // Ignore all inner captured regions. 750b57cec5SDimitry Andric unsigned CurScopeIndex = FunctionScopes.size() - 1; 760b57cec5SDimitry Andric while (CurScopeIndex > 0 && isa<clang::sema::CapturedRegionScopeInfo>( 770b57cec5SDimitry Andric FunctionScopes[CurScopeIndex])) 780b57cec5SDimitry Andric --CurScopeIndex; 790b57cec5SDimitry Andric assert( 800b57cec5SDimitry Andric isa<clang::sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]) && 810b57cec5SDimitry Andric "The function on the top of sema's function-info stack must be a lambda"); 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric // If VarToCapture is null, we are attempting to capture 'this'. 840b57cec5SDimitry Andric const bool IsCapturingThis = !VarToCapture; 850b57cec5SDimitry Andric const bool IsCapturingVariable = !IsCapturingThis; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric // Start with the current lambda at the top of the stack (highest index). 880b57cec5SDimitry Andric DeclContext *EnclosingDC = 890b57cec5SDimitry Andric cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex])->CallOperator; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric do { 920b57cec5SDimitry Andric const clang::sema::LambdaScopeInfo *LSI = 930b57cec5SDimitry Andric cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]); 940b57cec5SDimitry Andric // IF we have climbed down to an intervening enclosing lambda that contains 950b57cec5SDimitry Andric // the variable declaration - it obviously can/must not capture the 960b57cec5SDimitry Andric // variable. 970b57cec5SDimitry Andric // Since its enclosing DC is dependent, all the lambdas between it and the 980b57cec5SDimitry Andric // innermost nested lambda are dependent (otherwise we wouldn't have 990b57cec5SDimitry Andric // arrived here) - so we don't yet have a lambda that can capture the 1000b57cec5SDimitry Andric // variable. 1010b57cec5SDimitry Andric if (IsCapturingVariable && 1020b57cec5SDimitry Andric VarToCapture->getDeclContext()->Equals(EnclosingDC)) 1030b57cec5SDimitry Andric return NoLambdaIsCaptureReady; 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric // For an enclosing lambda to be capture ready for an entity, all 1060b57cec5SDimitry Andric // intervening lambda's have to be able to capture that entity. If even 1070b57cec5SDimitry Andric // one of the intervening lambda's is not capable of capturing the entity 1080b57cec5SDimitry Andric // then no enclosing lambda can ever capture that entity. 1090b57cec5SDimitry Andric // For e.g. 1100b57cec5SDimitry Andric // const int x = 10; 1110b57cec5SDimitry Andric // [=](auto a) { #1 1120b57cec5SDimitry Andric // [](auto b) { #2 <-- an intervening lambda that can never capture 'x' 1130b57cec5SDimitry Andric // [=](auto c) { #3 1140b57cec5SDimitry Andric // f(x, c); <-- can not lead to x's speculative capture by #1 or #2 1150b57cec5SDimitry Andric // }; }; }; 1160b57cec5SDimitry Andric // If they do not have a default implicit capture, check to see 1170b57cec5SDimitry Andric // if the entity has already been explicitly captured. 1180b57cec5SDimitry Andric // If even a single dependent enclosing lambda lacks the capability 1190b57cec5SDimitry Andric // to ever capture this variable, there is no further enclosing 1200b57cec5SDimitry Andric // non-dependent lambda that can capture this variable. 1210b57cec5SDimitry Andric if (LSI->ImpCaptureStyle == sema::LambdaScopeInfo::ImpCap_None) { 1220b57cec5SDimitry Andric if (IsCapturingVariable && !LSI->isCaptured(VarToCapture)) 1230b57cec5SDimitry Andric return NoLambdaIsCaptureReady; 1240b57cec5SDimitry Andric if (IsCapturingThis && !LSI->isCXXThisCaptured()) 1250b57cec5SDimitry Andric return NoLambdaIsCaptureReady; 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric EnclosingDC = getLambdaAwareParentOfDeclContext(EnclosingDC); 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric assert(CurScopeIndex); 1300b57cec5SDimitry Andric --CurScopeIndex; 1310b57cec5SDimitry Andric } while (!EnclosingDC->isTranslationUnit() && 1320b57cec5SDimitry Andric EnclosingDC->isDependentContext() && 1330b57cec5SDimitry Andric isLambdaCallOperator(EnclosingDC)); 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric assert(CurScopeIndex < (FunctionScopes.size() - 1)); 1360b57cec5SDimitry Andric // If the enclosingDC is not dependent, then the immediately nested lambda 1370b57cec5SDimitry Andric // (one index above) is capture-ready. 1380b57cec5SDimitry Andric if (!EnclosingDC->isDependentContext()) 1390b57cec5SDimitry Andric return CurScopeIndex + 1; 1400b57cec5SDimitry Andric return NoLambdaIsCaptureReady; 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric /// Examines the FunctionScopeInfo stack to determine the nearest 1440b57cec5SDimitry Andric /// enclosing lambda (to the current lambda) that is 'capture-capable' for 1450b57cec5SDimitry Andric /// the variable referenced in the current lambda (i.e. \p VarToCapture). 1460b57cec5SDimitry Andric /// If successful, returns the index into Sema's FunctionScopeInfo stack 1470b57cec5SDimitry Andric /// of the capture-capable lambda's LambdaScopeInfo. 1480b57cec5SDimitry Andric /// 1490b57cec5SDimitry Andric /// Given the current stack of lambdas being processed by Sema and 1500b57cec5SDimitry Andric /// the variable of interest, to identify the nearest enclosing lambda (to the 1510b57cec5SDimitry Andric /// current lambda at the top of the stack) that can truly capture 1520b57cec5SDimitry Andric /// a variable, it has to have the following two properties: 1530b57cec5SDimitry Andric /// a) 'capture-ready' - be the innermost lambda that is 'capture-ready': 1540b57cec5SDimitry Andric /// - climb down the stack (i.e. starting from the innermost and examining 1550b57cec5SDimitry Andric /// each outer lambda step by step) checking if each enclosing 1560b57cec5SDimitry Andric /// lambda can either implicitly or explicitly capture the variable. 1570b57cec5SDimitry Andric /// Record the first such lambda that is enclosed in a non-dependent 1580b57cec5SDimitry Andric /// context. If no such lambda currently exists return failure. 1590b57cec5SDimitry Andric /// b) 'capture-capable' - make sure the 'capture-ready' lambda can truly 1600b57cec5SDimitry Andric /// capture the variable by checking all its enclosing lambdas: 1610b57cec5SDimitry Andric /// - check if all outer lambdas enclosing the 'capture-ready' lambda 1620b57cec5SDimitry Andric /// identified above in 'a' can also capture the variable (this is done 1630b57cec5SDimitry Andric /// via tryCaptureVariable for variables and CheckCXXThisCapture for 1640b57cec5SDimitry Andric /// 'this' by passing in the index of the Lambda identified in step 'a') 1650b57cec5SDimitry Andric /// 1660b57cec5SDimitry Andric /// \param FunctionScopes - Sema's stack of nested FunctionScopeInfo's (which a 1670b57cec5SDimitry Andric /// LambdaScopeInfo inherits from). The current/deepest/innermost lambda 1680b57cec5SDimitry Andric /// is at the top of the stack. 1690b57cec5SDimitry Andric /// 1700b57cec5SDimitry Andric /// \param VarToCapture - the variable to capture. If NULL, capture 'this'. 1710b57cec5SDimitry Andric /// 1720b57cec5SDimitry Andric /// 173bdd1243dSDimitry Andric /// \returns An std::optional<unsigned> Index that if evaluates to 'true' 174bdd1243dSDimitry Andric /// contains the index (into Sema's FunctionScopeInfo stack) of the innermost 175bdd1243dSDimitry Andric /// lambda which is capture-capable. If the return value evaluates to 'false' 176bdd1243dSDimitry Andric /// then no lambda is capture-capable for \p VarToCapture. 1770b57cec5SDimitry Andric 178bdd1243dSDimitry Andric std::optional<unsigned> 179bdd1243dSDimitry Andric clang::getStackIndexOfNearestEnclosingCaptureCapableLambda( 1800b57cec5SDimitry Andric ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes, 181bdd1243dSDimitry Andric ValueDecl *VarToCapture, Sema &S) { 1820b57cec5SDimitry Andric 183bdd1243dSDimitry Andric const std::optional<unsigned> NoLambdaIsCaptureCapable; 1840b57cec5SDimitry Andric 185bdd1243dSDimitry Andric const std::optional<unsigned> OptionalStackIndex = 1860b57cec5SDimitry Andric getStackIndexOfNearestEnclosingCaptureReadyLambda(FunctionScopes, 1870b57cec5SDimitry Andric VarToCapture); 1880b57cec5SDimitry Andric if (!OptionalStackIndex) 1890b57cec5SDimitry Andric return NoLambdaIsCaptureCapable; 1900b57cec5SDimitry Andric 19181ad6265SDimitry Andric const unsigned IndexOfCaptureReadyLambda = *OptionalStackIndex; 1920b57cec5SDimitry Andric assert(((IndexOfCaptureReadyLambda != (FunctionScopes.size() - 1)) || 1930b57cec5SDimitry Andric S.getCurGenericLambda()) && 1940b57cec5SDimitry Andric "The capture ready lambda for a potential capture can only be the " 1950b57cec5SDimitry Andric "current lambda if it is a generic lambda"); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric const sema::LambdaScopeInfo *const CaptureReadyLambdaLSI = 1980b57cec5SDimitry Andric cast<sema::LambdaScopeInfo>(FunctionScopes[IndexOfCaptureReadyLambda]); 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric // If VarToCapture is null, we are attempting to capture 'this' 2010b57cec5SDimitry Andric const bool IsCapturingThis = !VarToCapture; 2020b57cec5SDimitry Andric const bool IsCapturingVariable = !IsCapturingThis; 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric if (IsCapturingVariable) { 2050b57cec5SDimitry Andric // Check if the capture-ready lambda can truly capture the variable, by 2060b57cec5SDimitry Andric // checking whether all enclosing lambdas of the capture-ready lambda allow 2070b57cec5SDimitry Andric // the capture - i.e. make sure it is capture-capable. 2080b57cec5SDimitry Andric QualType CaptureType, DeclRefType; 2090b57cec5SDimitry Andric const bool CanCaptureVariable = 2100b57cec5SDimitry Andric !S.tryCaptureVariable(VarToCapture, 2110b57cec5SDimitry Andric /*ExprVarIsUsedInLoc*/ SourceLocation(), 2120b57cec5SDimitry Andric clang::Sema::TryCapture_Implicit, 2130b57cec5SDimitry Andric /*EllipsisLoc*/ SourceLocation(), 2140b57cec5SDimitry Andric /*BuildAndDiagnose*/ false, CaptureType, 2150b57cec5SDimitry Andric DeclRefType, &IndexOfCaptureReadyLambda); 2160b57cec5SDimitry Andric if (!CanCaptureVariable) 2170b57cec5SDimitry Andric return NoLambdaIsCaptureCapable; 2180b57cec5SDimitry Andric } else { 2190b57cec5SDimitry Andric // Check if the capture-ready lambda can truly capture 'this' by checking 2200b57cec5SDimitry Andric // whether all enclosing lambdas of the capture-ready lambda can capture 2210b57cec5SDimitry Andric // 'this'. 2220b57cec5SDimitry Andric const bool CanCaptureThis = 2230b57cec5SDimitry Andric !S.CheckCXXThisCapture( 2240b57cec5SDimitry Andric CaptureReadyLambdaLSI->PotentialThisCaptureLocation, 2250b57cec5SDimitry Andric /*Explicit*/ false, /*BuildAndDiagnose*/ false, 2260b57cec5SDimitry Andric &IndexOfCaptureReadyLambda); 2270b57cec5SDimitry Andric if (!CanCaptureThis) 2280b57cec5SDimitry Andric return NoLambdaIsCaptureCapable; 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric return IndexOfCaptureReadyLambda; 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric static inline TemplateParameterList * 2340b57cec5SDimitry Andric getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) { 2350b57cec5SDimitry Andric if (!LSI->GLTemplateParameterList && !LSI->TemplateParams.empty()) { 2360b57cec5SDimitry Andric LSI->GLTemplateParameterList = TemplateParameterList::Create( 2370b57cec5SDimitry Andric SemaRef.Context, 2380b57cec5SDimitry Andric /*Template kw loc*/ SourceLocation(), 2390b57cec5SDimitry Andric /*L angle loc*/ LSI->ExplicitTemplateParamsRange.getBegin(), 2400b57cec5SDimitry Andric LSI->TemplateParams, 2410b57cec5SDimitry Andric /*R angle loc*/LSI->ExplicitTemplateParamsRange.getEnd(), 242e8d8bef9SDimitry Andric LSI->RequiresClause.get()); 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric return LSI->GLTemplateParameterList; 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric 24781ad6265SDimitry Andric CXXRecordDecl * 24881ad6265SDimitry Andric Sema::createLambdaClosureType(SourceRange IntroducerRange, TypeSourceInfo *Info, 24981ad6265SDimitry Andric unsigned LambdaDependencyKind, 2500b57cec5SDimitry Andric LambdaCaptureDefault CaptureDefault) { 2510b57cec5SDimitry Andric DeclContext *DC = CurContext; 2520b57cec5SDimitry Andric while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext())) 2530b57cec5SDimitry Andric DC = DC->getParent(); 25406c3fb27SDimitry Andric 25506c3fb27SDimitry Andric bool IsGenericLambda = 25606c3fb27SDimitry Andric Info && getGenericLambdaTemplateParameterList(getCurLambda(), *this); 2570b57cec5SDimitry Andric // Start constructing the lambda class. 25881ad6265SDimitry Andric CXXRecordDecl *Class = CXXRecordDecl::CreateLambda( 25981ad6265SDimitry Andric Context, DC, Info, IntroducerRange.getBegin(), LambdaDependencyKind, 26081ad6265SDimitry Andric IsGenericLambda, CaptureDefault); 2610b57cec5SDimitry Andric DC->addDecl(Class); 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric return Class; 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric /// Determine whether the given context is or is enclosed in an inline 2670b57cec5SDimitry Andric /// function. 2680b57cec5SDimitry Andric static bool isInInlineFunction(const DeclContext *DC) { 2690b57cec5SDimitry Andric while (!DC->isFileContext()) { 2700b57cec5SDimitry Andric if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DC)) 2710b57cec5SDimitry Andric if (FD->isInlined()) 2720b57cec5SDimitry Andric return true; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric DC = DC->getLexicalParent(); 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric return false; 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 280a7dea167SDimitry Andric std::tuple<MangleNumberingContext *, Decl *> 281a7dea167SDimitry Andric Sema::getCurrentMangleNumberContext(const DeclContext *DC) { 2820b57cec5SDimitry Andric // Compute the context for allocating mangling numbers in the current 2830b57cec5SDimitry Andric // expression, if the ABI requires them. 284a7dea167SDimitry Andric Decl *ManglingContextDecl = ExprEvalContexts.back().ManglingContextDecl; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric enum ContextKind { 2870b57cec5SDimitry Andric Normal, 2880b57cec5SDimitry Andric DefaultArgument, 2890b57cec5SDimitry Andric DataMember, 2900b57cec5SDimitry Andric InlineVariable, 29106c3fb27SDimitry Andric TemplatedVariable, 292bdd1243dSDimitry Andric Concept 2930b57cec5SDimitry Andric } Kind = Normal; 2940b57cec5SDimitry Andric 29506c3fb27SDimitry Andric bool IsInNonspecializedTemplate = 29606c3fb27SDimitry Andric inTemplateInstantiation() || CurContext->isDependentContext(); 29706c3fb27SDimitry Andric 2980b57cec5SDimitry Andric // Default arguments of member function parameters that appear in a class 2990b57cec5SDimitry Andric // definition, as well as the initializers of data members, receive special 3000b57cec5SDimitry Andric // treatment. Identify them. 3010b57cec5SDimitry Andric if (ManglingContextDecl) { 3020b57cec5SDimitry Andric if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ManglingContextDecl)) { 3030b57cec5SDimitry Andric if (const DeclContext *LexicalDC 3040b57cec5SDimitry Andric = Param->getDeclContext()->getLexicalParent()) 3050b57cec5SDimitry Andric if (LexicalDC->isRecord()) 3060b57cec5SDimitry Andric Kind = DefaultArgument; 3070b57cec5SDimitry Andric } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) { 30806c3fb27SDimitry Andric if (Var->getMostRecentDecl()->isInline()) 3090b57cec5SDimitry Andric Kind = InlineVariable; 31006c3fb27SDimitry Andric else if (Var->getDeclContext()->isRecord() && IsInNonspecializedTemplate) 31106c3fb27SDimitry Andric Kind = TemplatedVariable; 3120b57cec5SDimitry Andric else if (Var->getDescribedVarTemplate()) 31306c3fb27SDimitry Andric Kind = TemplatedVariable; 3140b57cec5SDimitry Andric else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) { 3150b57cec5SDimitry Andric if (!VTS->isExplicitSpecialization()) 31606c3fb27SDimitry Andric Kind = TemplatedVariable; 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric } else if (isa<FieldDecl>(ManglingContextDecl)) { 3190b57cec5SDimitry Andric Kind = DataMember; 320bdd1243dSDimitry Andric } else if (isa<ImplicitConceptSpecializationDecl>(ManglingContextDecl)) { 321bdd1243dSDimitry Andric Kind = Concept; 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric // Itanium ABI [5.1.7]: 3260b57cec5SDimitry Andric // In the following contexts [...] the one-definition rule requires closure 3270b57cec5SDimitry Andric // types in different translation units to "correspond": 3280b57cec5SDimitry Andric switch (Kind) { 3290b57cec5SDimitry Andric case Normal: { 33006c3fb27SDimitry Andric // -- the bodies of inline or templated functions 3310b57cec5SDimitry Andric if ((IsInNonspecializedTemplate && 3320b57cec5SDimitry Andric !(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) || 3330b57cec5SDimitry Andric isInInlineFunction(CurContext)) { 3340b57cec5SDimitry Andric while (auto *CD = dyn_cast<CapturedDecl>(DC)) 3350b57cec5SDimitry Andric DC = CD->getParent(); 336a7dea167SDimitry Andric return std::make_tuple(&Context.getManglingNumberContext(DC), nullptr); 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric 339a7dea167SDimitry Andric return std::make_tuple(nullptr, nullptr); 3400b57cec5SDimitry Andric } 3410b57cec5SDimitry Andric 342bdd1243dSDimitry Andric case Concept: 343bdd1243dSDimitry Andric // Concept definitions aren't code generated and thus aren't mangled, 344bdd1243dSDimitry Andric // however the ManglingContextDecl is important for the purposes of 345bdd1243dSDimitry Andric // re-forming the template argument list of the lambda for constraint 346bdd1243dSDimitry Andric // evaluation. 3470b57cec5SDimitry Andric case DataMember: 34806c3fb27SDimitry Andric // -- default member initializers 3490b57cec5SDimitry Andric case DefaultArgument: 3500b57cec5SDimitry Andric // -- default arguments appearing in class definitions 3510b57cec5SDimitry Andric case InlineVariable: 35206c3fb27SDimitry Andric case TemplatedVariable: 35306c3fb27SDimitry Andric // -- the initializers of inline or templated variables 354a7dea167SDimitry Andric return std::make_tuple( 355a7dea167SDimitry Andric &Context.getManglingNumberContext(ASTContext::NeedExtraManglingDecl, 356a7dea167SDimitry Andric ManglingContextDecl), 357a7dea167SDimitry Andric ManglingContextDecl); 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric llvm_unreachable("unexpected context"); 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric 36306c3fb27SDimitry Andric static QualType 36406c3fb27SDimitry Andric buildTypeForLambdaCallOperator(Sema &S, clang::CXXRecordDecl *Class, 36506c3fb27SDimitry Andric TemplateParameterList *TemplateParams, 36606c3fb27SDimitry Andric TypeSourceInfo *MethodTypeInfo) { 36706c3fb27SDimitry Andric assert(MethodTypeInfo && "expected a non null type"); 36806c3fb27SDimitry Andric 3690b57cec5SDimitry Andric QualType MethodType = MethodTypeInfo->getType(); 3700b57cec5SDimitry Andric // If a lambda appears in a dependent context or is a generic lambda (has 3710b57cec5SDimitry Andric // template parameters) and has an 'auto' return type, deduce it to a 3720b57cec5SDimitry Andric // dependent type. 3730b57cec5SDimitry Andric if (Class->isDependentContext() || TemplateParams) { 3740b57cec5SDimitry Andric const FunctionProtoType *FPT = MethodType->castAs<FunctionProtoType>(); 3750b57cec5SDimitry Andric QualType Result = FPT->getReturnType(); 3760b57cec5SDimitry Andric if (Result->isUndeducedType()) { 37706c3fb27SDimitry Andric Result = S.SubstAutoTypeDependent(Result); 37806c3fb27SDimitry Andric MethodType = S.Context.getFunctionType(Result, FPT->getParamTypes(), 3790b57cec5SDimitry Andric FPT->getExtProtoInfo()); 3800b57cec5SDimitry Andric } 3810b57cec5SDimitry Andric } 38206c3fb27SDimitry Andric return MethodType; 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3855f757f3fSDimitry Andric // [C++2b] [expr.prim.lambda.closure] p4 3865f757f3fSDimitry Andric // Given a lambda with a lambda-capture, the type of the explicit object 3875f757f3fSDimitry Andric // parameter, if any, of the lambda's function call operator (possibly 3885f757f3fSDimitry Andric // instantiated from a function call operator template) shall be either: 3895f757f3fSDimitry Andric // - the closure type, 390*0fca6ea1SDimitry Andric // - class type publicly and unambiguously derived from the closure type, or 3915f757f3fSDimitry Andric // - a reference to a possibly cv-qualified such type. 392*0fca6ea1SDimitry Andric bool Sema::DiagnoseInvalidExplicitObjectParameterInLambda( 393*0fca6ea1SDimitry Andric CXXMethodDecl *Method, SourceLocation CallLoc) { 3945f757f3fSDimitry Andric if (!isLambdaCallWithExplicitObjectParameter(Method)) 395*0fca6ea1SDimitry Andric return false; 3965f757f3fSDimitry Andric CXXRecordDecl *RD = Method->getParent(); 3975f757f3fSDimitry Andric if (Method->getType()->isDependentType()) 398*0fca6ea1SDimitry Andric return false; 3995f757f3fSDimitry Andric if (RD->isCapturelessLambda()) 400*0fca6ea1SDimitry Andric return false; 401*0fca6ea1SDimitry Andric 402*0fca6ea1SDimitry Andric ParmVarDecl *Param = Method->getParamDecl(0); 403*0fca6ea1SDimitry Andric QualType ExplicitObjectParameterType = Param->getType() 4045f757f3fSDimitry Andric .getNonReferenceType() 4055f757f3fSDimitry Andric .getUnqualifiedType() 4065f757f3fSDimitry Andric .getDesugaredType(getASTContext()); 4075f757f3fSDimitry Andric QualType LambdaType = getASTContext().getRecordType(RD); 4085f757f3fSDimitry Andric if (LambdaType == ExplicitObjectParameterType) 409*0fca6ea1SDimitry Andric return false; 410*0fca6ea1SDimitry Andric 411*0fca6ea1SDimitry Andric // Don't check the same instantiation twice. 412*0fca6ea1SDimitry Andric // 413*0fca6ea1SDimitry Andric // If this call operator is ill-formed, there is no point in issuing 414*0fca6ea1SDimitry Andric // a diagnostic every time it is called because the problem is in the 415*0fca6ea1SDimitry Andric // definition of the derived type, not at the call site. 416*0fca6ea1SDimitry Andric // 417*0fca6ea1SDimitry Andric // FIXME: Move this check to where we instantiate the method? This should 418*0fca6ea1SDimitry Andric // be possible, but the naive approach of just marking the method as invalid 419*0fca6ea1SDimitry Andric // leads to us emitting more diagnostics than we should have to for this case 420*0fca6ea1SDimitry Andric // (1 error here *and* 1 error about there being no matching overload at the 421*0fca6ea1SDimitry Andric // call site). It might be possible to avoid that by also checking if there 422*0fca6ea1SDimitry Andric // is an empty cast path for the method stored in the context (signalling that 423*0fca6ea1SDimitry Andric // we've already diagnosed it) and then just not building the call, but that 424*0fca6ea1SDimitry Andric // doesn't really seem any simpler than diagnosing it at the call site... 425*0fca6ea1SDimitry Andric if (auto It = Context.LambdaCastPaths.find(Method); 426*0fca6ea1SDimitry Andric It != Context.LambdaCastPaths.end()) 427*0fca6ea1SDimitry Andric return It->second.empty(); 428*0fca6ea1SDimitry Andric 429*0fca6ea1SDimitry Andric CXXCastPath &Path = Context.LambdaCastPaths[Method]; 430*0fca6ea1SDimitry Andric CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 431*0fca6ea1SDimitry Andric /*DetectVirtual=*/false); 432*0fca6ea1SDimitry Andric if (!IsDerivedFrom(RD->getLocation(), ExplicitObjectParameterType, LambdaType, 433*0fca6ea1SDimitry Andric Paths)) { 434*0fca6ea1SDimitry Andric Diag(Param->getLocation(), diag::err_invalid_explicit_object_type_in_lambda) 4355f757f3fSDimitry Andric << ExplicitObjectParameterType; 436*0fca6ea1SDimitry Andric return true; 437*0fca6ea1SDimitry Andric } 438*0fca6ea1SDimitry Andric 439*0fca6ea1SDimitry Andric if (Paths.isAmbiguous(LambdaType->getCanonicalTypeUnqualified())) { 440*0fca6ea1SDimitry Andric std::string PathsDisplay = getAmbiguousPathsDisplayString(Paths); 441*0fca6ea1SDimitry Andric Diag(CallLoc, diag::err_explicit_object_lambda_ambiguous_base) 442*0fca6ea1SDimitry Andric << LambdaType << PathsDisplay; 443*0fca6ea1SDimitry Andric return true; 444*0fca6ea1SDimitry Andric } 445*0fca6ea1SDimitry Andric 446*0fca6ea1SDimitry Andric if (CheckBaseClassAccess(CallLoc, LambdaType, ExplicitObjectParameterType, 447*0fca6ea1SDimitry Andric Paths.front(), 448*0fca6ea1SDimitry Andric diag::err_explicit_object_lambda_inaccessible_base)) 449*0fca6ea1SDimitry Andric return true; 450*0fca6ea1SDimitry Andric 451*0fca6ea1SDimitry Andric BuildBasePathArray(Paths, Path); 452*0fca6ea1SDimitry Andric return false; 4535f757f3fSDimitry Andric } 4545f757f3fSDimitry Andric 455a7dea167SDimitry Andric void Sema::handleLambdaNumbering( 456a7dea167SDimitry Andric CXXRecordDecl *Class, CXXMethodDecl *Method, 45706c3fb27SDimitry Andric std::optional<CXXRecordDecl::LambdaNumbering> NumberingOverride) { 45806c3fb27SDimitry Andric if (NumberingOverride) { 45906c3fb27SDimitry Andric Class->setLambdaNumbering(*NumberingOverride); 460a7dea167SDimitry Andric return; 461a7dea167SDimitry Andric } 462a7dea167SDimitry Andric 46306c3fb27SDimitry Andric ContextRAII ManglingContext(*this, Class->getDeclContext()); 46406c3fb27SDimitry Andric 465a7dea167SDimitry Andric auto getMangleNumberingContext = 466a7dea167SDimitry Andric [this](CXXRecordDecl *Class, 467a7dea167SDimitry Andric Decl *ManglingContextDecl) -> MangleNumberingContext * { 468a7dea167SDimitry Andric // Get mangle numbering context if there's any extra decl context. 469a7dea167SDimitry Andric if (ManglingContextDecl) 470a7dea167SDimitry Andric return &Context.getManglingNumberContext( 471a7dea167SDimitry Andric ASTContext::NeedExtraManglingDecl, ManglingContextDecl); 472a7dea167SDimitry Andric // Otherwise, from that lambda's decl context. 473a7dea167SDimitry Andric auto DC = Class->getDeclContext(); 474a7dea167SDimitry Andric while (auto *CD = dyn_cast<CapturedDecl>(DC)) 475a7dea167SDimitry Andric DC = CD->getParent(); 476a7dea167SDimitry Andric return &Context.getManglingNumberContext(DC); 477a7dea167SDimitry Andric }; 478a7dea167SDimitry Andric 47906c3fb27SDimitry Andric CXXRecordDecl::LambdaNumbering Numbering; 480a7dea167SDimitry Andric MangleNumberingContext *MCtx; 48106c3fb27SDimitry Andric std::tie(MCtx, Numbering.ContextDecl) = 482a7dea167SDimitry Andric getCurrentMangleNumberContext(Class->getDeclContext()); 483fe6060f1SDimitry Andric if (!MCtx && (getLangOpts().CUDA || getLangOpts().SYCLIsDevice || 484fe6060f1SDimitry Andric getLangOpts().SYCLIsHost)) { 485a7dea167SDimitry Andric // Force lambda numbering in CUDA/HIP as we need to name lambdas following 486a7dea167SDimitry Andric // ODR. Both device- and host-compilation need to have a consistent naming 487a7dea167SDimitry Andric // on kernel functions. As lambdas are potential part of these `__global__` 488a7dea167SDimitry Andric // function names, they needs numbering following ODR. 489fe6060f1SDimitry Andric // Also force for SYCL, since we need this for the 490fe6060f1SDimitry Andric // __builtin_sycl_unique_stable_name implementation, which depends on lambda 491fe6060f1SDimitry Andric // mangling. 49206c3fb27SDimitry Andric MCtx = getMangleNumberingContext(Class, Numbering.ContextDecl); 493a7dea167SDimitry Andric assert(MCtx && "Retrieving mangle numbering context failed!"); 49406c3fb27SDimitry Andric Numbering.HasKnownInternalLinkage = true; 495a7dea167SDimitry Andric } 496a7dea167SDimitry Andric if (MCtx) { 49706c3fb27SDimitry Andric Numbering.IndexInContext = MCtx->getNextLambdaIndex(); 49806c3fb27SDimitry Andric Numbering.ManglingNumber = MCtx->getManglingNumber(Method); 49906c3fb27SDimitry Andric Numbering.DeviceManglingNumber = MCtx->getDeviceManglingNumber(Method); 50006c3fb27SDimitry Andric Class->setLambdaNumbering(Numbering); 50106c3fb27SDimitry Andric 50206c3fb27SDimitry Andric if (auto *Source = 50306c3fb27SDimitry Andric dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource())) 50406c3fb27SDimitry Andric Source->AssignedLambdaNumbering(Class); 505a7dea167SDimitry Andric } 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric 50806c3fb27SDimitry Andric static void buildLambdaScopeReturnType(Sema &S, LambdaScopeInfo *LSI, 5090b57cec5SDimitry Andric CXXMethodDecl *CallOperator, 51006c3fb27SDimitry Andric bool ExplicitResultType) { 51106c3fb27SDimitry Andric if (ExplicitResultType) { 51206c3fb27SDimitry Andric LSI->HasImplicitReturnType = false; 51306c3fb27SDimitry Andric LSI->ReturnType = CallOperator->getReturnType(); 51406c3fb27SDimitry Andric if (!LSI->ReturnType->isDependentType() && !LSI->ReturnType->isVoidType()) 51506c3fb27SDimitry Andric S.RequireCompleteType(CallOperator->getBeginLoc(), LSI->ReturnType, 51606c3fb27SDimitry Andric diag::err_lambda_incomplete_result); 51706c3fb27SDimitry Andric } else { 51806c3fb27SDimitry Andric LSI->HasImplicitReturnType = true; 51906c3fb27SDimitry Andric } 52006c3fb27SDimitry Andric } 52106c3fb27SDimitry Andric 52206c3fb27SDimitry Andric void Sema::buildLambdaScope(LambdaScopeInfo *LSI, CXXMethodDecl *CallOperator, 5230b57cec5SDimitry Andric SourceRange IntroducerRange, 5240b57cec5SDimitry Andric LambdaCaptureDefault CaptureDefault, 5250b57cec5SDimitry Andric SourceLocation CaptureDefaultLoc, 52606c3fb27SDimitry Andric bool ExplicitParams, bool Mutable) { 5270b57cec5SDimitry Andric LSI->CallOperator = CallOperator; 5280b57cec5SDimitry Andric CXXRecordDecl *LambdaClass = CallOperator->getParent(); 5290b57cec5SDimitry Andric LSI->Lambda = LambdaClass; 5300b57cec5SDimitry Andric if (CaptureDefault == LCD_ByCopy) 5310b57cec5SDimitry Andric LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval; 5320b57cec5SDimitry Andric else if (CaptureDefault == LCD_ByRef) 5330b57cec5SDimitry Andric LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByref; 5340b57cec5SDimitry Andric LSI->CaptureDefaultLoc = CaptureDefaultLoc; 5350b57cec5SDimitry Andric LSI->IntroducerRange = IntroducerRange; 5360b57cec5SDimitry Andric LSI->ExplicitParams = ExplicitParams; 5370b57cec5SDimitry Andric LSI->Mutable = Mutable; 5380b57cec5SDimitry Andric } 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) { 5410b57cec5SDimitry Andric LSI->finishedExplicitCaptures(); 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric 54406c3fb27SDimitry Andric void Sema::ActOnLambdaExplicitTemplateParameterList( 54506c3fb27SDimitry Andric LambdaIntroducer &Intro, SourceLocation LAngleLoc, 54606c3fb27SDimitry Andric ArrayRef<NamedDecl *> TParams, SourceLocation RAngleLoc, 547e8d8bef9SDimitry Andric ExprResult RequiresClause) { 5480b57cec5SDimitry Andric LambdaScopeInfo *LSI = getCurLambda(); 5490b57cec5SDimitry Andric assert(LSI && "Expected a lambda scope"); 5500b57cec5SDimitry Andric assert(LSI->NumExplicitTemplateParams == 0 && 5510b57cec5SDimitry Andric "Already acted on explicit template parameters"); 5520b57cec5SDimitry Andric assert(LSI->TemplateParams.empty() && 5530b57cec5SDimitry Andric "Explicit template parameters should come " 5540b57cec5SDimitry Andric "before invented (auto) ones"); 5550b57cec5SDimitry Andric assert(!TParams.empty() && 5560b57cec5SDimitry Andric "No template parameters to act on"); 5570b57cec5SDimitry Andric LSI->TemplateParams.append(TParams.begin(), TParams.end()); 5580b57cec5SDimitry Andric LSI->NumExplicitTemplateParams = TParams.size(); 5590b57cec5SDimitry Andric LSI->ExplicitTemplateParamsRange = {LAngleLoc, RAngleLoc}; 560e8d8bef9SDimitry Andric LSI->RequiresClause = RequiresClause; 5610b57cec5SDimitry Andric } 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric /// If this expression is an enumerator-like expression of some type 5640b57cec5SDimitry Andric /// T, return the type T; otherwise, return null. 5650b57cec5SDimitry Andric /// 5660b57cec5SDimitry Andric /// Pointer comparisons on the result here should always work because 5670b57cec5SDimitry Andric /// it's derived from either the parent of an EnumConstantDecl 5680b57cec5SDimitry Andric /// (i.e. the definition) or the declaration returned by 5690b57cec5SDimitry Andric /// EnumType::getDecl() (i.e. the definition). 5700b57cec5SDimitry Andric static EnumDecl *findEnumForBlockReturn(Expr *E) { 5710b57cec5SDimitry Andric // An expression is an enumerator-like expression of type T if, 5720b57cec5SDimitry Andric // ignoring parens and parens-like expressions: 5730b57cec5SDimitry Andric E = E->IgnoreParens(); 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andric // - it is an enumerator whose enum type is T or 5760b57cec5SDimitry Andric if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { 5770b57cec5SDimitry Andric if (EnumConstantDecl *D 5780b57cec5SDimitry Andric = dyn_cast<EnumConstantDecl>(DRE->getDecl())) { 5790b57cec5SDimitry Andric return cast<EnumDecl>(D->getDeclContext()); 5800b57cec5SDimitry Andric } 5810b57cec5SDimitry Andric return nullptr; 5820b57cec5SDimitry Andric } 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric // - it is a comma expression whose RHS is an enumerator-like 5850b57cec5SDimitry Andric // expression of type T or 5860b57cec5SDimitry Andric if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { 5870b57cec5SDimitry Andric if (BO->getOpcode() == BO_Comma) 5880b57cec5SDimitry Andric return findEnumForBlockReturn(BO->getRHS()); 5890b57cec5SDimitry Andric return nullptr; 5900b57cec5SDimitry Andric } 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric // - it is a statement-expression whose value expression is an 5930b57cec5SDimitry Andric // enumerator-like expression of type T or 5940b57cec5SDimitry Andric if (StmtExpr *SE = dyn_cast<StmtExpr>(E)) { 5950b57cec5SDimitry Andric if (Expr *last = dyn_cast_or_null<Expr>(SE->getSubStmt()->body_back())) 5960b57cec5SDimitry Andric return findEnumForBlockReturn(last); 5970b57cec5SDimitry Andric return nullptr; 5980b57cec5SDimitry Andric } 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric // - it is a ternary conditional operator (not the GNU ?: 6010b57cec5SDimitry Andric // extension) whose second and third operands are 6020b57cec5SDimitry Andric // enumerator-like expressions of type T or 6030b57cec5SDimitry Andric if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { 6040b57cec5SDimitry Andric if (EnumDecl *ED = findEnumForBlockReturn(CO->getTrueExpr())) 6050b57cec5SDimitry Andric if (ED == findEnumForBlockReturn(CO->getFalseExpr())) 6060b57cec5SDimitry Andric return ED; 6070b57cec5SDimitry Andric return nullptr; 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric // (implicitly:) 6110b57cec5SDimitry Andric // - it is an implicit integral conversion applied to an 6120b57cec5SDimitry Andric // enumerator-like expression of type T or 6130b57cec5SDimitry Andric if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) { 6140b57cec5SDimitry Andric // We can sometimes see integral conversions in valid 6150b57cec5SDimitry Andric // enumerator-like expressions. 6160b57cec5SDimitry Andric if (ICE->getCastKind() == CK_IntegralCast) 6170b57cec5SDimitry Andric return findEnumForBlockReturn(ICE->getSubExpr()); 6180b57cec5SDimitry Andric 6190b57cec5SDimitry Andric // Otherwise, just rely on the type. 6200b57cec5SDimitry Andric } 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric // - it is an expression of that formal enum type. 6230b57cec5SDimitry Andric if (const EnumType *ET = E->getType()->getAs<EnumType>()) { 6240b57cec5SDimitry Andric return ET->getDecl(); 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric // Otherwise, nope. 6280b57cec5SDimitry Andric return nullptr; 6290b57cec5SDimitry Andric } 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andric /// Attempt to find a type T for which the returned expression of the 6320b57cec5SDimitry Andric /// given statement is an enumerator-like expression of that type. 6330b57cec5SDimitry Andric static EnumDecl *findEnumForBlockReturn(ReturnStmt *ret) { 6340b57cec5SDimitry Andric if (Expr *retValue = ret->getRetValue()) 6350b57cec5SDimitry Andric return findEnumForBlockReturn(retValue); 6360b57cec5SDimitry Andric return nullptr; 6370b57cec5SDimitry Andric } 6380b57cec5SDimitry Andric 6390b57cec5SDimitry Andric /// Attempt to find a common type T for which all of the returned 6400b57cec5SDimitry Andric /// expressions in a block are enumerator-like expressions of that 6410b57cec5SDimitry Andric /// type. 6420b57cec5SDimitry Andric static EnumDecl *findCommonEnumForBlockReturns(ArrayRef<ReturnStmt*> returns) { 6430b57cec5SDimitry Andric ArrayRef<ReturnStmt*>::iterator i = returns.begin(), e = returns.end(); 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric // Try to find one for the first return. 6460b57cec5SDimitry Andric EnumDecl *ED = findEnumForBlockReturn(*i); 6470b57cec5SDimitry Andric if (!ED) return nullptr; 6480b57cec5SDimitry Andric 6490b57cec5SDimitry Andric // Check that the rest of the returns have the same enum. 6500b57cec5SDimitry Andric for (++i; i != e; ++i) { 6510b57cec5SDimitry Andric if (findEnumForBlockReturn(*i) != ED) 6520b57cec5SDimitry Andric return nullptr; 6530b57cec5SDimitry Andric } 6540b57cec5SDimitry Andric 6550b57cec5SDimitry Andric // Never infer an anonymous enum type. 6560b57cec5SDimitry Andric if (!ED->hasNameForLinkage()) return nullptr; 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric return ED; 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric /// Adjust the given return statements so that they formally return 6620b57cec5SDimitry Andric /// the given type. It should require, at most, an IntegralCast. 6630b57cec5SDimitry Andric static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt*> returns, 6640b57cec5SDimitry Andric QualType returnType) { 6650b57cec5SDimitry Andric for (ArrayRef<ReturnStmt*>::iterator 6660b57cec5SDimitry Andric i = returns.begin(), e = returns.end(); i != e; ++i) { 6670b57cec5SDimitry Andric ReturnStmt *ret = *i; 6680b57cec5SDimitry Andric Expr *retValue = ret->getRetValue(); 6690b57cec5SDimitry Andric if (S.Context.hasSameType(retValue->getType(), returnType)) 6700b57cec5SDimitry Andric continue; 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric // Right now we only support integral fixup casts. 6730b57cec5SDimitry Andric assert(returnType->isIntegralOrUnscopedEnumerationType()); 6740b57cec5SDimitry Andric assert(retValue->getType()->isIntegralOrUnscopedEnumerationType()); 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(retValue); 6770b57cec5SDimitry Andric 6780b57cec5SDimitry Andric Expr *E = (cleanups ? cleanups->getSubExpr() : retValue); 679e8d8bef9SDimitry Andric E = ImplicitCastExpr::Create(S.Context, returnType, CK_IntegralCast, E, 680fe6060f1SDimitry Andric /*base path*/ nullptr, VK_PRValue, 681e8d8bef9SDimitry Andric FPOptionsOverride()); 6820b57cec5SDimitry Andric if (cleanups) { 6830b57cec5SDimitry Andric cleanups->setSubExpr(E); 6840b57cec5SDimitry Andric } else { 6850b57cec5SDimitry Andric ret->setRetValue(E); 6860b57cec5SDimitry Andric } 6870b57cec5SDimitry Andric } 6880b57cec5SDimitry Andric } 6890b57cec5SDimitry Andric 6900b57cec5SDimitry Andric void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) { 6910b57cec5SDimitry Andric assert(CSI.HasImplicitReturnType); 6920b57cec5SDimitry Andric // If it was ever a placeholder, it had to been deduced to DependentTy. 6930b57cec5SDimitry Andric assert(CSI.ReturnType.isNull() || !CSI.ReturnType->isUndeducedType()); 6940b57cec5SDimitry Andric assert((!isa<LambdaScopeInfo>(CSI) || !getLangOpts().CPlusPlus14) && 6950b57cec5SDimitry Andric "lambda expressions use auto deduction in C++14 onwards"); 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andric // C++ core issue 975: 6980b57cec5SDimitry Andric // If a lambda-expression does not include a trailing-return-type, 6990b57cec5SDimitry Andric // it is as if the trailing-return-type denotes the following type: 7000b57cec5SDimitry Andric // - if there are no return statements in the compound-statement, 7010b57cec5SDimitry Andric // or all return statements return either an expression of type 7020b57cec5SDimitry Andric // void or no expression or braced-init-list, the type void; 7030b57cec5SDimitry Andric // - otherwise, if all return statements return an expression 7040b57cec5SDimitry Andric // and the types of the returned expressions after 7050b57cec5SDimitry Andric // lvalue-to-rvalue conversion (4.1 [conv.lval]), 7060b57cec5SDimitry Andric // array-to-pointer conversion (4.2 [conv.array]), and 7070b57cec5SDimitry Andric // function-to-pointer conversion (4.3 [conv.func]) are the 7080b57cec5SDimitry Andric // same, that common type; 7090b57cec5SDimitry Andric // - otherwise, the program is ill-formed. 7100b57cec5SDimitry Andric // 7110b57cec5SDimitry Andric // C++ core issue 1048 additionally removes top-level cv-qualifiers 7120b57cec5SDimitry Andric // from the types of returned expressions to match the C++14 auto 7130b57cec5SDimitry Andric // deduction rules. 7140b57cec5SDimitry Andric // 7150b57cec5SDimitry Andric // In addition, in blocks in non-C++ modes, if all of the return 7160b57cec5SDimitry Andric // statements are enumerator-like expressions of some type T, where 7170b57cec5SDimitry Andric // T has a name for linkage, then we infer the return type of the 7180b57cec5SDimitry Andric // block to be that type. 7190b57cec5SDimitry Andric 7200b57cec5SDimitry Andric // First case: no return statements, implicit void return type. 7210b57cec5SDimitry Andric ASTContext &Ctx = getASTContext(); 7220b57cec5SDimitry Andric if (CSI.Returns.empty()) { 7230b57cec5SDimitry Andric // It's possible there were simply no /valid/ return statements. 7240b57cec5SDimitry Andric // In this case, the first one we found may have at least given us a type. 7250b57cec5SDimitry Andric if (CSI.ReturnType.isNull()) 7260b57cec5SDimitry Andric CSI.ReturnType = Ctx.VoidTy; 7270b57cec5SDimitry Andric return; 7280b57cec5SDimitry Andric } 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric // Second case: at least one return statement has dependent type. 7310b57cec5SDimitry Andric // Delay type checking until instantiation. 7320b57cec5SDimitry Andric assert(!CSI.ReturnType.isNull() && "We should have a tentative return type."); 7330b57cec5SDimitry Andric if (CSI.ReturnType->isDependentType()) 7340b57cec5SDimitry Andric return; 7350b57cec5SDimitry Andric 7360b57cec5SDimitry Andric // Try to apply the enum-fuzz rule. 7370b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) { 7380b57cec5SDimitry Andric assert(isa<BlockScopeInfo>(CSI)); 7390b57cec5SDimitry Andric const EnumDecl *ED = findCommonEnumForBlockReturns(CSI.Returns); 7400b57cec5SDimitry Andric if (ED) { 7410b57cec5SDimitry Andric CSI.ReturnType = Context.getTypeDeclType(ED); 7420b57cec5SDimitry Andric adjustBlockReturnsToEnum(*this, CSI.Returns, CSI.ReturnType); 7430b57cec5SDimitry Andric return; 7440b57cec5SDimitry Andric } 7450b57cec5SDimitry Andric } 7460b57cec5SDimitry Andric 7470b57cec5SDimitry Andric // Third case: only one return statement. Don't bother doing extra work! 7480b57cec5SDimitry Andric if (CSI.Returns.size() == 1) 7490b57cec5SDimitry Andric return; 7500b57cec5SDimitry Andric 7510b57cec5SDimitry Andric // General case: many return statements. 7520b57cec5SDimitry Andric // Check that they all have compatible return types. 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andric // We require the return types to strictly match here. 7550b57cec5SDimitry Andric // Note that we've already done the required promotions as part of 7560b57cec5SDimitry Andric // processing the return statement. 7570b57cec5SDimitry Andric for (const ReturnStmt *RS : CSI.Returns) { 7580b57cec5SDimitry Andric const Expr *RetE = RS->getRetValue(); 7590b57cec5SDimitry Andric 7600b57cec5SDimitry Andric QualType ReturnType = 7610b57cec5SDimitry Andric (RetE ? RetE->getType() : Context.VoidTy).getUnqualifiedType(); 7620b57cec5SDimitry Andric if (Context.getCanonicalFunctionResultType(ReturnType) == 7630b57cec5SDimitry Andric Context.getCanonicalFunctionResultType(CSI.ReturnType)) { 7640b57cec5SDimitry Andric // Use the return type with the strictest possible nullability annotation. 765bdd1243dSDimitry Andric auto RetTyNullability = ReturnType->getNullability(); 766bdd1243dSDimitry Andric auto BlockNullability = CSI.ReturnType->getNullability(); 7670b57cec5SDimitry Andric if (BlockNullability && 7680b57cec5SDimitry Andric (!RetTyNullability || 7690b57cec5SDimitry Andric hasWeakerNullability(*RetTyNullability, *BlockNullability))) 7700b57cec5SDimitry Andric CSI.ReturnType = ReturnType; 7710b57cec5SDimitry Andric continue; 7720b57cec5SDimitry Andric } 7730b57cec5SDimitry Andric 7740b57cec5SDimitry Andric // FIXME: This is a poor diagnostic for ReturnStmts without expressions. 7750b57cec5SDimitry Andric // TODO: It's possible that the *first* return is the divergent one. 7760b57cec5SDimitry Andric Diag(RS->getBeginLoc(), 7770b57cec5SDimitry Andric diag::err_typecheck_missing_return_type_incompatible) 7780b57cec5SDimitry Andric << ReturnType << CSI.ReturnType << isa<LambdaScopeInfo>(CSI); 7790b57cec5SDimitry Andric // Continue iterating so that we keep emitting diagnostics. 7800b57cec5SDimitry Andric } 7810b57cec5SDimitry Andric } 7820b57cec5SDimitry Andric 7830b57cec5SDimitry Andric QualType Sema::buildLambdaInitCaptureInitialization( 7840b57cec5SDimitry Andric SourceLocation Loc, bool ByRef, SourceLocation EllipsisLoc, 785bdd1243dSDimitry Andric std::optional<unsigned> NumExpansions, IdentifierInfo *Id, 786bdd1243dSDimitry Andric bool IsDirectInit, Expr *&Init) { 7870b57cec5SDimitry Andric // Create an 'auto' or 'auto&' TypeSourceInfo that we can use to 7880b57cec5SDimitry Andric // deduce against. 7890b57cec5SDimitry Andric QualType DeductType = Context.getAutoDeductType(); 7900b57cec5SDimitry Andric TypeLocBuilder TLB; 79155e4f9d5SDimitry Andric AutoTypeLoc TL = TLB.push<AutoTypeLoc>(DeductType); 79255e4f9d5SDimitry Andric TL.setNameLoc(Loc); 7930b57cec5SDimitry Andric if (ByRef) { 7940b57cec5SDimitry Andric DeductType = BuildReferenceType(DeductType, true, Loc, Id); 7950b57cec5SDimitry Andric assert(!DeductType.isNull() && "can't build reference to auto"); 7960b57cec5SDimitry Andric TLB.push<ReferenceTypeLoc>(DeductType).setSigilLoc(Loc); 7970b57cec5SDimitry Andric } 7980b57cec5SDimitry Andric if (EllipsisLoc.isValid()) { 7990b57cec5SDimitry Andric if (Init->containsUnexpandedParameterPack()) { 8005ffd83dbSDimitry Andric Diag(EllipsisLoc, getLangOpts().CPlusPlus20 8010b57cec5SDimitry Andric ? diag::warn_cxx17_compat_init_capture_pack 8020b57cec5SDimitry Andric : diag::ext_init_capture_pack); 803e63539f3SDimitry Andric DeductType = Context.getPackExpansionType(DeductType, NumExpansions, 804e63539f3SDimitry Andric /*ExpectPackInType=*/false); 8050b57cec5SDimitry Andric TLB.push<PackExpansionTypeLoc>(DeductType).setEllipsisLoc(EllipsisLoc); 8060b57cec5SDimitry Andric } else { 8070b57cec5SDimitry Andric // Just ignore the ellipsis for now and form a non-pack variable. We'll 8080b57cec5SDimitry Andric // diagnose this later when we try to capture it. 8090b57cec5SDimitry Andric } 8100b57cec5SDimitry Andric } 8110b57cec5SDimitry Andric TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType); 8120b57cec5SDimitry Andric 8130b57cec5SDimitry Andric // Deduce the type of the init capture. 8140b57cec5SDimitry Andric QualType DeducedType = deduceVarTypeFromInitializer( 8150b57cec5SDimitry Andric /*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI, 8160b57cec5SDimitry Andric SourceRange(Loc, Loc), IsDirectInit, Init); 8170b57cec5SDimitry Andric if (DeducedType.isNull()) 8180b57cec5SDimitry Andric return QualType(); 8190b57cec5SDimitry Andric 8200b57cec5SDimitry Andric // Are we a non-list direct initialization? 8210b57cec5SDimitry Andric ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init); 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric // Perform initialization analysis and ensure any implicit conversions 8240b57cec5SDimitry Andric // (such as lvalue-to-rvalue) are enforced. 8250b57cec5SDimitry Andric InitializedEntity Entity = 8260b57cec5SDimitry Andric InitializedEntity::InitializeLambdaCapture(Id, DeducedType, Loc); 8270b57cec5SDimitry Andric InitializationKind Kind = 8280b57cec5SDimitry Andric IsDirectInit 8290b57cec5SDimitry Andric ? (CXXDirectInit ? InitializationKind::CreateDirect( 8300b57cec5SDimitry Andric Loc, Init->getBeginLoc(), Init->getEndLoc()) 8310b57cec5SDimitry Andric : InitializationKind::CreateDirectList(Loc)) 8320b57cec5SDimitry Andric : InitializationKind::CreateCopy(Loc, Init->getBeginLoc()); 8330b57cec5SDimitry Andric 8340b57cec5SDimitry Andric MultiExprArg Args = Init; 8350b57cec5SDimitry Andric if (CXXDirectInit) 8360b57cec5SDimitry Andric Args = 8370b57cec5SDimitry Andric MultiExprArg(CXXDirectInit->getExprs(), CXXDirectInit->getNumExprs()); 8380b57cec5SDimitry Andric QualType DclT; 8390b57cec5SDimitry Andric InitializationSequence InitSeq(*this, Entity, Kind, Args); 8400b57cec5SDimitry Andric ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT); 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric if (Result.isInvalid()) 8430b57cec5SDimitry Andric return QualType(); 8440b57cec5SDimitry Andric 8450b57cec5SDimitry Andric Init = Result.getAs<Expr>(); 8460b57cec5SDimitry Andric return DeducedType; 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric 84906c3fb27SDimitry Andric VarDecl *Sema::createLambdaInitCaptureVarDecl( 85006c3fb27SDimitry Andric SourceLocation Loc, QualType InitCaptureType, SourceLocation EllipsisLoc, 85106c3fb27SDimitry Andric IdentifierInfo *Id, unsigned InitStyle, Expr *Init, DeclContext *DeclCtx) { 8520b57cec5SDimitry Andric // FIXME: Retain the TypeSourceInfo from buildLambdaInitCaptureInitialization 8530b57cec5SDimitry Andric // rather than reconstructing it here. 8540b57cec5SDimitry Andric TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo(InitCaptureType, Loc); 8550b57cec5SDimitry Andric if (auto PETL = TSI->getTypeLoc().getAs<PackExpansionTypeLoc>()) 8560b57cec5SDimitry Andric PETL.setEllipsisLoc(EllipsisLoc); 8570b57cec5SDimitry Andric 8580b57cec5SDimitry Andric // Create a dummy variable representing the init-capture. This is not actually 8590b57cec5SDimitry Andric // used as a variable, and only exists as a way to name and refer to the 8600b57cec5SDimitry Andric // init-capture. 8610b57cec5SDimitry Andric // FIXME: Pass in separate source locations for '&' and identifier. 86206c3fb27SDimitry Andric VarDecl *NewVD = VarDecl::Create(Context, DeclCtx, Loc, Loc, Id, 86306c3fb27SDimitry Andric InitCaptureType, TSI, SC_Auto); 8640b57cec5SDimitry Andric NewVD->setInitCapture(true); 8650b57cec5SDimitry Andric NewVD->setReferenced(true); 8660b57cec5SDimitry Andric // FIXME: Pass in a VarDecl::InitializationStyle. 8670b57cec5SDimitry Andric NewVD->setInitStyle(static_cast<VarDecl::InitializationStyle>(InitStyle)); 8680b57cec5SDimitry Andric NewVD->markUsed(Context); 8690b57cec5SDimitry Andric NewVD->setInit(Init); 870a7dea167SDimitry Andric if (NewVD->isParameterPack()) 871a7dea167SDimitry Andric getCurLambda()->LocalPacks.push_back(NewVD); 8720b57cec5SDimitry Andric return NewVD; 8730b57cec5SDimitry Andric } 8740b57cec5SDimitry Andric 87506c3fb27SDimitry Andric void Sema::addInitCapture(LambdaScopeInfo *LSI, VarDecl *Var, bool ByRef) { 8760b57cec5SDimitry Andric assert(Var->isInitCapture() && "init capture flag should be set"); 87706c3fb27SDimitry Andric LSI->addCapture(Var, /*isBlock=*/false, ByRef, 87806c3fb27SDimitry Andric /*isNested=*/false, Var->getLocation(), SourceLocation(), 87906c3fb27SDimitry Andric Var->getType(), /*Invalid=*/false); 8800b57cec5SDimitry Andric } 8810b57cec5SDimitry Andric 88206c3fb27SDimitry Andric // Unlike getCurLambda, getCurrentLambdaScopeUnsafe doesn't 88306c3fb27SDimitry Andric // check that the current lambda is in a consistent or fully constructed state. 88406c3fb27SDimitry Andric static LambdaScopeInfo *getCurrentLambdaScopeUnsafe(Sema &S) { 88506c3fb27SDimitry Andric assert(!S.FunctionScopes.empty()); 88606c3fb27SDimitry Andric return cast<LambdaScopeInfo>(S.FunctionScopes[S.FunctionScopes.size() - 1]); 88706c3fb27SDimitry Andric } 88806c3fb27SDimitry Andric 88906c3fb27SDimitry Andric static TypeSourceInfo * 89006c3fb27SDimitry Andric getDummyLambdaType(Sema &S, SourceLocation Loc = SourceLocation()) { 89106c3fb27SDimitry Andric // C++11 [expr.prim.lambda]p4: 89206c3fb27SDimitry Andric // If a lambda-expression does not include a lambda-declarator, it is as 89306c3fb27SDimitry Andric // if the lambda-declarator were (). 89406c3fb27SDimitry Andric FunctionProtoType::ExtProtoInfo EPI(S.Context.getDefaultCallingConvention( 89506c3fb27SDimitry Andric /*IsVariadic=*/false, /*IsCXXMethod=*/true)); 89606c3fb27SDimitry Andric EPI.HasTrailingReturn = true; 89706c3fb27SDimitry Andric EPI.TypeQuals.addConst(); 89806c3fb27SDimitry Andric LangAS AS = S.getDefaultCXXMethodAddrSpace(); 89906c3fb27SDimitry Andric if (AS != LangAS::Default) 90006c3fb27SDimitry Andric EPI.TypeQuals.addAddressSpace(AS); 90106c3fb27SDimitry Andric 90206c3fb27SDimitry Andric // C++1y [expr.prim.lambda]: 90306c3fb27SDimitry Andric // The lambda return type is 'auto', which is replaced by the 90406c3fb27SDimitry Andric // trailing-return type if provided and/or deduced from 'return' 90506c3fb27SDimitry Andric // statements 90606c3fb27SDimitry Andric // We don't do this before C++1y, because we don't support deduced return 90706c3fb27SDimitry Andric // types there. 90806c3fb27SDimitry Andric QualType DefaultTypeForNoTrailingReturn = S.getLangOpts().CPlusPlus14 90906c3fb27SDimitry Andric ? S.Context.getAutoDeductType() 91006c3fb27SDimitry Andric : S.Context.DependentTy; 91106c3fb27SDimitry Andric QualType MethodTy = S.Context.getFunctionType(DefaultTypeForNoTrailingReturn, 91206c3fb27SDimitry Andric std::nullopt, EPI); 91306c3fb27SDimitry Andric return S.Context.getTrivialTypeSourceInfo(MethodTy, Loc); 91406c3fb27SDimitry Andric } 91506c3fb27SDimitry Andric 91606c3fb27SDimitry Andric static TypeSourceInfo *getLambdaType(Sema &S, LambdaIntroducer &Intro, 91706c3fb27SDimitry Andric Declarator &ParamInfo, Scope *CurScope, 91806c3fb27SDimitry Andric SourceLocation Loc, 91906c3fb27SDimitry Andric bool &ExplicitResultType) { 92006c3fb27SDimitry Andric 92106c3fb27SDimitry Andric ExplicitResultType = false; 92206c3fb27SDimitry Andric 92306c3fb27SDimitry Andric assert( 92406c3fb27SDimitry Andric (ParamInfo.getDeclSpec().getStorageClassSpec() == 92506c3fb27SDimitry Andric DeclSpec::SCS_unspecified || 92606c3fb27SDimitry Andric ParamInfo.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static) && 92706c3fb27SDimitry Andric "Unexpected storage specifier"); 92806c3fb27SDimitry Andric bool IsLambdaStatic = 92906c3fb27SDimitry Andric ParamInfo.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static; 93006c3fb27SDimitry Andric 93106c3fb27SDimitry Andric TypeSourceInfo *MethodTyInfo; 93206c3fb27SDimitry Andric 93306c3fb27SDimitry Andric if (ParamInfo.getNumTypeObjects() == 0) { 93406c3fb27SDimitry Andric MethodTyInfo = getDummyLambdaType(S, Loc); 93506c3fb27SDimitry Andric } else { 9365f757f3fSDimitry Andric // Check explicit parameters 9375f757f3fSDimitry Andric S.CheckExplicitObjectLambda(ParamInfo); 9385f757f3fSDimitry Andric 93906c3fb27SDimitry Andric DeclaratorChunk::FunctionTypeInfo &FTI = ParamInfo.getFunctionTypeInfo(); 9405f757f3fSDimitry Andric 9415f757f3fSDimitry Andric bool HasExplicitObjectParameter = 9425f757f3fSDimitry Andric ParamInfo.isExplicitObjectMemberFunction(); 9435f757f3fSDimitry Andric 94406c3fb27SDimitry Andric ExplicitResultType = FTI.hasTrailingReturnType(); 9455f757f3fSDimitry Andric if (!FTI.hasMutableQualifier() && !IsLambdaStatic && 9465f757f3fSDimitry Andric !HasExplicitObjectParameter) 94706c3fb27SDimitry Andric FTI.getOrCreateMethodQualifiers().SetTypeQual(DeclSpec::TQ_const, Loc); 94806c3fb27SDimitry Andric 94906c3fb27SDimitry Andric if (ExplicitResultType && S.getLangOpts().HLSL) { 95006c3fb27SDimitry Andric QualType RetTy = FTI.getTrailingReturnType().get(); 95106c3fb27SDimitry Andric if (!RetTy.isNull()) { 95206c3fb27SDimitry Andric // HLSL does not support specifying an address space on a lambda return 95306c3fb27SDimitry Andric // type. 95406c3fb27SDimitry Andric LangAS AddressSpace = RetTy.getAddressSpace(); 95506c3fb27SDimitry Andric if (AddressSpace != LangAS::Default) 95606c3fb27SDimitry Andric S.Diag(FTI.getTrailingReturnTypeLoc(), 95706c3fb27SDimitry Andric diag::err_return_value_with_address_space); 95806c3fb27SDimitry Andric } 95906c3fb27SDimitry Andric } 96006c3fb27SDimitry Andric 9617a6dacacSDimitry Andric MethodTyInfo = S.GetTypeForDeclarator(ParamInfo); 96206c3fb27SDimitry Andric assert(MethodTyInfo && "no type from lambda-declarator"); 96306c3fb27SDimitry Andric 96406c3fb27SDimitry Andric // Check for unexpanded parameter packs in the method type. 96506c3fb27SDimitry Andric if (MethodTyInfo->getType()->containsUnexpandedParameterPack()) 96606c3fb27SDimitry Andric S.DiagnoseUnexpandedParameterPack(Intro.Range.getBegin(), MethodTyInfo, 96706c3fb27SDimitry Andric S.UPPC_DeclarationType); 96806c3fb27SDimitry Andric } 96906c3fb27SDimitry Andric return MethodTyInfo; 97006c3fb27SDimitry Andric } 97106c3fb27SDimitry Andric 97206c3fb27SDimitry Andric CXXMethodDecl *Sema::CreateLambdaCallOperator(SourceRange IntroducerRange, 97306c3fb27SDimitry Andric CXXRecordDecl *Class) { 97406c3fb27SDimitry Andric 97506c3fb27SDimitry Andric // C++20 [expr.prim.lambda.closure]p3: 97606c3fb27SDimitry Andric // The closure type for a lambda-expression has a public inline function 97706c3fb27SDimitry Andric // call operator (for a non-generic lambda) or function call operator 97806c3fb27SDimitry Andric // template (for a generic lambda) whose parameters and return type are 97906c3fb27SDimitry Andric // described by the lambda-expression's parameter-declaration-clause 98006c3fb27SDimitry Andric // and trailing-return-type respectively. 98106c3fb27SDimitry Andric DeclarationName MethodName = 98206c3fb27SDimitry Andric Context.DeclarationNames.getCXXOperatorName(OO_Call); 98306c3fb27SDimitry Andric DeclarationNameLoc MethodNameLoc = 98406c3fb27SDimitry Andric DeclarationNameLoc::makeCXXOperatorNameLoc(IntroducerRange.getBegin()); 98506c3fb27SDimitry Andric CXXMethodDecl *Method = CXXMethodDecl::Create( 98606c3fb27SDimitry Andric Context, Class, SourceLocation(), 98706c3fb27SDimitry Andric DeclarationNameInfo(MethodName, IntroducerRange.getBegin(), 98806c3fb27SDimitry Andric MethodNameLoc), 98906c3fb27SDimitry Andric QualType(), /*Tinfo=*/nullptr, SC_None, 99006c3fb27SDimitry Andric getCurFPFeatures().isFPConstrained(), 99106c3fb27SDimitry Andric /*isInline=*/true, ConstexprSpecKind::Unspecified, SourceLocation(), 99206c3fb27SDimitry Andric /*TrailingRequiresClause=*/nullptr); 99306c3fb27SDimitry Andric Method->setAccess(AS_public); 99406c3fb27SDimitry Andric return Method; 99506c3fb27SDimitry Andric } 99606c3fb27SDimitry Andric 9975f757f3fSDimitry Andric void Sema::AddTemplateParametersToLambdaCallOperator( 9985f757f3fSDimitry Andric CXXMethodDecl *CallOperator, CXXRecordDecl *Class, 9995f757f3fSDimitry Andric TemplateParameterList *TemplateParams) { 10005f757f3fSDimitry Andric assert(TemplateParams && "no template parameters"); 10015f757f3fSDimitry Andric FunctionTemplateDecl *TemplateMethod = FunctionTemplateDecl::Create( 10025f757f3fSDimitry Andric Context, Class, CallOperator->getLocation(), CallOperator->getDeclName(), 10035f757f3fSDimitry Andric TemplateParams, CallOperator); 10045f757f3fSDimitry Andric TemplateMethod->setAccess(AS_public); 10055f757f3fSDimitry Andric CallOperator->setDescribedFunctionTemplate(TemplateMethod); 10065f757f3fSDimitry Andric } 10075f757f3fSDimitry Andric 100806c3fb27SDimitry Andric void Sema::CompleteLambdaCallOperator( 100906c3fb27SDimitry Andric CXXMethodDecl *Method, SourceLocation LambdaLoc, 101006c3fb27SDimitry Andric SourceLocation CallOperatorLoc, Expr *TrailingRequiresClause, 101106c3fb27SDimitry Andric TypeSourceInfo *MethodTyInfo, ConstexprSpecKind ConstexprKind, 101206c3fb27SDimitry Andric StorageClass SC, ArrayRef<ParmVarDecl *> Params, 101306c3fb27SDimitry Andric bool HasExplicitResultType) { 101406c3fb27SDimitry Andric 101506c3fb27SDimitry Andric LambdaScopeInfo *LSI = getCurrentLambdaScopeUnsafe(*this); 101606c3fb27SDimitry Andric 101706c3fb27SDimitry Andric if (TrailingRequiresClause) 101806c3fb27SDimitry Andric Method->setTrailingRequiresClause(TrailingRequiresClause); 101906c3fb27SDimitry Andric 102006c3fb27SDimitry Andric TemplateParameterList *TemplateParams = 102106c3fb27SDimitry Andric getGenericLambdaTemplateParameterList(LSI, *this); 102206c3fb27SDimitry Andric 102306c3fb27SDimitry Andric DeclContext *DC = Method->getLexicalDeclContext(); 102406c3fb27SDimitry Andric Method->setLexicalDeclContext(LSI->Lambda); 102506c3fb27SDimitry Andric if (TemplateParams) { 10265f757f3fSDimitry Andric FunctionTemplateDecl *TemplateMethod = 10275f757f3fSDimitry Andric Method->getDescribedFunctionTemplate(); 10285f757f3fSDimitry Andric assert(TemplateMethod && 10295f757f3fSDimitry Andric "AddTemplateParametersToLambdaCallOperator should have been called"); 10305f757f3fSDimitry Andric 103106c3fb27SDimitry Andric LSI->Lambda->addDecl(TemplateMethod); 103206c3fb27SDimitry Andric TemplateMethod->setLexicalDeclContext(DC); 103306c3fb27SDimitry Andric } else { 103406c3fb27SDimitry Andric LSI->Lambda->addDecl(Method); 103506c3fb27SDimitry Andric } 103606c3fb27SDimitry Andric LSI->Lambda->setLambdaIsGeneric(TemplateParams); 103706c3fb27SDimitry Andric LSI->Lambda->setLambdaTypeInfo(MethodTyInfo); 103806c3fb27SDimitry Andric 103906c3fb27SDimitry Andric Method->setLexicalDeclContext(DC); 104006c3fb27SDimitry Andric Method->setLocation(LambdaLoc); 104106c3fb27SDimitry Andric Method->setInnerLocStart(CallOperatorLoc); 104206c3fb27SDimitry Andric Method->setTypeSourceInfo(MethodTyInfo); 104306c3fb27SDimitry Andric Method->setType(buildTypeForLambdaCallOperator(*this, LSI->Lambda, 104406c3fb27SDimitry Andric TemplateParams, MethodTyInfo)); 104506c3fb27SDimitry Andric Method->setConstexprKind(ConstexprKind); 104606c3fb27SDimitry Andric Method->setStorageClass(SC); 104706c3fb27SDimitry Andric if (!Params.empty()) { 104806c3fb27SDimitry Andric CheckParmsForFunctionDef(Params, /*CheckParameterNames=*/false); 104906c3fb27SDimitry Andric Method->setParams(Params); 105006c3fb27SDimitry Andric for (auto P : Method->parameters()) { 105106c3fb27SDimitry Andric assert(P && "null in a parameter list"); 105206c3fb27SDimitry Andric P->setOwningFunction(Method); 105306c3fb27SDimitry Andric } 105406c3fb27SDimitry Andric } 105506c3fb27SDimitry Andric 105606c3fb27SDimitry Andric buildLambdaScopeReturnType(*this, LSI, Method, HasExplicitResultType); 105706c3fb27SDimitry Andric } 105806c3fb27SDimitry Andric 105906c3fb27SDimitry Andric void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, 106006c3fb27SDimitry Andric Scope *CurrentScope) { 106106c3fb27SDimitry Andric 106206c3fb27SDimitry Andric LambdaScopeInfo *LSI = getCurLambda(); 10630b57cec5SDimitry Andric assert(LSI && "LambdaScopeInfo should be on stack!"); 10640b57cec5SDimitry Andric 106506c3fb27SDimitry Andric if (Intro.Default == LCD_ByCopy) 106606c3fb27SDimitry Andric LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval; 106706c3fb27SDimitry Andric else if (Intro.Default == LCD_ByRef) 106806c3fb27SDimitry Andric LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByref; 106906c3fb27SDimitry Andric LSI->CaptureDefaultLoc = Intro.DefaultLoc; 107006c3fb27SDimitry Andric LSI->IntroducerRange = Intro.Range; 107106c3fb27SDimitry Andric LSI->AfterParameterList = false; 107206c3fb27SDimitry Andric 107306c3fb27SDimitry Andric assert(LSI->NumExplicitTemplateParams == 0); 107406c3fb27SDimitry Andric 10750b57cec5SDimitry Andric // Determine if we're within a context where we know that the lambda will 10760b57cec5SDimitry Andric // be dependent, because there are template parameters in scope. 107781ad6265SDimitry Andric CXXRecordDecl::LambdaDependencyKind LambdaDependencyKind = 107881ad6265SDimitry Andric CXXRecordDecl::LDK_Unknown; 1079*0fca6ea1SDimitry Andric if (CurScope->getTemplateParamParent() != nullptr) { 108081ad6265SDimitry Andric LambdaDependencyKind = CXXRecordDecl::LDK_AlwaysDependent; 1081*0fca6ea1SDimitry Andric } else if (Scope *P = CurScope->getParent()) { 1082*0fca6ea1SDimitry Andric // Given a lambda defined inside a requires expression, 1083*0fca6ea1SDimitry Andric // 1084*0fca6ea1SDimitry Andric // struct S { 1085*0fca6ea1SDimitry Andric // S(auto var) requires requires { [&] -> decltype(var) { }; } 1086*0fca6ea1SDimitry Andric // {} 1087*0fca6ea1SDimitry Andric // }; 1088*0fca6ea1SDimitry Andric // 1089*0fca6ea1SDimitry Andric // The parameter var is not injected into the function Decl at the point of 1090*0fca6ea1SDimitry Andric // parsing lambda. In such scenarios, perceiving it as dependent could 1091*0fca6ea1SDimitry Andric // result in the constraint being evaluated, which matches what GCC does. 1092*0fca6ea1SDimitry Andric while (P->getEntity() && P->getEntity()->isRequiresExprBody()) 1093*0fca6ea1SDimitry Andric P = P->getParent(); 1094*0fca6ea1SDimitry Andric if (P->isFunctionDeclarationScope() && 1095*0fca6ea1SDimitry Andric llvm::any_of(P->decls(), [](Decl *D) { 1096*0fca6ea1SDimitry Andric return isa<ParmVarDecl>(D) && 1097*0fca6ea1SDimitry Andric cast<ParmVarDecl>(D)->getType()->isTemplateTypeParmType(); 1098*0fca6ea1SDimitry Andric })) 109981ad6265SDimitry Andric LambdaDependencyKind = CXXRecordDecl::LDK_AlwaysDependent; 11000b57cec5SDimitry Andric } 11010b57cec5SDimitry Andric 110281ad6265SDimitry Andric CXXRecordDecl *Class = createLambdaClosureType( 110306c3fb27SDimitry Andric Intro.Range, /*Info=*/nullptr, LambdaDependencyKind, Intro.Default); 110406c3fb27SDimitry Andric LSI->Lambda = Class; 11050b57cec5SDimitry Andric 110606c3fb27SDimitry Andric CXXMethodDecl *Method = CreateLambdaCallOperator(Intro.Range, Class); 110706c3fb27SDimitry Andric LSI->CallOperator = Method; 110806c3fb27SDimitry Andric Method->setLexicalDeclContext(CurContext); 11090b57cec5SDimitry Andric 11100b57cec5SDimitry Andric PushDeclContext(CurScope, Method); 11110b57cec5SDimitry Andric 111206c3fb27SDimitry Andric bool ContainsUnexpandedParameterPack = false; 11130b57cec5SDimitry Andric 11140b57cec5SDimitry Andric // Distinct capture names, for diagnostics. 111506c3fb27SDimitry Andric llvm::DenseMap<IdentifierInfo *, ValueDecl *> CaptureNames; 11160b57cec5SDimitry Andric 11170b57cec5SDimitry Andric // Handle explicit captures. 111806c3fb27SDimitry Andric SourceLocation PrevCaptureLoc = 111906c3fb27SDimitry Andric Intro.Default == LCD_None ? Intro.Range.getBegin() : Intro.DefaultLoc; 11200b57cec5SDimitry Andric for (auto C = Intro.Captures.begin(), E = Intro.Captures.end(); C != E; 11210b57cec5SDimitry Andric PrevCaptureLoc = C->Loc, ++C) { 11220b57cec5SDimitry Andric if (C->Kind == LCK_This || C->Kind == LCK_StarThis) { 11230b57cec5SDimitry Andric if (C->Kind == LCK_StarThis) 11240b57cec5SDimitry Andric Diag(C->Loc, !getLangOpts().CPlusPlus17 11250b57cec5SDimitry Andric ? diag::ext_star_this_lambda_capture_cxx17 11260b57cec5SDimitry Andric : diag::warn_cxx14_compat_star_this_lambda_capture); 11270b57cec5SDimitry Andric 11280b57cec5SDimitry Andric // C++11 [expr.prim.lambda]p8: 11290b57cec5SDimitry Andric // An identifier or this shall not appear more than once in a 11300b57cec5SDimitry Andric // lambda-capture. 11310b57cec5SDimitry Andric if (LSI->isCXXThisCaptured()) { 11320b57cec5SDimitry Andric Diag(C->Loc, diag::err_capture_more_than_once) 11330b57cec5SDimitry Andric << "'this'" << SourceRange(LSI->getCXXThisCapture().getLocation()) 11340b57cec5SDimitry Andric << FixItHint::CreateRemoval( 11350b57cec5SDimitry Andric SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); 11360b57cec5SDimitry Andric continue; 11370b57cec5SDimitry Andric } 11380b57cec5SDimitry Andric 113906c3fb27SDimitry Andric // C++20 [expr.prim.lambda]p8: 11400b57cec5SDimitry Andric // If a lambda-capture includes a capture-default that is =, 11410b57cec5SDimitry Andric // each simple-capture of that lambda-capture shall be of the form 11420b57cec5SDimitry Andric // "&identifier", "this", or "* this". [ Note: The form [&,this] is 11430b57cec5SDimitry Andric // redundant but accepted for compatibility with ISO C++14. --end note ] 11440b57cec5SDimitry Andric if (Intro.Default == LCD_ByCopy && C->Kind != LCK_StarThis) 11455ffd83dbSDimitry Andric Diag(C->Loc, !getLangOpts().CPlusPlus20 11465ffd83dbSDimitry Andric ? diag::ext_equals_this_lambda_capture_cxx20 11470b57cec5SDimitry Andric : diag::warn_cxx17_compat_equals_this_lambda_capture); 11480b57cec5SDimitry Andric 11490b57cec5SDimitry Andric // C++11 [expr.prim.lambda]p12: 11500b57cec5SDimitry Andric // If this is captured by a local lambda expression, its nearest 11510b57cec5SDimitry Andric // enclosing function shall be a non-static member function. 11520b57cec5SDimitry Andric QualType ThisCaptureType = getCurrentThisType(); 11530b57cec5SDimitry Andric if (ThisCaptureType.isNull()) { 11540b57cec5SDimitry Andric Diag(C->Loc, diag::err_this_capture) << true; 11550b57cec5SDimitry Andric continue; 11560b57cec5SDimitry Andric } 11570b57cec5SDimitry Andric 11580b57cec5SDimitry Andric CheckCXXThisCapture(C->Loc, /*Explicit=*/true, /*BuildAndDiagnose*/ true, 11590b57cec5SDimitry Andric /*FunctionScopeIndexToStopAtPtr*/ nullptr, 11600b57cec5SDimitry Andric C->Kind == LCK_StarThis); 11610b57cec5SDimitry Andric if (!LSI->Captures.empty()) 11620b57cec5SDimitry Andric LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; 11630b57cec5SDimitry Andric continue; 11640b57cec5SDimitry Andric } 11650b57cec5SDimitry Andric 11660b57cec5SDimitry Andric assert(C->Id && "missing identifier for capture"); 11670b57cec5SDimitry Andric 11680b57cec5SDimitry Andric if (C->Init.isInvalid()) 11690b57cec5SDimitry Andric continue; 11700b57cec5SDimitry Andric 1171bdd1243dSDimitry Andric ValueDecl *Var = nullptr; 11720b57cec5SDimitry Andric if (C->Init.isUsable()) { 11730b57cec5SDimitry Andric Diag(C->Loc, getLangOpts().CPlusPlus14 11740b57cec5SDimitry Andric ? diag::warn_cxx11_compat_init_capture 11750b57cec5SDimitry Andric : diag::ext_init_capture); 11760b57cec5SDimitry Andric 11770b57cec5SDimitry Andric // If the initializer expression is usable, but the InitCaptureType 11780b57cec5SDimitry Andric // is not, then an error has occurred - so ignore the capture for now. 11790b57cec5SDimitry Andric // for e.g., [n{0}] { }; <-- if no <initializer_list> is included. 11800b57cec5SDimitry Andric // FIXME: we should create the init capture variable and mark it invalid 11810b57cec5SDimitry Andric // in this case. 11820b57cec5SDimitry Andric if (C->InitCaptureType.get().isNull()) 11830b57cec5SDimitry Andric continue; 11840b57cec5SDimitry Andric 11850b57cec5SDimitry Andric if (C->Init.get()->containsUnexpandedParameterPack() && 11860b57cec5SDimitry Andric !C->InitCaptureType.get()->getAs<PackExpansionType>()) 1187a7dea167SDimitry Andric DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer); 11880b57cec5SDimitry Andric 11890b57cec5SDimitry Andric unsigned InitStyle; 11900b57cec5SDimitry Andric switch (C->InitKind) { 11910b57cec5SDimitry Andric case LambdaCaptureInitKind::NoInit: 11920b57cec5SDimitry Andric llvm_unreachable("not an init-capture?"); 11930b57cec5SDimitry Andric case LambdaCaptureInitKind::CopyInit: 11940b57cec5SDimitry Andric InitStyle = VarDecl::CInit; 11950b57cec5SDimitry Andric break; 11960b57cec5SDimitry Andric case LambdaCaptureInitKind::DirectInit: 11970b57cec5SDimitry Andric InitStyle = VarDecl::CallInit; 11980b57cec5SDimitry Andric break; 11990b57cec5SDimitry Andric case LambdaCaptureInitKind::ListInit: 12000b57cec5SDimitry Andric InitStyle = VarDecl::ListInit; 12010b57cec5SDimitry Andric break; 12020b57cec5SDimitry Andric } 12030b57cec5SDimitry Andric Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(), 12040b57cec5SDimitry Andric C->EllipsisLoc, C->Id, InitStyle, 120506c3fb27SDimitry Andric C->Init.get(), Method); 120606c3fb27SDimitry Andric assert(Var && "createLambdaInitCaptureVarDecl returned a null VarDecl?"); 120706c3fb27SDimitry Andric if (auto *V = dyn_cast<VarDecl>(Var)) 120806c3fb27SDimitry Andric CheckShadow(CurrentScope, V); 120906c3fb27SDimitry Andric PushOnScopeChains(Var, CurrentScope, false); 12100b57cec5SDimitry Andric } else { 12110b57cec5SDimitry Andric assert(C->InitKind == LambdaCaptureInitKind::NoInit && 12120b57cec5SDimitry Andric "init capture has valid but null init?"); 12130b57cec5SDimitry Andric 12140b57cec5SDimitry Andric // C++11 [expr.prim.lambda]p8: 12150b57cec5SDimitry Andric // If a lambda-capture includes a capture-default that is &, the 12160b57cec5SDimitry Andric // identifiers in the lambda-capture shall not be preceded by &. 12170b57cec5SDimitry Andric // If a lambda-capture includes a capture-default that is =, [...] 12180b57cec5SDimitry Andric // each identifier it contains shall be preceded by &. 12190b57cec5SDimitry Andric if (C->Kind == LCK_ByRef && Intro.Default == LCD_ByRef) { 12200b57cec5SDimitry Andric Diag(C->Loc, diag::err_reference_capture_with_reference_default) 12210b57cec5SDimitry Andric << FixItHint::CreateRemoval( 12220b57cec5SDimitry Andric SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); 12230b57cec5SDimitry Andric continue; 12240b57cec5SDimitry Andric } else if (C->Kind == LCK_ByCopy && Intro.Default == LCD_ByCopy) { 12250b57cec5SDimitry Andric Diag(C->Loc, diag::err_copy_capture_with_copy_default) 12260b57cec5SDimitry Andric << FixItHint::CreateRemoval( 12270b57cec5SDimitry Andric SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); 12280b57cec5SDimitry Andric continue; 12290b57cec5SDimitry Andric } 12300b57cec5SDimitry Andric 12310b57cec5SDimitry Andric // C++11 [expr.prim.lambda]p10: 12320b57cec5SDimitry Andric // The identifiers in a capture-list are looked up using the usual 12330b57cec5SDimitry Andric // rules for unqualified name lookup (3.4.1) 12340b57cec5SDimitry Andric DeclarationNameInfo Name(C->Id, C->Loc); 12350b57cec5SDimitry Andric LookupResult R(*this, Name, LookupOrdinaryName); 12360b57cec5SDimitry Andric LookupName(R, CurScope); 12370b57cec5SDimitry Andric if (R.isAmbiguous()) 12380b57cec5SDimitry Andric continue; 12390b57cec5SDimitry Andric if (R.empty()) { 12400b57cec5SDimitry Andric // FIXME: Disable corrections that would add qualification? 12410b57cec5SDimitry Andric CXXScopeSpec ScopeSpec; 12420b57cec5SDimitry Andric DeclFilterCCC<VarDecl> Validator{}; 12430b57cec5SDimitry Andric if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, Validator)) 12440b57cec5SDimitry Andric continue; 12450b57cec5SDimitry Andric } 12460b57cec5SDimitry Andric 1247bdd1243dSDimitry Andric if (auto *BD = R.getAsSingle<BindingDecl>()) 1248bdd1243dSDimitry Andric Var = BD; 1249*0fca6ea1SDimitry Andric else if (R.getAsSingle<FieldDecl>()) { 1250*0fca6ea1SDimitry Andric Diag(C->Loc, diag::err_capture_class_member_does_not_name_variable) 1251*0fca6ea1SDimitry Andric << C->Id; 1252*0fca6ea1SDimitry Andric continue; 1253*0fca6ea1SDimitry Andric } else 12540b57cec5SDimitry Andric Var = R.getAsSingle<VarDecl>(); 12550b57cec5SDimitry Andric if (Var && DiagnoseUseOfDecl(Var, C->Loc)) 12560b57cec5SDimitry Andric continue; 12570b57cec5SDimitry Andric } 12580b57cec5SDimitry Andric 12590b57cec5SDimitry Andric // C++11 [expr.prim.lambda]p10: 12600b57cec5SDimitry Andric // [...] each such lookup shall find a variable with automatic storage 12610b57cec5SDimitry Andric // duration declared in the reaching scope of the local lambda expression. 12620b57cec5SDimitry Andric // Note that the 'reaching scope' check happens in tryCaptureVariable(). 12630b57cec5SDimitry Andric if (!Var) { 12640b57cec5SDimitry Andric Diag(C->Loc, diag::err_capture_does_not_name_variable) << C->Id; 12650b57cec5SDimitry Andric continue; 12660b57cec5SDimitry Andric } 12670b57cec5SDimitry Andric 126806c3fb27SDimitry Andric // C++11 [expr.prim.lambda]p8: 126906c3fb27SDimitry Andric // An identifier or this shall not appear more than once in a 127006c3fb27SDimitry Andric // lambda-capture. 127106c3fb27SDimitry Andric if (auto [It, Inserted] = CaptureNames.insert(std::pair{C->Id, Var}); 127206c3fb27SDimitry Andric !Inserted) { 127306c3fb27SDimitry Andric if (C->InitKind == LambdaCaptureInitKind::NoInit && 127406c3fb27SDimitry Andric !Var->isInitCapture()) { 127506c3fb27SDimitry Andric Diag(C->Loc, diag::err_capture_more_than_once) 127606c3fb27SDimitry Andric << C->Id << It->second->getBeginLoc() 127706c3fb27SDimitry Andric << FixItHint::CreateRemoval( 127806c3fb27SDimitry Andric SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); 12795f757f3fSDimitry Andric Var->setInvalidDecl(); 12805f757f3fSDimitry Andric } else if (Var && Var->isPlaceholderVar(getLangOpts())) { 12815f757f3fSDimitry Andric DiagPlaceholderVariableDefinition(C->Loc); 12825f757f3fSDimitry Andric } else { 128306c3fb27SDimitry Andric // Previous capture captured something different (one or both was 128406c3fb27SDimitry Andric // an init-capture): no fixit. 128506c3fb27SDimitry Andric Diag(C->Loc, diag::err_capture_more_than_once) << C->Id; 128606c3fb27SDimitry Andric continue; 128706c3fb27SDimitry Andric } 12885f757f3fSDimitry Andric } 128906c3fb27SDimitry Andric 12900b57cec5SDimitry Andric // Ignore invalid decls; they'll just confuse the code later. 12910b57cec5SDimitry Andric if (Var->isInvalidDecl()) 12920b57cec5SDimitry Andric continue; 12930b57cec5SDimitry Andric 1294bdd1243dSDimitry Andric VarDecl *Underlying = Var->getPotentiallyDecomposedVarDecl(); 1295bdd1243dSDimitry Andric 1296bdd1243dSDimitry Andric if (!Underlying->hasLocalStorage()) { 12970b57cec5SDimitry Andric Diag(C->Loc, diag::err_capture_non_automatic_variable) << C->Id; 12980b57cec5SDimitry Andric Diag(Var->getLocation(), diag::note_previous_decl) << C->Id; 12990b57cec5SDimitry Andric continue; 13000b57cec5SDimitry Andric } 13010b57cec5SDimitry Andric 13020b57cec5SDimitry Andric // C++11 [expr.prim.lambda]p23: 13030b57cec5SDimitry Andric // A capture followed by an ellipsis is a pack expansion (14.5.3). 13040b57cec5SDimitry Andric SourceLocation EllipsisLoc; 13050b57cec5SDimitry Andric if (C->EllipsisLoc.isValid()) { 13060b57cec5SDimitry Andric if (Var->isParameterPack()) { 13070b57cec5SDimitry Andric EllipsisLoc = C->EllipsisLoc; 13080b57cec5SDimitry Andric } else { 13090b57cec5SDimitry Andric Diag(C->EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) 13100b57cec5SDimitry Andric << (C->Init.isUsable() ? C->Init.get()->getSourceRange() 13110b57cec5SDimitry Andric : SourceRange(C->Loc)); 13120b57cec5SDimitry Andric 13130b57cec5SDimitry Andric // Just ignore the ellipsis. 13140b57cec5SDimitry Andric } 13150b57cec5SDimitry Andric } else if (Var->isParameterPack()) { 13160b57cec5SDimitry Andric ContainsUnexpandedParameterPack = true; 13170b57cec5SDimitry Andric } 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andric if (C->Init.isUsable()) { 1320bdd1243dSDimitry Andric addInitCapture(LSI, cast<VarDecl>(Var), C->Kind == LCK_ByRef); 13210b57cec5SDimitry Andric } else { 132206c3fb27SDimitry Andric TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef 132306c3fb27SDimitry Andric : TryCapture_ExplicitByVal; 13240b57cec5SDimitry Andric tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc); 13250b57cec5SDimitry Andric } 13260b57cec5SDimitry Andric if (!LSI->Captures.empty()) 13270b57cec5SDimitry Andric LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; 13280b57cec5SDimitry Andric } 13290b57cec5SDimitry Andric finishLambdaExplicitCaptures(LSI); 1330a7dea167SDimitry Andric LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack; 133106c3fb27SDimitry Andric PopDeclContext(); 133206c3fb27SDimitry Andric } 13330b57cec5SDimitry Andric 133406c3fb27SDimitry Andric void Sema::ActOnLambdaClosureQualifiers(LambdaIntroducer &Intro, 133506c3fb27SDimitry Andric SourceLocation MutableLoc) { 133606c3fb27SDimitry Andric 133706c3fb27SDimitry Andric LambdaScopeInfo *LSI = getCurrentLambdaScopeUnsafe(*this); 133806c3fb27SDimitry Andric LSI->Mutable = MutableLoc.isValid(); 133906c3fb27SDimitry Andric ContextRAII Context(*this, LSI->CallOperator, /*NewThisContext*/ false); 134006c3fb27SDimitry Andric 134106c3fb27SDimitry Andric // C++11 [expr.prim.lambda]p9: 134206c3fb27SDimitry Andric // A lambda-expression whose smallest enclosing scope is a block scope is a 134306c3fb27SDimitry Andric // local lambda expression; any other lambda expression shall not have a 134406c3fb27SDimitry Andric // capture-default or simple-capture in its lambda-introducer. 134506c3fb27SDimitry Andric // 134606c3fb27SDimitry Andric // For simple-captures, this is covered by the check below that any named 134706c3fb27SDimitry Andric // entity is a variable that can be captured. 134806c3fb27SDimitry Andric // 134906c3fb27SDimitry Andric // For DR1632, we also allow a capture-default in any context where we can 135006c3fb27SDimitry Andric // odr-use 'this' (in particular, in a default initializer for a non-static 135106c3fb27SDimitry Andric // data member). 135206c3fb27SDimitry Andric if (Intro.Default != LCD_None && 135306c3fb27SDimitry Andric !LSI->Lambda->getParent()->isFunctionOrMethod() && 135406c3fb27SDimitry Andric (getCurrentThisType().isNull() || 135506c3fb27SDimitry Andric CheckCXXThisCapture(SourceLocation(), /*Explicit=*/true, 135606c3fb27SDimitry Andric /*BuildAndDiagnose=*/false))) 135706c3fb27SDimitry Andric Diag(Intro.DefaultLoc, diag::err_capture_default_non_local); 135806c3fb27SDimitry Andric } 135906c3fb27SDimitry Andric 136006c3fb27SDimitry Andric void Sema::ActOnLambdaClosureParameters( 136106c3fb27SDimitry Andric Scope *LambdaScope, MutableArrayRef<DeclaratorChunk::ParamInfo> Params) { 136206c3fb27SDimitry Andric LambdaScopeInfo *LSI = getCurrentLambdaScopeUnsafe(*this); 136306c3fb27SDimitry Andric PushDeclContext(LambdaScope, LSI->CallOperator); 136406c3fb27SDimitry Andric 136506c3fb27SDimitry Andric for (const DeclaratorChunk::ParamInfo &P : Params) { 136606c3fb27SDimitry Andric auto *Param = cast<ParmVarDecl>(P.Param); 136706c3fb27SDimitry Andric Param->setOwningFunction(LSI->CallOperator); 136806c3fb27SDimitry Andric if (Param->getIdentifier()) 136906c3fb27SDimitry Andric PushOnScopeChains(Param, LambdaScope, false); 137006c3fb27SDimitry Andric } 137106c3fb27SDimitry Andric 13725f757f3fSDimitry Andric // After the parameter list, we may parse a noexcept/requires/trailing return 13735f757f3fSDimitry Andric // type which need to know whether the call operator constiture a dependent 13745f757f3fSDimitry Andric // context, so we need to setup the FunctionTemplateDecl of generic lambdas 13755f757f3fSDimitry Andric // now. 13765f757f3fSDimitry Andric TemplateParameterList *TemplateParams = 13775f757f3fSDimitry Andric getGenericLambdaTemplateParameterList(LSI, *this); 13785f757f3fSDimitry Andric if (TemplateParams) { 13795f757f3fSDimitry Andric AddTemplateParametersToLambdaCallOperator(LSI->CallOperator, LSI->Lambda, 13805f757f3fSDimitry Andric TemplateParams); 13815f757f3fSDimitry Andric LSI->Lambda->setLambdaIsGeneric(true); 1382*0fca6ea1SDimitry Andric LSI->ContainsUnexpandedParameterPack |= 1383*0fca6ea1SDimitry Andric TemplateParams->containsUnexpandedParameterPack(); 13845f757f3fSDimitry Andric } 138506c3fb27SDimitry Andric LSI->AfterParameterList = true; 138606c3fb27SDimitry Andric } 138706c3fb27SDimitry Andric 138806c3fb27SDimitry Andric void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, 138906c3fb27SDimitry Andric Declarator &ParamInfo, 139006c3fb27SDimitry Andric const DeclSpec &DS) { 139106c3fb27SDimitry Andric 139206c3fb27SDimitry Andric LambdaScopeInfo *LSI = getCurrentLambdaScopeUnsafe(*this); 139306c3fb27SDimitry Andric LSI->CallOperator->setConstexprKind(DS.getConstexprSpecifier()); 139406c3fb27SDimitry Andric 139506c3fb27SDimitry Andric SmallVector<ParmVarDecl *, 8> Params; 139606c3fb27SDimitry Andric bool ExplicitResultType; 139706c3fb27SDimitry Andric 139806c3fb27SDimitry Andric SourceLocation TypeLoc, CallOperatorLoc; 139906c3fb27SDimitry Andric if (ParamInfo.getNumTypeObjects() == 0) { 140006c3fb27SDimitry Andric CallOperatorLoc = TypeLoc = Intro.Range.getEnd(); 140106c3fb27SDimitry Andric } else { 140206c3fb27SDimitry Andric unsigned Index; 140306c3fb27SDimitry Andric ParamInfo.isFunctionDeclarator(Index); 140406c3fb27SDimitry Andric const auto &Object = ParamInfo.getTypeObject(Index); 140506c3fb27SDimitry Andric TypeLoc = 140606c3fb27SDimitry Andric Object.Loc.isValid() ? Object.Loc : ParamInfo.getSourceRange().getEnd(); 140706c3fb27SDimitry Andric CallOperatorLoc = ParamInfo.getSourceRange().getEnd(); 140806c3fb27SDimitry Andric } 140906c3fb27SDimitry Andric 141006c3fb27SDimitry Andric CXXRecordDecl *Class = LSI->Lambda; 141106c3fb27SDimitry Andric CXXMethodDecl *Method = LSI->CallOperator; 141206c3fb27SDimitry Andric 141306c3fb27SDimitry Andric TypeSourceInfo *MethodTyInfo = getLambdaType( 141406c3fb27SDimitry Andric *this, Intro, ParamInfo, getCurScope(), TypeLoc, ExplicitResultType); 141506c3fb27SDimitry Andric 141606c3fb27SDimitry Andric LSI->ExplicitParams = ParamInfo.getNumTypeObjects() != 0; 141706c3fb27SDimitry Andric 141806c3fb27SDimitry Andric if (ParamInfo.isFunctionDeclarator() != 0 && 141906c3fb27SDimitry Andric !FTIHasSingleVoidParameter(ParamInfo.getFunctionTypeInfo())) { 142006c3fb27SDimitry Andric const auto &FTI = ParamInfo.getFunctionTypeInfo(); 142106c3fb27SDimitry Andric Params.reserve(Params.size()); 142206c3fb27SDimitry Andric for (unsigned I = 0; I < FTI.NumParams; ++I) { 142306c3fb27SDimitry Andric auto *Param = cast<ParmVarDecl>(FTI.Params[I].Param); 142406c3fb27SDimitry Andric Param->setScopeInfo(0, Params.size()); 142506c3fb27SDimitry Andric Params.push_back(Param); 142606c3fb27SDimitry Andric } 142706c3fb27SDimitry Andric } 142806c3fb27SDimitry Andric 142906c3fb27SDimitry Andric bool IsLambdaStatic = 143006c3fb27SDimitry Andric ParamInfo.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static; 143106c3fb27SDimitry Andric 143206c3fb27SDimitry Andric CompleteLambdaCallOperator( 143306c3fb27SDimitry Andric Method, Intro.Range.getBegin(), CallOperatorLoc, 143406c3fb27SDimitry Andric ParamInfo.getTrailingRequiresClause(), MethodTyInfo, 143506c3fb27SDimitry Andric ParamInfo.getDeclSpec().getConstexprSpecifier(), 143606c3fb27SDimitry Andric IsLambdaStatic ? SC_Static : SC_None, Params, ExplicitResultType); 143706c3fb27SDimitry Andric 143806c3fb27SDimitry Andric CheckCXXDefaultArguments(Method); 143906c3fb27SDimitry Andric 144006c3fb27SDimitry Andric // This represents the function body for the lambda function, check if we 144106c3fb27SDimitry Andric // have to apply optnone due to a pragma. 144206c3fb27SDimitry Andric AddRangeBasedOptnone(Method); 144306c3fb27SDimitry Andric 144406c3fb27SDimitry Andric // code_seg attribute on lambda apply to the method. 144506c3fb27SDimitry Andric if (Attr *A = getImplicitCodeSegOrSectionAttrForFunction( 144606c3fb27SDimitry Andric Method, /*IsDefinition=*/true)) 144706c3fb27SDimitry Andric Method->addAttr(A); 144806c3fb27SDimitry Andric 144906c3fb27SDimitry Andric // Attributes on the lambda apply to the method. 145006c3fb27SDimitry Andric ProcessDeclAttributes(CurScope, Method, ParamInfo); 145106c3fb27SDimitry Andric 145206c3fb27SDimitry Andric // CUDA lambdas get implicit host and device attributes. 145306c3fb27SDimitry Andric if (getLangOpts().CUDA) 1454*0fca6ea1SDimitry Andric CUDA().SetLambdaAttrs(Method); 145506c3fb27SDimitry Andric 145606c3fb27SDimitry Andric // OpenMP lambdas might get assumumption attributes. 145706c3fb27SDimitry Andric if (LangOpts.OpenMP) 1458*0fca6ea1SDimitry Andric OpenMP().ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Method); 145906c3fb27SDimitry Andric 146006c3fb27SDimitry Andric handleLambdaNumbering(Class, Method); 146106c3fb27SDimitry Andric 146206c3fb27SDimitry Andric for (auto &&C : LSI->Captures) { 146306c3fb27SDimitry Andric if (!C.isVariableCapture()) 146406c3fb27SDimitry Andric continue; 146506c3fb27SDimitry Andric ValueDecl *Var = C.getVariable(); 146606c3fb27SDimitry Andric if (Var && Var->isInitCapture()) { 146706c3fb27SDimitry Andric PushOnScopeChains(Var, CurScope, false); 146806c3fb27SDimitry Andric } 146906c3fb27SDimitry Andric } 147006c3fb27SDimitry Andric 147106c3fb27SDimitry Andric auto CheckRedefinition = [&](ParmVarDecl *Param) { 147206c3fb27SDimitry Andric for (const auto &Capture : Intro.Captures) { 147306c3fb27SDimitry Andric if (Capture.Id == Param->getIdentifier()) { 147406c3fb27SDimitry Andric Diag(Param->getLocation(), diag::err_parameter_shadow_capture); 147506c3fb27SDimitry Andric Diag(Capture.Loc, diag::note_var_explicitly_captured_here) 147606c3fb27SDimitry Andric << Capture.Id << true; 147706c3fb27SDimitry Andric return false; 147806c3fb27SDimitry Andric } 147906c3fb27SDimitry Andric } 148006c3fb27SDimitry Andric return true; 148106c3fb27SDimitry Andric }; 148206c3fb27SDimitry Andric 148306c3fb27SDimitry Andric for (ParmVarDecl *P : Params) { 148406c3fb27SDimitry Andric if (!P->getIdentifier()) 148506c3fb27SDimitry Andric continue; 148606c3fb27SDimitry Andric if (CheckRedefinition(P)) 148706c3fb27SDimitry Andric CheckShadow(CurScope, P); 148806c3fb27SDimitry Andric PushOnScopeChains(P, CurScope); 148906c3fb27SDimitry Andric } 149006c3fb27SDimitry Andric 149106c3fb27SDimitry Andric // C++23 [expr.prim.lambda.capture]p5: 149206c3fb27SDimitry Andric // If an identifier in a capture appears as the declarator-id of a parameter 149306c3fb27SDimitry Andric // of the lambda-declarator's parameter-declaration-clause or as the name of a 149406c3fb27SDimitry Andric // template parameter of the lambda-expression's template-parameter-list, the 149506c3fb27SDimitry Andric // program is ill-formed. 149606c3fb27SDimitry Andric TemplateParameterList *TemplateParams = 149706c3fb27SDimitry Andric getGenericLambdaTemplateParameterList(LSI, *this); 149806c3fb27SDimitry Andric if (TemplateParams) { 149906c3fb27SDimitry Andric for (const auto *TP : TemplateParams->asArray()) { 150006c3fb27SDimitry Andric if (!TP->getIdentifier()) 150106c3fb27SDimitry Andric continue; 150206c3fb27SDimitry Andric for (const auto &Capture : Intro.Captures) { 150306c3fb27SDimitry Andric if (Capture.Id == TP->getIdentifier()) { 150406c3fb27SDimitry Andric Diag(Capture.Loc, diag::err_template_param_shadow) << Capture.Id; 15055f757f3fSDimitry Andric NoteTemplateParameterLocation(*TP); 150606c3fb27SDimitry Andric } 150706c3fb27SDimitry Andric } 150806c3fb27SDimitry Andric } 150906c3fb27SDimitry Andric } 151006c3fb27SDimitry Andric 151106c3fb27SDimitry Andric // C++20: dcl.decl.general p4: 151206c3fb27SDimitry Andric // The optional requires-clause ([temp.pre]) in an init-declarator or 151306c3fb27SDimitry Andric // member-declarator shall be present only if the declarator declares a 151406c3fb27SDimitry Andric // templated function ([dcl.fct]). 151506c3fb27SDimitry Andric if (Expr *TRC = Method->getTrailingRequiresClause()) { 151606c3fb27SDimitry Andric // [temp.pre]/8: 151706c3fb27SDimitry Andric // An entity is templated if it is 151806c3fb27SDimitry Andric // - a template, 151906c3fb27SDimitry Andric // - an entity defined ([basic.def]) or created ([class.temporary]) in a 152006c3fb27SDimitry Andric // templated entity, 152106c3fb27SDimitry Andric // - a member of a templated entity, 152206c3fb27SDimitry Andric // - an enumerator for an enumeration that is a templated entity, or 152306c3fb27SDimitry Andric // - the closure type of a lambda-expression ([expr.prim.lambda.closure]) 152406c3fb27SDimitry Andric // appearing in the declaration of a templated entity. [Note 6: A local 152506c3fb27SDimitry Andric // class, a local or block variable, or a friend function defined in a 152606c3fb27SDimitry Andric // templated entity is a templated entity. — end note] 152706c3fb27SDimitry Andric // 152806c3fb27SDimitry Andric // A templated function is a function template or a function that is 152906c3fb27SDimitry Andric // templated. A templated class is a class template or a class that is 153006c3fb27SDimitry Andric // templated. A templated variable is a variable template or a variable 153106c3fb27SDimitry Andric // that is templated. 153206c3fb27SDimitry Andric 153306c3fb27SDimitry Andric // Note: we only have to check if this is defined in a template entity, OR 153406c3fb27SDimitry Andric // if we are a template, since the rest don't apply. The requires clause 153506c3fb27SDimitry Andric // applies to the call operator, which we already know is a member function, 153606c3fb27SDimitry Andric // AND defined. 153706c3fb27SDimitry Andric if (!Method->getDescribedFunctionTemplate() && !Method->isTemplated()) { 153806c3fb27SDimitry Andric Diag(TRC->getBeginLoc(), diag::err_constrained_non_templated_function); 153906c3fb27SDimitry Andric } 154006c3fb27SDimitry Andric } 15410b57cec5SDimitry Andric 15420b57cec5SDimitry Andric // Enter a new evaluation context to insulate the lambda from any 15430b57cec5SDimitry Andric // cleanups from the enclosing full-expression. 15440b57cec5SDimitry Andric PushExpressionEvaluationContext( 15455ffd83dbSDimitry Andric LSI->CallOperator->isConsteval() 1546349cc55cSDimitry Andric ? ExpressionEvaluationContext::ImmediateFunctionContext 15475ffd83dbSDimitry Andric : ExpressionEvaluationContext::PotentiallyEvaluated); 154806c3fb27SDimitry Andric ExprEvalContexts.back().InImmediateFunctionContext = 154906c3fb27SDimitry Andric LSI->CallOperator->isConsteval(); 155006c3fb27SDimitry Andric ExprEvalContexts.back().InImmediateEscalatingFunctionContext = 155106c3fb27SDimitry Andric getLangOpts().CPlusPlus20 && LSI->CallOperator->isImmediateEscalating(); 15520b57cec5SDimitry Andric } 15530b57cec5SDimitry Andric 15540b57cec5SDimitry Andric void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, 15550b57cec5SDimitry Andric bool IsInstantiation) { 15560b57cec5SDimitry Andric LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(FunctionScopes.back()); 15570b57cec5SDimitry Andric 15580b57cec5SDimitry Andric // Leave the expression-evaluation context. 15590b57cec5SDimitry Andric DiscardCleanupsInEvaluationContext(); 15600b57cec5SDimitry Andric PopExpressionEvaluationContext(); 15610b57cec5SDimitry Andric 15620b57cec5SDimitry Andric // Leave the context of the lambda. 15630b57cec5SDimitry Andric if (!IsInstantiation) 15640b57cec5SDimitry Andric PopDeclContext(); 15650b57cec5SDimitry Andric 15660b57cec5SDimitry Andric // Finalize the lambda. 15670b57cec5SDimitry Andric CXXRecordDecl *Class = LSI->Lambda; 15680b57cec5SDimitry Andric Class->setInvalidDecl(); 15690b57cec5SDimitry Andric SmallVector<Decl*, 4> Fields(Class->fields()); 15700b57cec5SDimitry Andric ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(), 15710b57cec5SDimitry Andric SourceLocation(), ParsedAttributesView()); 1572480093f4SDimitry Andric CheckCompletedCXXClass(nullptr, Class); 15730b57cec5SDimitry Andric 15740b57cec5SDimitry Andric PopFunctionScopeInfo(); 15750b57cec5SDimitry Andric } 15760b57cec5SDimitry Andric 1577e8d8bef9SDimitry Andric template <typename Func> 1578e8d8bef9SDimitry Andric static void repeatForLambdaConversionFunctionCallingConvs( 1579e8d8bef9SDimitry Andric Sema &S, const FunctionProtoType &CallOpProto, Func F) { 1580e8d8bef9SDimitry Andric CallingConv DefaultFree = S.Context.getDefaultCallingConvention( 1581e8d8bef9SDimitry Andric CallOpProto.isVariadic(), /*IsCXXMethod=*/false); 1582e8d8bef9SDimitry Andric CallingConv DefaultMember = S.Context.getDefaultCallingConvention( 1583e8d8bef9SDimitry Andric CallOpProto.isVariadic(), /*IsCXXMethod=*/true); 1584e8d8bef9SDimitry Andric CallingConv CallOpCC = CallOpProto.getCallConv(); 1585e8d8bef9SDimitry Andric 1586e8d8bef9SDimitry Andric /// Implement emitting a version of the operator for many of the calling 1587e8d8bef9SDimitry Andric /// conventions for MSVC, as described here: 1588e8d8bef9SDimitry Andric /// https://devblogs.microsoft.com/oldnewthing/20150220-00/?p=44623. 1589e8d8bef9SDimitry Andric /// Experimentally, we determined that cdecl, stdcall, fastcall, and 1590e8d8bef9SDimitry Andric /// vectorcall are generated by MSVC when it is supported by the target. 1591e8d8bef9SDimitry Andric /// Additionally, we are ensuring that the default-free/default-member and 1592e8d8bef9SDimitry Andric /// call-operator calling convention are generated as well. 1593e8d8bef9SDimitry Andric /// NOTE: We intentionally generate a 'thiscall' on Win32 implicitly from the 1594e8d8bef9SDimitry Andric /// 'member default', despite MSVC not doing so. We do this in order to ensure 1595e8d8bef9SDimitry Andric /// that someone who intentionally places 'thiscall' on the lambda call 1596e8d8bef9SDimitry Andric /// operator will still get that overload, since we don't have the a way of 1597e8d8bef9SDimitry Andric /// detecting the attribute by the time we get here. 1598e8d8bef9SDimitry Andric if (S.getLangOpts().MSVCCompat) { 1599e8d8bef9SDimitry Andric CallingConv Convs[] = { 1600e8d8bef9SDimitry Andric CC_C, CC_X86StdCall, CC_X86FastCall, CC_X86VectorCall, 1601e8d8bef9SDimitry Andric DefaultFree, DefaultMember, CallOpCC}; 1602e8d8bef9SDimitry Andric llvm::sort(Convs); 1603e8d8bef9SDimitry Andric llvm::iterator_range<CallingConv *> Range( 1604e8d8bef9SDimitry Andric std::begin(Convs), std::unique(std::begin(Convs), std::end(Convs))); 1605e8d8bef9SDimitry Andric const TargetInfo &TI = S.getASTContext().getTargetInfo(); 1606e8d8bef9SDimitry Andric 1607e8d8bef9SDimitry Andric for (CallingConv C : Range) { 1608e8d8bef9SDimitry Andric if (TI.checkCallingConvention(C) == TargetInfo::CCCR_OK) 1609e8d8bef9SDimitry Andric F(C); 1610e8d8bef9SDimitry Andric } 1611e8d8bef9SDimitry Andric return; 1612e8d8bef9SDimitry Andric } 1613e8d8bef9SDimitry Andric 1614e8d8bef9SDimitry Andric if (CallOpCC == DefaultMember && DefaultMember != DefaultFree) { 1615e8d8bef9SDimitry Andric F(DefaultFree); 1616e8d8bef9SDimitry Andric F(DefaultMember); 1617e8d8bef9SDimitry Andric } else { 1618e8d8bef9SDimitry Andric F(CallOpCC); 1619e8d8bef9SDimitry Andric } 1620e8d8bef9SDimitry Andric } 1621e8d8bef9SDimitry Andric 1622e8d8bef9SDimitry Andric // Returns the 'standard' calling convention to be used for the lambda 1623e8d8bef9SDimitry Andric // conversion function, that is, the 'free' function calling convention unless 1624e8d8bef9SDimitry Andric // it is overridden by a non-default calling convention attribute. 1625e8d8bef9SDimitry Andric static CallingConv 1626e8d8bef9SDimitry Andric getLambdaConversionFunctionCallConv(Sema &S, 16270b57cec5SDimitry Andric const FunctionProtoType *CallOpProto) { 1628e8d8bef9SDimitry Andric CallingConv DefaultFree = S.Context.getDefaultCallingConvention( 1629e8d8bef9SDimitry Andric CallOpProto->isVariadic(), /*IsCXXMethod=*/false); 1630e8d8bef9SDimitry Andric CallingConv DefaultMember = S.Context.getDefaultCallingConvention( 1631e8d8bef9SDimitry Andric CallOpProto->isVariadic(), /*IsCXXMethod=*/true); 1632e8d8bef9SDimitry Andric CallingConv CallOpCC = CallOpProto->getCallConv(); 1633e8d8bef9SDimitry Andric 1634e8d8bef9SDimitry Andric // If the call-operator hasn't been changed, return both the 'free' and 1635e8d8bef9SDimitry Andric // 'member' function calling convention. 1636e8d8bef9SDimitry Andric if (CallOpCC == DefaultMember && DefaultMember != DefaultFree) 1637e8d8bef9SDimitry Andric return DefaultFree; 1638e8d8bef9SDimitry Andric return CallOpCC; 1639e8d8bef9SDimitry Andric } 1640e8d8bef9SDimitry Andric 1641e8d8bef9SDimitry Andric QualType Sema::getLambdaConversionFunctionResultType( 1642e8d8bef9SDimitry Andric const FunctionProtoType *CallOpProto, CallingConv CC) { 16430b57cec5SDimitry Andric const FunctionProtoType::ExtProtoInfo CallOpExtInfo = 16440b57cec5SDimitry Andric CallOpProto->getExtProtoInfo(); 16450b57cec5SDimitry Andric FunctionProtoType::ExtProtoInfo InvokerExtInfo = CallOpExtInfo; 16460b57cec5SDimitry Andric InvokerExtInfo.ExtInfo = InvokerExtInfo.ExtInfo.withCallingConv(CC); 16470b57cec5SDimitry Andric InvokerExtInfo.TypeQuals = Qualifiers(); 16480b57cec5SDimitry Andric assert(InvokerExtInfo.RefQualifier == RQ_None && 16490b57cec5SDimitry Andric "Lambda's call operator should not have a reference qualifier"); 16500b57cec5SDimitry Andric return Context.getFunctionType(CallOpProto->getReturnType(), 16510b57cec5SDimitry Andric CallOpProto->getParamTypes(), InvokerExtInfo); 16520b57cec5SDimitry Andric } 16530b57cec5SDimitry Andric 16540b57cec5SDimitry Andric /// Add a lambda's conversion to function pointer, as described in 16550b57cec5SDimitry Andric /// C++11 [expr.prim.lambda]p6. 1656e8d8bef9SDimitry Andric static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange, 16570b57cec5SDimitry Andric CXXRecordDecl *Class, 1658e8d8bef9SDimitry Andric CXXMethodDecl *CallOperator, 1659e8d8bef9SDimitry Andric QualType InvokerFunctionTy) { 16600b57cec5SDimitry Andric // This conversion is explicitly disabled if the lambda's function has 16610b57cec5SDimitry Andric // pass_object_size attributes on any of its parameters. 16620b57cec5SDimitry Andric auto HasPassObjectSizeAttr = [](const ParmVarDecl *P) { 16630b57cec5SDimitry Andric return P->hasAttr<PassObjectSizeAttr>(); 16640b57cec5SDimitry Andric }; 16650b57cec5SDimitry Andric if (llvm::any_of(CallOperator->parameters(), HasPassObjectSizeAttr)) 16660b57cec5SDimitry Andric return; 16670b57cec5SDimitry Andric 16680b57cec5SDimitry Andric // Add the conversion to function pointer. 16690b57cec5SDimitry Andric QualType PtrToFunctionTy = S.Context.getPointerType(InvokerFunctionTy); 16700b57cec5SDimitry Andric 16710b57cec5SDimitry Andric // Create the type of the conversion function. 16720b57cec5SDimitry Andric FunctionProtoType::ExtProtoInfo ConvExtInfo( 16730b57cec5SDimitry Andric S.Context.getDefaultCallingConvention( 16740b57cec5SDimitry Andric /*IsVariadic=*/false, /*IsCXXMethod=*/true)); 16750b57cec5SDimitry Andric // The conversion function is always const and noexcept. 16760b57cec5SDimitry Andric ConvExtInfo.TypeQuals = Qualifiers(); 16770b57cec5SDimitry Andric ConvExtInfo.TypeQuals.addConst(); 16780b57cec5SDimitry Andric ConvExtInfo.ExceptionSpec.Type = EST_BasicNoexcept; 16790b57cec5SDimitry Andric QualType ConvTy = 1680bdd1243dSDimitry Andric S.Context.getFunctionType(PtrToFunctionTy, std::nullopt, ConvExtInfo); 16810b57cec5SDimitry Andric 16820b57cec5SDimitry Andric SourceLocation Loc = IntroducerRange.getBegin(); 16830b57cec5SDimitry Andric DeclarationName ConversionName 16840b57cec5SDimitry Andric = S.Context.DeclarationNames.getCXXConversionFunctionName( 16850b57cec5SDimitry Andric S.Context.getCanonicalType(PtrToFunctionTy)); 16860b57cec5SDimitry Andric // Construct a TypeSourceInfo for the conversion function, and wire 16870b57cec5SDimitry Andric // all the parameters appropriately for the FunctionProtoTypeLoc 16880b57cec5SDimitry Andric // so that everything works during transformation/instantiation of 16890b57cec5SDimitry Andric // generic lambdas. 16900b57cec5SDimitry Andric // The main reason for wiring up the parameters of the conversion 16910b57cec5SDimitry Andric // function with that of the call operator is so that constructs 16920b57cec5SDimitry Andric // like the following work: 16930b57cec5SDimitry Andric // auto L = [](auto b) { <-- 1 16940b57cec5SDimitry Andric // return [](auto a) -> decltype(a) { <-- 2 16950b57cec5SDimitry Andric // return a; 16960b57cec5SDimitry Andric // }; 16970b57cec5SDimitry Andric // }; 16980b57cec5SDimitry Andric // int (*fp)(int) = L(5); 16990b57cec5SDimitry Andric // Because the trailing return type can contain DeclRefExprs that refer 17000b57cec5SDimitry Andric // to the original call operator's variables, we hijack the call 17010b57cec5SDimitry Andric // operators ParmVarDecls below. 17020b57cec5SDimitry Andric TypeSourceInfo *ConvNamePtrToFunctionTSI = 17030b57cec5SDimitry Andric S.Context.getTrivialTypeSourceInfo(PtrToFunctionTy, Loc); 1704fe6060f1SDimitry Andric DeclarationNameLoc ConvNameLoc = 1705fe6060f1SDimitry Andric DeclarationNameLoc::makeNamedTypeLoc(ConvNamePtrToFunctionTSI); 17060b57cec5SDimitry Andric 17070b57cec5SDimitry Andric // The conversion function is a conversion to a pointer-to-function. 17080b57cec5SDimitry Andric TypeSourceInfo *ConvTSI = S.Context.getTrivialTypeSourceInfo(ConvTy, Loc); 17090b57cec5SDimitry Andric FunctionProtoTypeLoc ConvTL = 17100b57cec5SDimitry Andric ConvTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>(); 17110b57cec5SDimitry Andric // Get the result of the conversion function which is a pointer-to-function. 17120b57cec5SDimitry Andric PointerTypeLoc PtrToFunctionTL = 17130b57cec5SDimitry Andric ConvTL.getReturnLoc().getAs<PointerTypeLoc>(); 17140b57cec5SDimitry Andric // Do the same for the TypeSourceInfo that is used to name the conversion 17150b57cec5SDimitry Andric // operator. 17160b57cec5SDimitry Andric PointerTypeLoc ConvNamePtrToFunctionTL = 17170b57cec5SDimitry Andric ConvNamePtrToFunctionTSI->getTypeLoc().getAs<PointerTypeLoc>(); 17180b57cec5SDimitry Andric 17190b57cec5SDimitry Andric // Get the underlying function types that the conversion function will 17200b57cec5SDimitry Andric // be converting to (should match the type of the call operator). 17210b57cec5SDimitry Andric FunctionProtoTypeLoc CallOpConvTL = 17220b57cec5SDimitry Andric PtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>(); 17230b57cec5SDimitry Andric FunctionProtoTypeLoc CallOpConvNameTL = 17240b57cec5SDimitry Andric ConvNamePtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>(); 17250b57cec5SDimitry Andric 17260b57cec5SDimitry Andric // Wire up the FunctionProtoTypeLocs with the call operator's parameters. 17270b57cec5SDimitry Andric // These parameter's are essentially used to transform the name and 17280b57cec5SDimitry Andric // the type of the conversion operator. By using the same parameters 17290b57cec5SDimitry Andric // as the call operator's we don't have to fix any back references that 17300b57cec5SDimitry Andric // the trailing return type of the call operator's uses (such as 17310b57cec5SDimitry Andric // decltype(some_type<decltype(a)>::type{} + decltype(a){}) etc.) 17320b57cec5SDimitry Andric // - we can simply use the return type of the call operator, and 17330b57cec5SDimitry Andric // everything should work. 17340b57cec5SDimitry Andric SmallVector<ParmVarDecl *, 4> InvokerParams; 17350b57cec5SDimitry Andric for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) { 17360b57cec5SDimitry Andric ParmVarDecl *From = CallOperator->getParamDecl(I); 17370b57cec5SDimitry Andric 17380b57cec5SDimitry Andric InvokerParams.push_back(ParmVarDecl::Create( 17390b57cec5SDimitry Andric S.Context, 17400b57cec5SDimitry Andric // Temporarily add to the TU. This is set to the invoker below. 17410b57cec5SDimitry Andric S.Context.getTranslationUnitDecl(), From->getBeginLoc(), 17420b57cec5SDimitry Andric From->getLocation(), From->getIdentifier(), From->getType(), 17430b57cec5SDimitry Andric From->getTypeSourceInfo(), From->getStorageClass(), 17440b57cec5SDimitry Andric /*DefArg=*/nullptr)); 17450b57cec5SDimitry Andric CallOpConvTL.setParam(I, From); 17460b57cec5SDimitry Andric CallOpConvNameTL.setParam(I, From); 17470b57cec5SDimitry Andric } 17480b57cec5SDimitry Andric 17490b57cec5SDimitry Andric CXXConversionDecl *Conversion = CXXConversionDecl::Create( 17500b57cec5SDimitry Andric S.Context, Class, Loc, 17510b57cec5SDimitry Andric DeclarationNameInfo(ConversionName, Loc, ConvNameLoc), ConvTy, ConvTSI, 1752349cc55cSDimitry Andric S.getCurFPFeatures().isFPConstrained(), 17530b57cec5SDimitry Andric /*isInline=*/true, ExplicitSpecifier(), 1754e8d8bef9SDimitry Andric S.getLangOpts().CPlusPlus17 ? ConstexprSpecKind::Constexpr 1755e8d8bef9SDimitry Andric : ConstexprSpecKind::Unspecified, 17560b57cec5SDimitry Andric CallOperator->getBody()->getEndLoc()); 17570b57cec5SDimitry Andric Conversion->setAccess(AS_public); 17580b57cec5SDimitry Andric Conversion->setImplicit(true); 17590b57cec5SDimitry Andric 176006c3fb27SDimitry Andric // A non-generic lambda may still be a templated entity. We need to preserve 176106c3fb27SDimitry Andric // constraints when converting the lambda to a function pointer. See GH63181. 176206c3fb27SDimitry Andric if (Expr *Requires = CallOperator->getTrailingRequiresClause()) 176306c3fb27SDimitry Andric Conversion->setTrailingRequiresClause(Requires); 176406c3fb27SDimitry Andric 17650b57cec5SDimitry Andric if (Class->isGenericLambda()) { 17660b57cec5SDimitry Andric // Create a template version of the conversion operator, using the template 17670b57cec5SDimitry Andric // parameter list of the function call operator. 17680b57cec5SDimitry Andric FunctionTemplateDecl *TemplateCallOperator = 17690b57cec5SDimitry Andric CallOperator->getDescribedFunctionTemplate(); 17700b57cec5SDimitry Andric FunctionTemplateDecl *ConversionTemplate = 17710b57cec5SDimitry Andric FunctionTemplateDecl::Create(S.Context, Class, 17720b57cec5SDimitry Andric Loc, ConversionName, 17730b57cec5SDimitry Andric TemplateCallOperator->getTemplateParameters(), 17740b57cec5SDimitry Andric Conversion); 17750b57cec5SDimitry Andric ConversionTemplate->setAccess(AS_public); 17760b57cec5SDimitry Andric ConversionTemplate->setImplicit(true); 17770b57cec5SDimitry Andric Conversion->setDescribedFunctionTemplate(ConversionTemplate); 17780b57cec5SDimitry Andric Class->addDecl(ConversionTemplate); 17790b57cec5SDimitry Andric } else 17800b57cec5SDimitry Andric Class->addDecl(Conversion); 1781bdd1243dSDimitry Andric 1782bdd1243dSDimitry Andric // If the lambda is not static, we need to add a static member 1783bdd1243dSDimitry Andric // function that will be the result of the conversion with a 1784bdd1243dSDimitry Andric // certain unique ID. 1785bdd1243dSDimitry Andric // When it is static we just return the static call operator instead. 17865f757f3fSDimitry Andric if (CallOperator->isImplicitObjectMemberFunction()) { 1787bdd1243dSDimitry Andric DeclarationName InvokerName = 1788bdd1243dSDimitry Andric &S.Context.Idents.get(getLambdaStaticInvokerName()); 17890b57cec5SDimitry Andric // FIXME: Instead of passing in the CallOperator->getTypeSourceInfo() 17900b57cec5SDimitry Andric // we should get a prebuilt TrivialTypeSourceInfo from Context 17910b57cec5SDimitry Andric // using FunctionTy & Loc and get its TypeLoc as a FunctionProtoTypeLoc 17920b57cec5SDimitry Andric // then rewire the parameters accordingly, by hoisting up the InvokeParams 17930b57cec5SDimitry Andric // loop below and then use its Params to set Invoke->setParams(...) below. 17940b57cec5SDimitry Andric // This would avoid the 'const' qualifier of the calloperator from 17950b57cec5SDimitry Andric // contaminating the type of the invoker, which is currently adjusted 17960b57cec5SDimitry Andric // in SemaTemplateDeduction.cpp:DeduceTemplateArguments. Fixing the 17970b57cec5SDimitry Andric // trailing return type of the invoker would require a visitor to rebuild 17980b57cec5SDimitry Andric // the trailing return type and adjusting all back DeclRefExpr's to refer 17990b57cec5SDimitry Andric // to the new static invoker parameters - not the call operator's. 18000b57cec5SDimitry Andric CXXMethodDecl *Invoke = CXXMethodDecl::Create( 18010b57cec5SDimitry Andric S.Context, Class, Loc, DeclarationNameInfo(InvokerName, Loc), 18020b57cec5SDimitry Andric InvokerFunctionTy, CallOperator->getTypeSourceInfo(), SC_Static, 1803349cc55cSDimitry Andric S.getCurFPFeatures().isFPConstrained(), 180406c3fb27SDimitry Andric /*isInline=*/true, CallOperator->getConstexprKind(), 1805e8d8bef9SDimitry Andric CallOperator->getBody()->getEndLoc()); 18060b57cec5SDimitry Andric for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) 18070b57cec5SDimitry Andric InvokerParams[I]->setOwningFunction(Invoke); 18080b57cec5SDimitry Andric Invoke->setParams(InvokerParams); 18090b57cec5SDimitry Andric Invoke->setAccess(AS_private); 18100b57cec5SDimitry Andric Invoke->setImplicit(true); 18110b57cec5SDimitry Andric if (Class->isGenericLambda()) { 18120b57cec5SDimitry Andric FunctionTemplateDecl *TemplateCallOperator = 18130b57cec5SDimitry Andric CallOperator->getDescribedFunctionTemplate(); 1814bdd1243dSDimitry Andric FunctionTemplateDecl *StaticInvokerTemplate = 1815bdd1243dSDimitry Andric FunctionTemplateDecl::Create( 18160b57cec5SDimitry Andric S.Context, Class, Loc, InvokerName, 1817bdd1243dSDimitry Andric TemplateCallOperator->getTemplateParameters(), Invoke); 18180b57cec5SDimitry Andric StaticInvokerTemplate->setAccess(AS_private); 18190b57cec5SDimitry Andric StaticInvokerTemplate->setImplicit(true); 18200b57cec5SDimitry Andric Invoke->setDescribedFunctionTemplate(StaticInvokerTemplate); 18210b57cec5SDimitry Andric Class->addDecl(StaticInvokerTemplate); 18220b57cec5SDimitry Andric } else 18230b57cec5SDimitry Andric Class->addDecl(Invoke); 18240b57cec5SDimitry Andric } 1825bdd1243dSDimitry Andric } 18260b57cec5SDimitry Andric 1827e8d8bef9SDimitry Andric /// Add a lambda's conversion to function pointers, as described in 1828e8d8bef9SDimitry Andric /// C++11 [expr.prim.lambda]p6. Note that in most cases, this should emit only a 1829e8d8bef9SDimitry Andric /// single pointer conversion. In the event that the default calling convention 1830e8d8bef9SDimitry Andric /// for free and member functions is different, it will emit both conventions. 1831e8d8bef9SDimitry Andric static void addFunctionPointerConversions(Sema &S, SourceRange IntroducerRange, 1832e8d8bef9SDimitry Andric CXXRecordDecl *Class, 1833e8d8bef9SDimitry Andric CXXMethodDecl *CallOperator) { 1834e8d8bef9SDimitry Andric const FunctionProtoType *CallOpProto = 1835e8d8bef9SDimitry Andric CallOperator->getType()->castAs<FunctionProtoType>(); 1836e8d8bef9SDimitry Andric 1837e8d8bef9SDimitry Andric repeatForLambdaConversionFunctionCallingConvs( 1838e8d8bef9SDimitry Andric S, *CallOpProto, [&](CallingConv CC) { 1839e8d8bef9SDimitry Andric QualType InvokerFunctionTy = 1840e8d8bef9SDimitry Andric S.getLambdaConversionFunctionResultType(CallOpProto, CC); 1841e8d8bef9SDimitry Andric addFunctionPointerConversion(S, IntroducerRange, Class, CallOperator, 1842e8d8bef9SDimitry Andric InvokerFunctionTy); 1843e8d8bef9SDimitry Andric }); 1844e8d8bef9SDimitry Andric } 1845e8d8bef9SDimitry Andric 18460b57cec5SDimitry Andric /// Add a lambda's conversion to block pointer. 18470b57cec5SDimitry Andric static void addBlockPointerConversion(Sema &S, 18480b57cec5SDimitry Andric SourceRange IntroducerRange, 18490b57cec5SDimitry Andric CXXRecordDecl *Class, 18500b57cec5SDimitry Andric CXXMethodDecl *CallOperator) { 1851e8d8bef9SDimitry Andric const FunctionProtoType *CallOpProto = 1852e8d8bef9SDimitry Andric CallOperator->getType()->castAs<FunctionProtoType>(); 18530b57cec5SDimitry Andric QualType FunctionTy = S.getLambdaConversionFunctionResultType( 1854e8d8bef9SDimitry Andric CallOpProto, getLambdaConversionFunctionCallConv(S, CallOpProto)); 18550b57cec5SDimitry Andric QualType BlockPtrTy = S.Context.getBlockPointerType(FunctionTy); 18560b57cec5SDimitry Andric 18570b57cec5SDimitry Andric FunctionProtoType::ExtProtoInfo ConversionEPI( 18580b57cec5SDimitry Andric S.Context.getDefaultCallingConvention( 18590b57cec5SDimitry Andric /*IsVariadic=*/false, /*IsCXXMethod=*/true)); 18600b57cec5SDimitry Andric ConversionEPI.TypeQuals = Qualifiers(); 18610b57cec5SDimitry Andric ConversionEPI.TypeQuals.addConst(); 1862bdd1243dSDimitry Andric QualType ConvTy = 1863bdd1243dSDimitry Andric S.Context.getFunctionType(BlockPtrTy, std::nullopt, ConversionEPI); 18640b57cec5SDimitry Andric 18650b57cec5SDimitry Andric SourceLocation Loc = IntroducerRange.getBegin(); 18660b57cec5SDimitry Andric DeclarationName Name 18670b57cec5SDimitry Andric = S.Context.DeclarationNames.getCXXConversionFunctionName( 18680b57cec5SDimitry Andric S.Context.getCanonicalType(BlockPtrTy)); 1869fe6060f1SDimitry Andric DeclarationNameLoc NameLoc = DeclarationNameLoc::makeNamedTypeLoc( 1870fe6060f1SDimitry Andric S.Context.getTrivialTypeSourceInfo(BlockPtrTy, Loc)); 18710b57cec5SDimitry Andric CXXConversionDecl *Conversion = CXXConversionDecl::Create( 18720b57cec5SDimitry Andric S.Context, Class, Loc, DeclarationNameInfo(Name, Loc, NameLoc), ConvTy, 18730b57cec5SDimitry Andric S.Context.getTrivialTypeSourceInfo(ConvTy, Loc), 1874349cc55cSDimitry Andric S.getCurFPFeatures().isFPConstrained(), 1875e8d8bef9SDimitry Andric /*isInline=*/true, ExplicitSpecifier(), ConstexprSpecKind::Unspecified, 18760b57cec5SDimitry Andric CallOperator->getBody()->getEndLoc()); 18770b57cec5SDimitry Andric Conversion->setAccess(AS_public); 18780b57cec5SDimitry Andric Conversion->setImplicit(true); 18790b57cec5SDimitry Andric Class->addDecl(Conversion); 18800b57cec5SDimitry Andric } 18810b57cec5SDimitry Andric 18820b57cec5SDimitry Andric ExprResult Sema::BuildCaptureInit(const Capture &Cap, 18830b57cec5SDimitry Andric SourceLocation ImplicitCaptureLoc, 18840b57cec5SDimitry Andric bool IsOpenMPMapping) { 18850b57cec5SDimitry Andric // VLA captures don't have a stored initialization expression. 18860b57cec5SDimitry Andric if (Cap.isVLATypeCapture()) 18870b57cec5SDimitry Andric return ExprResult(); 18880b57cec5SDimitry Andric 18890b57cec5SDimitry Andric // An init-capture is initialized directly from its stored initializer. 18900b57cec5SDimitry Andric if (Cap.isInitCapture()) 1891bdd1243dSDimitry Andric return cast<VarDecl>(Cap.getVariable())->getInit(); 18920b57cec5SDimitry Andric 18930b57cec5SDimitry Andric // For anything else, build an initialization expression. For an implicit 18940b57cec5SDimitry Andric // capture, the capture notionally happens at the capture-default, so use 18950b57cec5SDimitry Andric // that location here. 18960b57cec5SDimitry Andric SourceLocation Loc = 18970b57cec5SDimitry Andric ImplicitCaptureLoc.isValid() ? ImplicitCaptureLoc : Cap.getLocation(); 18980b57cec5SDimitry Andric 18990b57cec5SDimitry Andric // C++11 [expr.prim.lambda]p21: 19000b57cec5SDimitry Andric // When the lambda-expression is evaluated, the entities that 19010b57cec5SDimitry Andric // are captured by copy are used to direct-initialize each 19020b57cec5SDimitry Andric // corresponding non-static data member of the resulting closure 19030b57cec5SDimitry Andric // object. (For array members, the array elements are 19040b57cec5SDimitry Andric // direct-initialized in increasing subscript order.) These 19050b57cec5SDimitry Andric // initializations are performed in the (unspecified) order in 19060b57cec5SDimitry Andric // which the non-static data members are declared. 19070b57cec5SDimitry Andric 19080b57cec5SDimitry Andric // C++ [expr.prim.lambda]p12: 19090b57cec5SDimitry Andric // An entity captured by a lambda-expression is odr-used (3.2) in 19100b57cec5SDimitry Andric // the scope containing the lambda-expression. 19110b57cec5SDimitry Andric ExprResult Init; 19120b57cec5SDimitry Andric IdentifierInfo *Name = nullptr; 19130b57cec5SDimitry Andric if (Cap.isThisCapture()) { 19140b57cec5SDimitry Andric QualType ThisTy = getCurrentThisType(); 19150b57cec5SDimitry Andric Expr *This = BuildCXXThisExpr(Loc, ThisTy, ImplicitCaptureLoc.isValid()); 19160b57cec5SDimitry Andric if (Cap.isCopyCapture()) 19170b57cec5SDimitry Andric Init = CreateBuiltinUnaryOp(Loc, UO_Deref, This); 19180b57cec5SDimitry Andric else 19190b57cec5SDimitry Andric Init = This; 19200b57cec5SDimitry Andric } else { 19210b57cec5SDimitry Andric assert(Cap.isVariableCapture() && "unknown kind of capture"); 1922bdd1243dSDimitry Andric ValueDecl *Var = Cap.getVariable(); 19230b57cec5SDimitry Andric Name = Var->getIdentifier(); 19240b57cec5SDimitry Andric Init = BuildDeclarationNameExpr( 19250b57cec5SDimitry Andric CXXScopeSpec(), DeclarationNameInfo(Var->getDeclName(), Loc), Var); 19260b57cec5SDimitry Andric } 19270b57cec5SDimitry Andric 19280b57cec5SDimitry Andric // In OpenMP, the capture kind doesn't actually describe how to capture: 19290b57cec5SDimitry Andric // variables are "mapped" onto the device in a process that does not formally 19300b57cec5SDimitry Andric // make a copy, even for a "copy capture". 19310b57cec5SDimitry Andric if (IsOpenMPMapping) 19320b57cec5SDimitry Andric return Init; 19330b57cec5SDimitry Andric 19340b57cec5SDimitry Andric if (Init.isInvalid()) 19350b57cec5SDimitry Andric return ExprError(); 19360b57cec5SDimitry Andric 19370b57cec5SDimitry Andric Expr *InitExpr = Init.get(); 19380b57cec5SDimitry Andric InitializedEntity Entity = InitializedEntity::InitializeLambdaCapture( 19390b57cec5SDimitry Andric Name, Cap.getCaptureType(), Loc); 19400b57cec5SDimitry Andric InitializationKind InitKind = 19410b57cec5SDimitry Andric InitializationKind::CreateDirect(Loc, Loc, Loc); 19420b57cec5SDimitry Andric InitializationSequence InitSeq(*this, Entity, InitKind, InitExpr); 19430b57cec5SDimitry Andric return InitSeq.Perform(*this, Entity, InitKind, InitExpr); 19440b57cec5SDimitry Andric } 19450b57cec5SDimitry Andric 19465f757f3fSDimitry Andric ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body) { 19470b57cec5SDimitry Andric LambdaScopeInfo LSI = *cast<LambdaScopeInfo>(FunctionScopes.back()); 19480b57cec5SDimitry Andric ActOnFinishFunctionBody(LSI.CallOperator, Body); 19490b57cec5SDimitry Andric return BuildLambdaExpr(StartLoc, Body->getEndLoc(), &LSI); 19500b57cec5SDimitry Andric } 19510b57cec5SDimitry Andric 19520b57cec5SDimitry Andric static LambdaCaptureDefault 19530b57cec5SDimitry Andric mapImplicitCaptureStyle(CapturingScopeInfo::ImplicitCaptureStyle ICS) { 19540b57cec5SDimitry Andric switch (ICS) { 19550b57cec5SDimitry Andric case CapturingScopeInfo::ImpCap_None: 19560b57cec5SDimitry Andric return LCD_None; 19570b57cec5SDimitry Andric case CapturingScopeInfo::ImpCap_LambdaByval: 19580b57cec5SDimitry Andric return LCD_ByCopy; 19590b57cec5SDimitry Andric case CapturingScopeInfo::ImpCap_CapturedRegion: 19600b57cec5SDimitry Andric case CapturingScopeInfo::ImpCap_LambdaByref: 19610b57cec5SDimitry Andric return LCD_ByRef; 19620b57cec5SDimitry Andric case CapturingScopeInfo::ImpCap_Block: 19630b57cec5SDimitry Andric llvm_unreachable("block capture in lambda"); 19640b57cec5SDimitry Andric } 19650b57cec5SDimitry Andric llvm_unreachable("Unknown implicit capture style"); 19660b57cec5SDimitry Andric } 19670b57cec5SDimitry Andric 19680b57cec5SDimitry Andric bool Sema::CaptureHasSideEffects(const Capture &From) { 19690b57cec5SDimitry Andric if (From.isInitCapture()) { 1970bdd1243dSDimitry Andric Expr *Init = cast<VarDecl>(From.getVariable())->getInit(); 19710b57cec5SDimitry Andric if (Init && Init->HasSideEffects(Context)) 19720b57cec5SDimitry Andric return true; 19730b57cec5SDimitry Andric } 19740b57cec5SDimitry Andric 19750b57cec5SDimitry Andric if (!From.isCopyCapture()) 19760b57cec5SDimitry Andric return false; 19770b57cec5SDimitry Andric 19780b57cec5SDimitry Andric const QualType T = From.isThisCapture() 19790b57cec5SDimitry Andric ? getCurrentThisType()->getPointeeType() 19800b57cec5SDimitry Andric : From.getCaptureType(); 19810b57cec5SDimitry Andric 19820b57cec5SDimitry Andric if (T.isVolatileQualified()) 19830b57cec5SDimitry Andric return true; 19840b57cec5SDimitry Andric 19850b57cec5SDimitry Andric const Type *BaseT = T->getBaseElementTypeUnsafe(); 19860b57cec5SDimitry Andric if (const CXXRecordDecl *RD = BaseT->getAsCXXRecordDecl()) 19870b57cec5SDimitry Andric return !RD->isCompleteDefinition() || !RD->hasTrivialCopyConstructor() || 19880b57cec5SDimitry Andric !RD->hasTrivialDestructor(); 19890b57cec5SDimitry Andric 19900b57cec5SDimitry Andric return false; 19910b57cec5SDimitry Andric } 19920b57cec5SDimitry Andric 19930b57cec5SDimitry Andric bool Sema::DiagnoseUnusedLambdaCapture(SourceRange CaptureRange, 19940b57cec5SDimitry Andric const Capture &From) { 19950b57cec5SDimitry Andric if (CaptureHasSideEffects(From)) 19960b57cec5SDimitry Andric return false; 19970b57cec5SDimitry Andric 19980b57cec5SDimitry Andric if (From.isVLATypeCapture()) 19990b57cec5SDimitry Andric return false; 20000b57cec5SDimitry Andric 20015f757f3fSDimitry Andric // FIXME: maybe we should warn on these if we can find a sensible diagnostic 20025f757f3fSDimitry Andric // message 20035f757f3fSDimitry Andric if (From.isInitCapture() && 20045f757f3fSDimitry Andric From.getVariable()->isPlaceholderVar(getLangOpts())) 20055f757f3fSDimitry Andric return false; 20065f757f3fSDimitry Andric 20070b57cec5SDimitry Andric auto diag = Diag(From.getLocation(), diag::warn_unused_lambda_capture); 20080b57cec5SDimitry Andric if (From.isThisCapture()) 20090b57cec5SDimitry Andric diag << "'this'"; 20100b57cec5SDimitry Andric else 20110b57cec5SDimitry Andric diag << From.getVariable(); 20120b57cec5SDimitry Andric diag << From.isNonODRUsed(); 20130b57cec5SDimitry Andric diag << FixItHint::CreateRemoval(CaptureRange); 20140b57cec5SDimitry Andric return true; 20150b57cec5SDimitry Andric } 20160b57cec5SDimitry Andric 20170b57cec5SDimitry Andric /// Create a field within the lambda class or captured statement record for the 20180b57cec5SDimitry Andric /// given capture. 20190b57cec5SDimitry Andric FieldDecl *Sema::BuildCaptureField(RecordDecl *RD, 20200b57cec5SDimitry Andric const sema::Capture &Capture) { 20210b57cec5SDimitry Andric SourceLocation Loc = Capture.getLocation(); 20220b57cec5SDimitry Andric QualType FieldType = Capture.getCaptureType(); 20230b57cec5SDimitry Andric 20240b57cec5SDimitry Andric TypeSourceInfo *TSI = nullptr; 20250b57cec5SDimitry Andric if (Capture.isVariableCapture()) { 2026bdd1243dSDimitry Andric const auto *Var = dyn_cast_or_null<VarDecl>(Capture.getVariable()); 2027bdd1243dSDimitry Andric if (Var && Var->isInitCapture()) 2028bdd1243dSDimitry Andric TSI = Var->getTypeSourceInfo(); 20290b57cec5SDimitry Andric } 20300b57cec5SDimitry Andric 20310b57cec5SDimitry Andric // FIXME: Should we really be doing this? A null TypeSourceInfo seems more 20320b57cec5SDimitry Andric // appropriate, at least for an implicit capture. 20330b57cec5SDimitry Andric if (!TSI) 20340b57cec5SDimitry Andric TSI = Context.getTrivialTypeSourceInfo(FieldType, Loc); 20350b57cec5SDimitry Andric 20360b57cec5SDimitry Andric // Build the non-static data member. 20370b57cec5SDimitry Andric FieldDecl *Field = 2038e8d8bef9SDimitry Andric FieldDecl::Create(Context, RD, /*StartLoc=*/Loc, /*IdLoc=*/Loc, 2039e8d8bef9SDimitry Andric /*Id=*/nullptr, FieldType, TSI, /*BW=*/nullptr, 2040e8d8bef9SDimitry Andric /*Mutable=*/false, ICIS_NoInit); 20410b57cec5SDimitry Andric // If the variable being captured has an invalid type, mark the class as 20420b57cec5SDimitry Andric // invalid as well. 20430b57cec5SDimitry Andric if (!FieldType->isDependentType()) { 20445ffd83dbSDimitry Andric if (RequireCompleteSizedType(Loc, FieldType, 20455ffd83dbSDimitry Andric diag::err_field_incomplete_or_sizeless)) { 20460b57cec5SDimitry Andric RD->setInvalidDecl(); 20470b57cec5SDimitry Andric Field->setInvalidDecl(); 20480b57cec5SDimitry Andric } else { 20490b57cec5SDimitry Andric NamedDecl *Def; 20500b57cec5SDimitry Andric FieldType->isIncompleteType(&Def); 20510b57cec5SDimitry Andric if (Def && Def->isInvalidDecl()) { 20520b57cec5SDimitry Andric RD->setInvalidDecl(); 20530b57cec5SDimitry Andric Field->setInvalidDecl(); 20540b57cec5SDimitry Andric } 20550b57cec5SDimitry Andric } 20560b57cec5SDimitry Andric } 20570b57cec5SDimitry Andric Field->setImplicit(true); 20580b57cec5SDimitry Andric Field->setAccess(AS_private); 20590b57cec5SDimitry Andric RD->addDecl(Field); 20600b57cec5SDimitry Andric 20610b57cec5SDimitry Andric if (Capture.isVLATypeCapture()) 20620b57cec5SDimitry Andric Field->setCapturedVLAType(Capture.getCapturedVLAType()); 20630b57cec5SDimitry Andric 20640b57cec5SDimitry Andric return Field; 20650b57cec5SDimitry Andric } 20660b57cec5SDimitry Andric 20670b57cec5SDimitry Andric ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, 20680b57cec5SDimitry Andric LambdaScopeInfo *LSI) { 20690b57cec5SDimitry Andric // Collect information from the lambda scope. 20700b57cec5SDimitry Andric SmallVector<LambdaCapture, 4> Captures; 20710b57cec5SDimitry Andric SmallVector<Expr *, 4> CaptureInits; 20720b57cec5SDimitry Andric SourceLocation CaptureDefaultLoc = LSI->CaptureDefaultLoc; 20730b57cec5SDimitry Andric LambdaCaptureDefault CaptureDefault = 20740b57cec5SDimitry Andric mapImplicitCaptureStyle(LSI->ImpCaptureStyle); 20750b57cec5SDimitry Andric CXXRecordDecl *Class; 20760b57cec5SDimitry Andric CXXMethodDecl *CallOperator; 20770b57cec5SDimitry Andric SourceRange IntroducerRange; 20780b57cec5SDimitry Andric bool ExplicitParams; 20790b57cec5SDimitry Andric bool ExplicitResultType; 20800b57cec5SDimitry Andric CleanupInfo LambdaCleanup; 20810b57cec5SDimitry Andric bool ContainsUnexpandedParameterPack; 20820b57cec5SDimitry Andric bool IsGenericLambda; 20830b57cec5SDimitry Andric { 20840b57cec5SDimitry Andric CallOperator = LSI->CallOperator; 20850b57cec5SDimitry Andric Class = LSI->Lambda; 20860b57cec5SDimitry Andric IntroducerRange = LSI->IntroducerRange; 20870b57cec5SDimitry Andric ExplicitParams = LSI->ExplicitParams; 20880b57cec5SDimitry Andric ExplicitResultType = !LSI->HasImplicitReturnType; 20890b57cec5SDimitry Andric LambdaCleanup = LSI->Cleanup; 20900b57cec5SDimitry Andric ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack; 20910b57cec5SDimitry Andric IsGenericLambda = Class->isGenericLambda(); 20920b57cec5SDimitry Andric 20930b57cec5SDimitry Andric CallOperator->setLexicalDeclContext(Class); 20940b57cec5SDimitry Andric Decl *TemplateOrNonTemplateCallOperatorDecl = 20950b57cec5SDimitry Andric CallOperator->getDescribedFunctionTemplate() 20960b57cec5SDimitry Andric ? CallOperator->getDescribedFunctionTemplate() 20970b57cec5SDimitry Andric : cast<Decl>(CallOperator); 20980b57cec5SDimitry Andric 2099a7dea167SDimitry Andric // FIXME: Is this really the best choice? Keeping the lexical decl context 2100a7dea167SDimitry Andric // set as CurContext seems more faithful to the source. 21010b57cec5SDimitry Andric TemplateOrNonTemplateCallOperatorDecl->setLexicalDeclContext(Class); 21020b57cec5SDimitry Andric 21030b57cec5SDimitry Andric PopExpressionEvaluationContext(); 21040b57cec5SDimitry Andric 21050b57cec5SDimitry Andric // True if the current capture has a used capture or default before it. 21060b57cec5SDimitry Andric bool CurHasPreviousCapture = CaptureDefault != LCD_None; 21070b57cec5SDimitry Andric SourceLocation PrevCaptureLoc = CurHasPreviousCapture ? 21080b57cec5SDimitry Andric CaptureDefaultLoc : IntroducerRange.getBegin(); 21090b57cec5SDimitry Andric 21100b57cec5SDimitry Andric for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) { 21110b57cec5SDimitry Andric const Capture &From = LSI->Captures[I]; 21120b57cec5SDimitry Andric 21130b57cec5SDimitry Andric if (From.isInvalid()) 21140b57cec5SDimitry Andric return ExprError(); 21150b57cec5SDimitry Andric 21160b57cec5SDimitry Andric assert(!From.isBlockCapture() && "Cannot capture __block variables"); 21170b57cec5SDimitry Andric bool IsImplicit = I >= LSI->NumExplicitCaptures; 21180b57cec5SDimitry Andric SourceLocation ImplicitCaptureLoc = 21190b57cec5SDimitry Andric IsImplicit ? CaptureDefaultLoc : SourceLocation(); 21200b57cec5SDimitry Andric 21210b57cec5SDimitry Andric // Use source ranges of explicit captures for fixits where available. 21220b57cec5SDimitry Andric SourceRange CaptureRange = LSI->ExplicitCaptureRanges[I]; 21230b57cec5SDimitry Andric 21240b57cec5SDimitry Andric // Warn about unused explicit captures. 21250b57cec5SDimitry Andric bool IsCaptureUsed = true; 21260b57cec5SDimitry Andric if (!CurContext->isDependentContext() && !IsImplicit && 21270b57cec5SDimitry Andric !From.isODRUsed()) { 21280b57cec5SDimitry Andric // Initialized captures that are non-ODR used may not be eliminated. 21290b57cec5SDimitry Andric // FIXME: Where did the IsGenericLambda here come from? 21300b57cec5SDimitry Andric bool NonODRUsedInitCapture = 21310b57cec5SDimitry Andric IsGenericLambda && From.isNonODRUsed() && From.isInitCapture(); 21320b57cec5SDimitry Andric if (!NonODRUsedInitCapture) { 21330b57cec5SDimitry Andric bool IsLast = (I + 1) == LSI->NumExplicitCaptures; 21340b57cec5SDimitry Andric SourceRange FixItRange; 21350b57cec5SDimitry Andric if (CaptureRange.isValid()) { 21360b57cec5SDimitry Andric if (!CurHasPreviousCapture && !IsLast) { 21370b57cec5SDimitry Andric // If there are no captures preceding this capture, remove the 21380b57cec5SDimitry Andric // following comma. 21390b57cec5SDimitry Andric FixItRange = SourceRange(CaptureRange.getBegin(), 21400b57cec5SDimitry Andric getLocForEndOfToken(CaptureRange.getEnd())); 21410b57cec5SDimitry Andric } else { 21420b57cec5SDimitry Andric // Otherwise, remove the comma since the last used capture. 21430b57cec5SDimitry Andric FixItRange = SourceRange(getLocForEndOfToken(PrevCaptureLoc), 21440b57cec5SDimitry Andric CaptureRange.getEnd()); 21450b57cec5SDimitry Andric } 21460b57cec5SDimitry Andric } 21470b57cec5SDimitry Andric 21480b57cec5SDimitry Andric IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From); 21490b57cec5SDimitry Andric } 21500b57cec5SDimitry Andric } 21510b57cec5SDimitry Andric 21520b57cec5SDimitry Andric if (CaptureRange.isValid()) { 21530b57cec5SDimitry Andric CurHasPreviousCapture |= IsCaptureUsed; 21540b57cec5SDimitry Andric PrevCaptureLoc = CaptureRange.getEnd(); 21550b57cec5SDimitry Andric } 21560b57cec5SDimitry Andric 21570b57cec5SDimitry Andric // Map the capture to our AST representation. 21580b57cec5SDimitry Andric LambdaCapture Capture = [&] { 21590b57cec5SDimitry Andric if (From.isThisCapture()) { 21600b57cec5SDimitry Andric // Capturing 'this' implicitly with a default of '[=]' is deprecated, 21610b57cec5SDimitry Andric // because it results in a reference capture. Don't warn prior to 21620b57cec5SDimitry Andric // C++2a; there's nothing that can be done about it before then. 21635ffd83dbSDimitry Andric if (getLangOpts().CPlusPlus20 && IsImplicit && 21640b57cec5SDimitry Andric CaptureDefault == LCD_ByCopy) { 21650b57cec5SDimitry Andric Diag(From.getLocation(), diag::warn_deprecated_this_capture); 21660b57cec5SDimitry Andric Diag(CaptureDefaultLoc, diag::note_deprecated_this_capture) 21670b57cec5SDimitry Andric << FixItHint::CreateInsertion( 21680b57cec5SDimitry Andric getLocForEndOfToken(CaptureDefaultLoc), ", this"); 21690b57cec5SDimitry Andric } 21700b57cec5SDimitry Andric return LambdaCapture(From.getLocation(), IsImplicit, 21710b57cec5SDimitry Andric From.isCopyCapture() ? LCK_StarThis : LCK_This); 21720b57cec5SDimitry Andric } else if (From.isVLATypeCapture()) { 21730b57cec5SDimitry Andric return LambdaCapture(From.getLocation(), IsImplicit, LCK_VLAType); 21740b57cec5SDimitry Andric } else { 21750b57cec5SDimitry Andric assert(From.isVariableCapture() && "unknown kind of capture"); 2176bdd1243dSDimitry Andric ValueDecl *Var = From.getVariable(); 21770b57cec5SDimitry Andric LambdaCaptureKind Kind = 21780b57cec5SDimitry Andric From.isCopyCapture() ? LCK_ByCopy : LCK_ByRef; 21790b57cec5SDimitry Andric return LambdaCapture(From.getLocation(), IsImplicit, Kind, Var, 21800b57cec5SDimitry Andric From.getEllipsisLoc()); 21810b57cec5SDimitry Andric } 21820b57cec5SDimitry Andric }(); 21830b57cec5SDimitry Andric 21840b57cec5SDimitry Andric // Form the initializer for the capture field. 21850b57cec5SDimitry Andric ExprResult Init = BuildCaptureInit(From, ImplicitCaptureLoc); 21860b57cec5SDimitry Andric 21870b57cec5SDimitry Andric // FIXME: Skip this capture if the capture is not used, the initializer 21880b57cec5SDimitry Andric // has no side-effects, the type of the capture is trivial, and the 21890b57cec5SDimitry Andric // lambda is not externally visible. 21900b57cec5SDimitry Andric 21910b57cec5SDimitry Andric // Add a FieldDecl for the capture and form its initializer. 21920b57cec5SDimitry Andric BuildCaptureField(Class, From); 21930b57cec5SDimitry Andric Captures.push_back(Capture); 21940b57cec5SDimitry Andric CaptureInits.push_back(Init.get()); 21955ffd83dbSDimitry Andric 21965ffd83dbSDimitry Andric if (LangOpts.CUDA) 2197*0fca6ea1SDimitry Andric CUDA().CheckLambdaCapture(CallOperator, From); 21980b57cec5SDimitry Andric } 21990b57cec5SDimitry Andric 2200e8d8bef9SDimitry Andric Class->setCaptures(Context, Captures); 22015ffd83dbSDimitry Andric 22020b57cec5SDimitry Andric // C++11 [expr.prim.lambda]p6: 22030b57cec5SDimitry Andric // The closure type for a lambda-expression with no lambda-capture 22040b57cec5SDimitry Andric // has a public non-virtual non-explicit const conversion function 22050b57cec5SDimitry Andric // to pointer to function having the same parameter and return 22060b57cec5SDimitry Andric // types as the closure type's function call operator. 22070b57cec5SDimitry Andric if (Captures.empty() && CaptureDefault == LCD_None) 2208e8d8bef9SDimitry Andric addFunctionPointerConversions(*this, IntroducerRange, Class, 22090b57cec5SDimitry Andric CallOperator); 22100b57cec5SDimitry Andric 22110b57cec5SDimitry Andric // Objective-C++: 22120b57cec5SDimitry Andric // The closure type for a lambda-expression has a public non-virtual 22130b57cec5SDimitry Andric // non-explicit const conversion function to a block pointer having the 22140b57cec5SDimitry Andric // same parameter and return types as the closure type's function call 22150b57cec5SDimitry Andric // operator. 22160b57cec5SDimitry Andric // FIXME: Fix generic lambda to block conversions. 22170b57cec5SDimitry Andric if (getLangOpts().Blocks && getLangOpts().ObjC && !IsGenericLambda) 22180b57cec5SDimitry Andric addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator); 22190b57cec5SDimitry Andric 22200b57cec5SDimitry Andric // Finalize the lambda class. 22210b57cec5SDimitry Andric SmallVector<Decl*, 4> Fields(Class->fields()); 22220b57cec5SDimitry Andric ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(), 22230b57cec5SDimitry Andric SourceLocation(), ParsedAttributesView()); 2224480093f4SDimitry Andric CheckCompletedCXXClass(nullptr, Class); 22250b57cec5SDimitry Andric } 22260b57cec5SDimitry Andric 22270b57cec5SDimitry Andric Cleanup.mergeFrom(LambdaCleanup); 22280b57cec5SDimitry Andric 22290b57cec5SDimitry Andric LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange, 22300b57cec5SDimitry Andric CaptureDefault, CaptureDefaultLoc, 22310b57cec5SDimitry Andric ExplicitParams, ExplicitResultType, 22320b57cec5SDimitry Andric CaptureInits, EndLoc, 22330b57cec5SDimitry Andric ContainsUnexpandedParameterPack); 22340b57cec5SDimitry Andric // If the lambda expression's call operator is not explicitly marked constexpr 22350b57cec5SDimitry Andric // and we are not in a dependent context, analyze the call operator to infer 22360b57cec5SDimitry Andric // its constexpr-ness, suppressing diagnostics while doing so. 22370b57cec5SDimitry Andric if (getLangOpts().CPlusPlus17 && !CallOperator->isInvalidDecl() && 22380b57cec5SDimitry Andric !CallOperator->isConstexpr() && 22390b57cec5SDimitry Andric !isa<CoroutineBodyStmt>(CallOperator->getBody()) && 22400b57cec5SDimitry Andric !Class->getDeclContext()->isDependentContext()) { 22410b57cec5SDimitry Andric CallOperator->setConstexprKind( 2242a7dea167SDimitry Andric CheckConstexprFunctionDefinition(CallOperator, 2243a7dea167SDimitry Andric CheckConstexprKind::CheckValid) 2244e8d8bef9SDimitry Andric ? ConstexprSpecKind::Constexpr 2245e8d8bef9SDimitry Andric : ConstexprSpecKind::Unspecified); 22460b57cec5SDimitry Andric } 22470b57cec5SDimitry Andric 22480b57cec5SDimitry Andric // Emit delayed shadowing warnings now that the full capture list is known. 22490b57cec5SDimitry Andric DiagnoseShadowingLambdaDecls(LSI); 22500b57cec5SDimitry Andric 22510b57cec5SDimitry Andric if (!CurContext->isDependentContext()) { 22520b57cec5SDimitry Andric switch (ExprEvalContexts.back().Context) { 22530b57cec5SDimitry Andric // C++11 [expr.prim.lambda]p2: 22540b57cec5SDimitry Andric // A lambda-expression shall not appear in an unevaluated operand 22550b57cec5SDimitry Andric // (Clause 5). 22560b57cec5SDimitry Andric case ExpressionEvaluationContext::Unevaluated: 22570b57cec5SDimitry Andric case ExpressionEvaluationContext::UnevaluatedList: 22580b57cec5SDimitry Andric case ExpressionEvaluationContext::UnevaluatedAbstract: 22590b57cec5SDimitry Andric // C++1y [expr.const]p2: 22600b57cec5SDimitry Andric // A conditional-expression e is a core constant expression unless the 22610b57cec5SDimitry Andric // evaluation of e, following the rules of the abstract machine, would 22620b57cec5SDimitry Andric // evaluate [...] a lambda-expression. 22630b57cec5SDimitry Andric // 22640b57cec5SDimitry Andric // This is technically incorrect, there are some constant evaluated contexts 22650b57cec5SDimitry Andric // where this should be allowed. We should probably fix this when DR1607 is 22660b57cec5SDimitry Andric // ratified, it lays out the exact set of conditions where we shouldn't 22670b57cec5SDimitry Andric // allow a lambda-expression. 22680b57cec5SDimitry Andric case ExpressionEvaluationContext::ConstantEvaluated: 2269349cc55cSDimitry Andric case ExpressionEvaluationContext::ImmediateFunctionContext: 22700b57cec5SDimitry Andric // We don't actually diagnose this case immediately, because we 22710b57cec5SDimitry Andric // could be within a context where we might find out later that 22720b57cec5SDimitry Andric // the expression is potentially evaluated (e.g., for typeid). 22730b57cec5SDimitry Andric ExprEvalContexts.back().Lambdas.push_back(Lambda); 22740b57cec5SDimitry Andric break; 22750b57cec5SDimitry Andric 22760b57cec5SDimitry Andric case ExpressionEvaluationContext::DiscardedStatement: 22770b57cec5SDimitry Andric case ExpressionEvaluationContext::PotentiallyEvaluated: 22780b57cec5SDimitry Andric case ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed: 22790b57cec5SDimitry Andric break; 22800b57cec5SDimitry Andric } 22810b57cec5SDimitry Andric } 22820b57cec5SDimitry Andric 22830b57cec5SDimitry Andric return MaybeBindToTemporary(Lambda); 22840b57cec5SDimitry Andric } 22850b57cec5SDimitry Andric 22860b57cec5SDimitry Andric ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, 22870b57cec5SDimitry Andric SourceLocation ConvLocation, 22880b57cec5SDimitry Andric CXXConversionDecl *Conv, 22890b57cec5SDimitry Andric Expr *Src) { 22900b57cec5SDimitry Andric // Make sure that the lambda call operator is marked used. 22910b57cec5SDimitry Andric CXXRecordDecl *Lambda = Conv->getParent(); 22920b57cec5SDimitry Andric CXXMethodDecl *CallOperator 22930b57cec5SDimitry Andric = cast<CXXMethodDecl>( 22940b57cec5SDimitry Andric Lambda->lookup( 22950b57cec5SDimitry Andric Context.DeclarationNames.getCXXOperatorName(OO_Call)).front()); 22960b57cec5SDimitry Andric CallOperator->setReferenced(); 22970b57cec5SDimitry Andric CallOperator->markUsed(Context); 22980b57cec5SDimitry Andric 22990b57cec5SDimitry Andric ExprResult Init = PerformCopyInitialization( 230028a41182SDimitry Andric InitializedEntity::InitializeLambdaToBlock(ConvLocation, Src->getType()), 23010b57cec5SDimitry Andric CurrentLocation, Src); 23020b57cec5SDimitry Andric if (!Init.isInvalid()) 23030b57cec5SDimitry Andric Init = ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 23040b57cec5SDimitry Andric 23050b57cec5SDimitry Andric if (Init.isInvalid()) 23060b57cec5SDimitry Andric return ExprError(); 23070b57cec5SDimitry Andric 23080b57cec5SDimitry Andric // Create the new block to be returned. 23090b57cec5SDimitry Andric BlockDecl *Block = BlockDecl::Create(Context, CurContext, ConvLocation); 23100b57cec5SDimitry Andric 23110b57cec5SDimitry Andric // Set the type information. 23120b57cec5SDimitry Andric Block->setSignatureAsWritten(CallOperator->getTypeSourceInfo()); 23130b57cec5SDimitry Andric Block->setIsVariadic(CallOperator->isVariadic()); 23140b57cec5SDimitry Andric Block->setBlockMissingReturnType(false); 23150b57cec5SDimitry Andric 23160b57cec5SDimitry Andric // Add parameters. 23170b57cec5SDimitry Andric SmallVector<ParmVarDecl *, 4> BlockParams; 23180b57cec5SDimitry Andric for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) { 23190b57cec5SDimitry Andric ParmVarDecl *From = CallOperator->getParamDecl(I); 23200b57cec5SDimitry Andric BlockParams.push_back(ParmVarDecl::Create( 23210b57cec5SDimitry Andric Context, Block, From->getBeginLoc(), From->getLocation(), 23220b57cec5SDimitry Andric From->getIdentifier(), From->getType(), From->getTypeSourceInfo(), 23230b57cec5SDimitry Andric From->getStorageClass(), 23240b57cec5SDimitry Andric /*DefArg=*/nullptr)); 23250b57cec5SDimitry Andric } 23260b57cec5SDimitry Andric Block->setParams(BlockParams); 23270b57cec5SDimitry Andric 23280b57cec5SDimitry Andric Block->setIsConversionFromLambda(true); 23290b57cec5SDimitry Andric 23300b57cec5SDimitry Andric // Add capture. The capture uses a fake variable, which doesn't correspond 23310b57cec5SDimitry Andric // to any actual memory location. However, the initializer copy-initializes 23320b57cec5SDimitry Andric // the lambda object. 23330b57cec5SDimitry Andric TypeSourceInfo *CapVarTSI = 23340b57cec5SDimitry Andric Context.getTrivialTypeSourceInfo(Src->getType()); 23350b57cec5SDimitry Andric VarDecl *CapVar = VarDecl::Create(Context, Block, ConvLocation, 23360b57cec5SDimitry Andric ConvLocation, nullptr, 23370b57cec5SDimitry Andric Src->getType(), CapVarTSI, 23380b57cec5SDimitry Andric SC_None); 23390b57cec5SDimitry Andric BlockDecl::Capture Capture(/*variable=*/CapVar, /*byRef=*/false, 23400b57cec5SDimitry Andric /*nested=*/false, /*copy=*/Init.get()); 23410b57cec5SDimitry Andric Block->setCaptures(Context, Capture, /*CapturesCXXThis=*/false); 23420b57cec5SDimitry Andric 23430b57cec5SDimitry Andric // Add a fake function body to the block. IR generation is responsible 23440b57cec5SDimitry Andric // for filling in the actual body, which cannot be expressed as an AST. 23450b57cec5SDimitry Andric Block->setBody(new (Context) CompoundStmt(ConvLocation)); 23460b57cec5SDimitry Andric 23470b57cec5SDimitry Andric // Create the block literal expression. 23480b57cec5SDimitry Andric Expr *BuildBlock = new (Context) BlockExpr(Block, Conv->getConversionType()); 23490b57cec5SDimitry Andric ExprCleanupObjects.push_back(Block); 23500b57cec5SDimitry Andric Cleanup.setExprNeedsCleanups(true); 23510b57cec5SDimitry Andric 23520b57cec5SDimitry Andric return BuildBlock; 23530b57cec5SDimitry Andric } 2354feb5b0c7SDimitry Andric 23555f757f3fSDimitry Andric static FunctionDecl *getPatternFunctionDecl(FunctionDecl *FD) { 23565f757f3fSDimitry Andric if (FD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization) { 23575f757f3fSDimitry Andric while (FD->getInstantiatedFromMemberFunction()) 23585f757f3fSDimitry Andric FD = FD->getInstantiatedFromMemberFunction(); 23595f757f3fSDimitry Andric return FD; 23605f757f3fSDimitry Andric } 23615f757f3fSDimitry Andric 23625f757f3fSDimitry Andric if (FD->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate) 23635f757f3fSDimitry Andric return FD->getInstantiatedFromDecl(); 23645f757f3fSDimitry Andric 23655f757f3fSDimitry Andric FunctionTemplateDecl *FTD = FD->getPrimaryTemplate(); 23665f757f3fSDimitry Andric if (!FTD) 23675f757f3fSDimitry Andric return nullptr; 23685f757f3fSDimitry Andric 23695f757f3fSDimitry Andric while (FTD->getInstantiatedFromMemberTemplate()) 23705f757f3fSDimitry Andric FTD = FTD->getInstantiatedFromMemberTemplate(); 23715f757f3fSDimitry Andric 23725f757f3fSDimitry Andric return FTD->getTemplatedDecl(); 23735f757f3fSDimitry Andric } 23745f757f3fSDimitry Andric 2375feb5b0c7SDimitry Andric Sema::LambdaScopeForCallOperatorInstantiationRAII:: 2376feb5b0c7SDimitry Andric LambdaScopeForCallOperatorInstantiationRAII( 23775f757f3fSDimitry Andric Sema &SemaRef, FunctionDecl *FD, MultiLevelTemplateArgumentList MLTAL, 23785f757f3fSDimitry Andric LocalInstantiationScope &Scope, bool ShouldAddDeclsFromParentScope) 23795f757f3fSDimitry Andric : FunctionScopeRAII(SemaRef) { 2380feb5b0c7SDimitry Andric if (!isLambdaCallOperator(FD)) { 2381feb5b0c7SDimitry Andric FunctionScopeRAII::disable(); 2382feb5b0c7SDimitry Andric return; 2383feb5b0c7SDimitry Andric } 2384feb5b0c7SDimitry Andric 23855f757f3fSDimitry Andric SemaRef.RebuildLambdaScopeInfo(cast<CXXMethodDecl>(FD)); 2386feb5b0c7SDimitry Andric 2387*0fca6ea1SDimitry Andric FunctionDecl *FDPattern = getPatternFunctionDecl(FD); 2388*0fca6ea1SDimitry Andric if (!FDPattern) 2389*0fca6ea1SDimitry Andric return; 2390feb5b0c7SDimitry Andric 2391*0fca6ea1SDimitry Andric SemaRef.addInstantiatedCapturesToScope(FD, FDPattern, Scope, MLTAL); 23925f757f3fSDimitry Andric 2393*0fca6ea1SDimitry Andric if (!ShouldAddDeclsFromParentScope) 2394*0fca6ea1SDimitry Andric return; 23955f757f3fSDimitry Andric 2396*0fca6ea1SDimitry Andric llvm::SmallVector<std::pair<FunctionDecl *, FunctionDecl *>, 4> 2397*0fca6ea1SDimitry Andric ParentInstantiations; 2398*0fca6ea1SDimitry Andric while (true) { 2399*0fca6ea1SDimitry Andric FDPattern = 2400*0fca6ea1SDimitry Andric dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(FDPattern)); 2401*0fca6ea1SDimitry Andric FD = dyn_cast<FunctionDecl>(getLambdaAwareParentOfDeclContext(FD)); 2402*0fca6ea1SDimitry Andric 2403*0fca6ea1SDimitry Andric if (!FDPattern || !FD) 24045f757f3fSDimitry Andric break; 24055f757f3fSDimitry Andric 2406*0fca6ea1SDimitry Andric ParentInstantiations.emplace_back(FDPattern, FD); 24075f757f3fSDimitry Andric } 2408*0fca6ea1SDimitry Andric 2409*0fca6ea1SDimitry Andric // Add instantiated parameters and local vars to scopes, starting from the 2410*0fca6ea1SDimitry Andric // outermost lambda to the innermost lambda. This ordering ensures that 2411*0fca6ea1SDimitry Andric // parameters in inner lambdas can correctly depend on those defined 2412*0fca6ea1SDimitry Andric // in outer lambdas, e.g. auto L = [](auto... x) { 2413*0fca6ea1SDimitry Andric // return [](decltype(x)... y) { }; // `y` depends on `x` 2414*0fca6ea1SDimitry Andric // }; 2415*0fca6ea1SDimitry Andric 2416*0fca6ea1SDimitry Andric for (const auto &[FDPattern, FD] : llvm::reverse(ParentInstantiations)) { 2417*0fca6ea1SDimitry Andric SemaRef.addInstantiatedParametersToScope(FD, FDPattern, Scope, MLTAL); 2418*0fca6ea1SDimitry Andric SemaRef.addInstantiatedLocalVarsToScope(FD, FDPattern, Scope); 24195f757f3fSDimitry Andric } 2420feb5b0c7SDimitry Andric } 2421