//===--- SemaLambda.cpp - Semantic Analysis for C++11 Lambdas -------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements semantic analysis for C++ lambda expressions. // //===----------------------------------------------------------------------===// #include "clang/Sema/DeclSpec.h" #include "TypeLocBuilder.h" #include "clang/AST/ASTLambda.h" #include "clang/AST/ExprCXX.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaLambda.h" using namespace clang; using namespace sema; /// \brief Examines the FunctionScopeInfo stack to determine the nearest /// enclosing lambda (to the current lambda) that is 'capture-ready' for /// the variable referenced in the current lambda (i.e. \p VarToCapture). /// If successful, returns the index into Sema's FunctionScopeInfo stack /// of the capture-ready lambda's LambdaScopeInfo. /// /// Climbs down the stack of lambdas (deepest nested lambda - i.e. current /// lambda - is on top) to determine the index of the nearest enclosing/outer /// lambda that is ready to capture the \p VarToCapture being referenced in /// the current lambda. /// As we climb down the stack, we want the index of the first such lambda - /// that is the lambda with the highest index that is 'capture-ready'. /// /// A lambda 'L' is capture-ready for 'V' (var or this) if: /// - its enclosing context is non-dependent /// - and if the chain of lambdas between L and the lambda in which /// V is potentially used (i.e. the lambda at the top of the scope info /// stack), can all capture or have already captured V. /// If \p VarToCapture is 'null' then we are trying to capture 'this'. /// /// Note that a lambda that is deemed 'capture-ready' still needs to be checked /// for whether it is 'capture-capable' (see /// getStackIndexOfNearestEnclosingCaptureCapableLambda), before it can truly /// capture. /// /// \param FunctionScopes - Sema's stack of nested FunctionScopeInfo's (which a /// LambdaScopeInfo inherits from). The current/deepest/innermost lambda /// is at the top of the stack and has the highest index. /// \param VarToCapture - the variable to capture. If NULL, capture 'this'. /// /// \returns An Optional<unsigned> Index that if evaluates to 'true' contains /// the index (into Sema's FunctionScopeInfo stack) of the innermost lambda /// which is capture-ready. If the return value evaluates to 'false' then /// no lambda is capture-ready for \p VarToCapture. static inline Optional<unsigned> getStackIndexOfNearestEnclosingCaptureReadyLambda( ArrayRef<const clang::sema::FunctionScopeInfo *> FunctionScopes, VarDecl *VarToCapture) { // Label failure to capture. const Optional<unsigned> NoLambdaIsCaptureReady; assert( isa<clang::sema::LambdaScopeInfo>( FunctionScopes[FunctionScopes.size() - 1]) && "The function on the top of sema's function-info stack must be a lambda"); // If VarToCapture is null, we are attempting to capture 'this'. const bool IsCapturingThis = !VarToCapture; const bool IsCapturingVariable = !IsCapturingThis; // Start with the current lambda at the top of the stack (highest index). unsigned CurScopeIndex = FunctionScopes.size() - 1; DeclContext *EnclosingDC = cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex])->CallOperator; do { const clang::sema::LambdaScopeInfo *LSI = cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]); // IF we have climbed down to an intervening enclosing lambda that contains // the variable declaration - it obviously can/must not capture the // variable. // Since its enclosing DC is dependent, all the lambdas between it and the // innermost nested lambda are dependent (otherwise we wouldn't have // arrived here) - so we don't yet have a lambda that can capture the // variable. if (IsCapturingVariable && VarToCapture->getDeclContext()->Equals(EnclosingDC)) return NoLambdaIsCaptureReady; // For an enclosing lambda to be capture ready for an entity, all // intervening lambda's have to be able to capture that entity. If even // one of the intervening lambda's is not capable of capturing the entity // then no enclosing lambda can ever capture that entity. // For e.g. // const int x = 10; // [=](auto a) { #1 // [](auto b) { #2 <-- an intervening lambda that can never capture 'x' // [=](auto c) { #3 // f(x, c); <-- can not lead to x's speculative capture by #1 or #2 // }; }; }; // If they do not have a default implicit capture, check to see // if the entity has already been explicitly captured. // If even a single dependent enclosing lambda lacks the capability // to ever capture this variable, there is no further enclosing // non-dependent lambda that can capture this variable. if (LSI->ImpCaptureStyle == sema::LambdaScopeInfo::ImpCap_None) { if (IsCapturingVariable && !LSI->isCaptured(VarToCapture)) return NoLambdaIsCaptureReady; if (IsCapturingThis && !LSI->isCXXThisCaptured()) return NoLambdaIsCaptureReady; } EnclosingDC = getLambdaAwareParentOfDeclContext(EnclosingDC); assert(CurScopeIndex); --CurScopeIndex; } while (!EnclosingDC->isTranslationUnit() && EnclosingDC->isDependentContext() && isLambdaCallOperator(EnclosingDC)); assert(CurScopeIndex < (FunctionScopes.size() - 1)); // If the enclosingDC is not dependent, then the immediately nested lambda // (one index above) is capture-ready. if (!EnclosingDC->isDependentContext()) return CurScopeIndex + 1; return NoLambdaIsCaptureReady; } /// \brief Examines the FunctionScopeInfo stack to determine the nearest /// enclosing lambda (to the current lambda) that is 'capture-capable' for /// the variable referenced in the current lambda (i.e. \p VarToCapture). /// If successful, returns the index into Sema's FunctionScopeInfo stack /// of the capture-capable lambda's LambdaScopeInfo. /// /// Given the current stack of lambdas being processed by Sema and /// the variable of interest, to identify the nearest enclosing lambda (to the /// current lambda at the top of the stack) that can truly capture /// a variable, it has to have the following two properties: /// a) 'capture-ready' - be the innermost lambda that is 'capture-ready': /// - climb down the stack (i.e. starting from the innermost and examining /// each outer lambda step by step) checking if each enclosing /// lambda can either implicitly or explicitly capture the variable. /// Record the first such lambda that is enclosed in a non-dependent /// context. If no such lambda currently exists return failure. /// b) 'capture-capable' - make sure the 'capture-ready' lambda can truly /// capture the variable by checking all its enclosing lambdas: /// - check if all outer lambdas enclosing the 'capture-ready' lambda /// identified above in 'a' can also capture the variable (this is done /// via tryCaptureVariable for variables and CheckCXXThisCapture for /// 'this' by passing in the index of the Lambda identified in step 'a') /// /// \param FunctionScopes - Sema's stack of nested FunctionScopeInfo's (which a /// LambdaScopeInfo inherits from). The current/deepest/innermost lambda /// is at the top of the stack. /// /// \param VarToCapture - the variable to capture. If NULL, capture 'this'. /// /// /// \returns An Optional<unsigned> Index that if evaluates to 'true' contains /// the index (into Sema's FunctionScopeInfo stack) of the innermost lambda /// which is capture-capable. If the return value evaluates to 'false' then /// no lambda is capture-capable for \p VarToCapture. Optional<unsigned> clang::getStackIndexOfNearestEnclosingCaptureCapableLambda( ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes, VarDecl *VarToCapture, Sema &S) { const Optional<unsigned> NoLambdaIsCaptureCapable; const Optional<unsigned> OptionalStackIndex = getStackIndexOfNearestEnclosingCaptureReadyLambda(FunctionScopes, VarToCapture); if (!OptionalStackIndex) return NoLambdaIsCaptureCapable; const unsigned IndexOfCaptureReadyLambda = OptionalStackIndex.getValue(); assert(((IndexOfCaptureReadyLambda != (FunctionScopes.size() - 1)) || S.getCurGenericLambda()) && "The capture ready lambda for a potential capture can only be the " "current lambda if it is a generic lambda"); const sema::LambdaScopeInfo *const CaptureReadyLambdaLSI = cast<sema::LambdaScopeInfo>(FunctionScopes[IndexOfCaptureReadyLambda]); // If VarToCapture is null, we are attempting to capture 'this' const bool IsCapturingThis = !VarToCapture; const bool IsCapturingVariable = !IsCapturingThis; if (IsCapturingVariable) { // Check if the capture-ready lambda can truly capture the variable, by // checking whether all enclosing lambdas of the capture-ready lambda allow // the capture - i.e. make sure it is capture-capable. QualType CaptureType, DeclRefType; const bool CanCaptureVariable = !S.tryCaptureVariable(VarToCapture, /*ExprVarIsUsedInLoc*/ SourceLocation(), clang::Sema::TryCapture_Implicit, /*EllipsisLoc*/ SourceLocation(), /*BuildAndDiagnose*/ false, CaptureType, DeclRefType, &IndexOfCaptureReadyLambda); if (!CanCaptureVariable) return NoLambdaIsCaptureCapable; } else { // Check if the capture-ready lambda can truly capture 'this' by checking // whether all enclosing lambdas of the capture-ready lambda can capture // 'this'. const bool CanCaptureThis = !S.CheckCXXThisCapture( CaptureReadyLambdaLSI->PotentialThisCaptureLocation, /*Explicit*/ false, /*BuildAndDiagnose*/ false, &IndexOfCaptureReadyLambda); if (!CanCaptureThis) return NoLambdaIsCaptureCapable; } return IndexOfCaptureReadyLambda; } static inline TemplateParameterList * getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) { if (LSI->GLTemplateParameterList) return LSI->GLTemplateParameterList; if (LSI->AutoTemplateParams.size()) { SourceRange IntroRange = LSI->IntroducerRange; SourceLocation LAngleLoc = IntroRange.getBegin(); SourceLocation RAngleLoc = IntroRange.getEnd(); LSI->GLTemplateParameterList = TemplateParameterList::Create( SemaRef.Context, /*Template kw loc*/ SourceLocation(), LAngleLoc, (NamedDecl **)LSI->AutoTemplateParams.data(), LSI->AutoTemplateParams.size(), RAngleLoc); } return LSI->GLTemplateParameterList; } CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange, TypeSourceInfo *Info, bool KnownDependent, LambdaCaptureDefault CaptureDefault) { DeclContext *DC = CurContext; while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext())) DC = DC->getParent(); bool IsGenericLambda = getGenericLambdaTemplateParameterList(getCurLambda(), *this); // Start constructing the lambda class. CXXRecordDecl *Class = CXXRecordDecl::CreateLambda(Context, DC, Info, IntroducerRange.getBegin(), KnownDependent, IsGenericLambda, CaptureDefault); DC->addDecl(Class); return Class; } /// \brief Determine whether the given context is or is enclosed in an inline /// function. static bool isInInlineFunction(const DeclContext *DC) { while (!DC->isFileContext()) { if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DC)) if (FD->isInlined()) return true; DC = DC->getLexicalParent(); } return false; } MangleNumberingContext * Sema::getCurrentMangleNumberContext(const DeclContext *DC, Decl *&ManglingContextDecl) { // Compute the context for allocating mangling numbers in the current // expression, if the ABI requires them. ManglingContextDecl = ExprEvalContexts.back().ManglingContextDecl; enum ContextKind { Normal, DefaultArgument, DataMember, StaticDataMember } Kind = Normal; // Default arguments of member function parameters that appear in a class // definition, as well as the initializers of data members, receive special // treatment. Identify them. if (ManglingContextDecl) { if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ManglingContextDecl)) { if (const DeclContext *LexicalDC = Param->getDeclContext()->getLexicalParent()) if (LexicalDC->isRecord()) Kind = DefaultArgument; } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) { if (Var->getDeclContext()->isRecord()) Kind = StaticDataMember; } else if (isa<FieldDecl>(ManglingContextDecl)) { Kind = DataMember; } } // Itanium ABI [5.1.7]: // In the following contexts [...] the one-definition rule requires closure // types in different translation units to "correspond": bool IsInNonspecializedTemplate = !ActiveTemplateInstantiations.empty() || CurContext->isDependentContext(); switch (Kind) { case Normal: // -- the bodies of non-exported nonspecialized template functions // -- the bodies of inline functions if ((IsInNonspecializedTemplate && !(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) || isInInlineFunction(CurContext)) { ManglingContextDecl = nullptr; return &Context.getManglingNumberContext(DC); } ManglingContextDecl = nullptr; return nullptr; case StaticDataMember: // -- the initializers of nonspecialized static members of template classes if (!IsInNonspecializedTemplate) { ManglingContextDecl = nullptr; return nullptr; } // Fall through to get the current context. case DataMember: // -- the in-class initializers of class members case DefaultArgument: // -- default arguments appearing in class definitions return &ExprEvalContexts.back().getMangleNumberingContext(Context); } llvm_unreachable("unexpected context"); } MangleNumberingContext & Sema::ExpressionEvaluationContextRecord::getMangleNumberingContext( ASTContext &Ctx) { assert(ManglingContextDecl && "Need to have a context declaration"); if (!MangleNumbering) MangleNumbering = Ctx.createMangleNumberingContext(); return *MangleNumbering; } CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, SourceRange IntroducerRange, TypeSourceInfo *MethodTypeInfo, SourceLocation EndLoc, ArrayRef<ParmVarDecl *> Params) { QualType MethodType = MethodTypeInfo->getType(); TemplateParameterList *TemplateParams = getGenericLambdaTemplateParameterList(getCurLambda(), *this); // If a lambda appears in a dependent context or is a generic lambda (has // template parameters) and has an 'auto' return type, deduce it to a // dependent type. if (Class->isDependentContext() || TemplateParams) { const FunctionProtoType *FPT = MethodType->castAs<FunctionProtoType>(); QualType Result = FPT->getReturnType(); if (Result->isUndeducedType()) { Result = SubstAutoType(Result, Context.DependentTy); MethodType = Context.getFunctionType(Result, FPT->getParamTypes(), FPT->getExtProtoInfo()); } } // C++11 [expr.prim.lambda]p5: // The closure type for a lambda-expression has a public inline function // call operator (13.5.4) whose parameters and return type are described by // the lambda-expression's parameter-declaration-clause and // trailing-return-type respectively. DeclarationName MethodName = Context.DeclarationNames.getCXXOperatorName(OO_Call); DeclarationNameLoc MethodNameLoc; MethodNameLoc.CXXOperatorName.BeginOpNameLoc = IntroducerRange.getBegin().getRawEncoding(); MethodNameLoc.CXXOperatorName.EndOpNameLoc = IntroducerRange.getEnd().getRawEncoding(); CXXMethodDecl *Method = CXXMethodDecl::Create(Context, Class, EndLoc, DeclarationNameInfo(MethodName, IntroducerRange.getBegin(), MethodNameLoc), MethodType, MethodTypeInfo, SC_None, /*isInline=*/true, /*isConstExpr=*/false, EndLoc); Method->setAccess(AS_public); // Temporarily set the lexical declaration context to the current // context, so that the Scope stack matches the lexical nesting. Method->setLexicalDeclContext(CurContext); // Create a function template if we have a template parameter list FunctionTemplateDecl *const TemplateMethod = TemplateParams ? FunctionTemplateDecl::Create(Context, Class, Method->getLocation(), MethodName, TemplateParams, Method) : nullptr; if (TemplateMethod) { TemplateMethod->setLexicalDeclContext(CurContext); TemplateMethod->setAccess(AS_public); Method->setDescribedFunctionTemplate(TemplateMethod); } // Add parameters. if (!Params.empty()) { Method->setParams(Params); CheckParmsForFunctionDef(const_cast<ParmVarDecl **>(Params.begin()), const_cast<ParmVarDecl **>(Params.end()), /*CheckParameterNames=*/false); for (auto P : Method->params()) P->setOwningFunction(Method); } Decl *ManglingContextDecl; if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext(Class->getDeclContext(), ManglingContextDecl)) { unsigned ManglingNumber = MCtx->getManglingNumber(Method); Class->setLambdaMangling(ManglingNumber, ManglingContextDecl); } return Method; } void Sema::buildLambdaScope(LambdaScopeInfo *LSI, CXXMethodDecl *CallOperator, SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc, bool ExplicitParams, bool ExplicitResultType, bool Mutable) { LSI->CallOperator = CallOperator; CXXRecordDecl *LambdaClass = CallOperator->getParent(); LSI->Lambda = LambdaClass; if (CaptureDefault == LCD_ByCopy) LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval; else if (CaptureDefault == LCD_ByRef) LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByref; LSI->CaptureDefaultLoc = CaptureDefaultLoc; LSI->IntroducerRange = IntroducerRange; LSI->ExplicitParams = ExplicitParams; LSI->Mutable = Mutable; if (ExplicitResultType) { LSI->ReturnType = CallOperator->getReturnType(); if (!LSI->ReturnType->isDependentType() && !LSI->ReturnType->isVoidType()) { if (RequireCompleteType(CallOperator->getLocStart(), LSI->ReturnType, diag::err_lambda_incomplete_result)) { // Do nothing. } } } else { LSI->HasImplicitReturnType = true; } } void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) { LSI->finishedExplicitCaptures(); } void Sema::addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope) { // Introduce our parameters into the function scope for (unsigned p = 0, NumParams = CallOperator->getNumParams(); p < NumParams; ++p) { ParmVarDecl *Param = CallOperator->getParamDecl(p); // If this has an identifier, add it to the scope stack. if (CurScope && Param->getIdentifier()) { CheckShadow(CurScope, Param); PushOnScopeChains(Param, CurScope); } } } /// If this expression is an enumerator-like expression of some type /// T, return the type T; otherwise, return null. /// /// Pointer comparisons on the result here should always work because /// it's derived from either the parent of an EnumConstantDecl /// (i.e. the definition) or the declaration returned by /// EnumType::getDecl() (i.e. the definition). static EnumDecl *findEnumForBlockReturn(Expr *E) { // An expression is an enumerator-like expression of type T if, // ignoring parens and parens-like expressions: E = E->IgnoreParens(); // - it is an enumerator whose enum type is T or if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { if (EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(DRE->getDecl())) { return cast<EnumDecl>(D->getDeclContext()); } return nullptr; } // - it is a comma expression whose RHS is an enumerator-like // expression of type T or if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { if (BO->getOpcode() == BO_Comma) return findEnumForBlockReturn(BO->getRHS()); return nullptr; } // - it is a statement-expression whose value expression is an // enumerator-like expression of type T or if (StmtExpr *SE = dyn_cast<StmtExpr>(E)) { if (Expr *last = dyn_cast_or_null<Expr>(SE->getSubStmt()->body_back())) return findEnumForBlockReturn(last); return nullptr; } // - it is a ternary conditional operator (not the GNU ?: // extension) whose second and third operands are // enumerator-like expressions of type T or if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { if (EnumDecl *ED = findEnumForBlockReturn(CO->getTrueExpr())) if (ED == findEnumForBlockReturn(CO->getFalseExpr())) return ED; return nullptr; } // (implicitly:) // - it is an implicit integral conversion applied to an // enumerator-like expression of type T or if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) { // We can sometimes see integral conversions in valid // enumerator-like expressions. if (ICE->getCastKind() == CK_IntegralCast) return findEnumForBlockReturn(ICE->getSubExpr()); // Otherwise, just rely on the type. } // - it is an expression of that formal enum type. if (const EnumType *ET = E->getType()->getAs<EnumType>()) { return ET->getDecl(); } // Otherwise, nope. return nullptr; } /// Attempt to find a type T for which the returned expression of the /// given statement is an enumerator-like expression of that type. static EnumDecl *findEnumForBlockReturn(ReturnStmt *ret) { if (Expr *retValue = ret->getRetValue()) return findEnumForBlockReturn(retValue); return nullptr; } /// Attempt to find a common type T for which all of the returned /// expressions in a block are enumerator-like expressions of that /// type. static EnumDecl *findCommonEnumForBlockReturns(ArrayRef<ReturnStmt*> returns) { ArrayRef<ReturnStmt*>::iterator i = returns.begin(), e = returns.end(); // Try to find one for the first return. EnumDecl *ED = findEnumForBlockReturn(*i); if (!ED) return nullptr; // Check that the rest of the returns have the same enum. for (++i; i != e; ++i) { if (findEnumForBlockReturn(*i) != ED) return nullptr; } // Never infer an anonymous enum type. if (!ED->hasNameForLinkage()) return nullptr; return ED; } /// Adjust the given return statements so that they formally return /// the given type. It should require, at most, an IntegralCast. static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt*> returns, QualType returnType) { for (ArrayRef<ReturnStmt*>::iterator i = returns.begin(), e = returns.end(); i != e; ++i) { ReturnStmt *ret = *i; Expr *retValue = ret->getRetValue(); if (S.Context.hasSameType(retValue->getType(), returnType)) continue; // Right now we only support integral fixup casts. assert(returnType->isIntegralOrUnscopedEnumerationType()); assert(retValue->getType()->isIntegralOrUnscopedEnumerationType()); ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(retValue); Expr *E = (cleanups ? cleanups->getSubExpr() : retValue); E = ImplicitCastExpr::Create(S.Context, returnType, CK_IntegralCast, E, /*base path*/ nullptr, VK_RValue); if (cleanups) { cleanups->setSubExpr(E); } else { ret->setRetValue(E); } } } void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) { assert(CSI.HasImplicitReturnType); // If it was ever a placeholder, it had to been deduced to DependentTy. assert(CSI.ReturnType.isNull() || !CSI.ReturnType->isUndeducedType()); // C++ core issue 975: // If a lambda-expression does not include a trailing-return-type, // it is as if the trailing-return-type denotes the following type: // - if there are no return statements in the compound-statement, // or all return statements return either an expression of type // void or no expression or braced-init-list, the type void; // - otherwise, if all return statements return an expression // and the types of the returned expressions after // lvalue-to-rvalue conversion (4.1 [conv.lval]), // array-to-pointer conversion (4.2 [conv.array]), and // function-to-pointer conversion (4.3 [conv.func]) are the // same, that common type; // - otherwise, the program is ill-formed. // // C++ core issue 1048 additionally removes top-level cv-qualifiers // from the types of returned expressions to match the C++14 auto // deduction rules. // // In addition, in blocks in non-C++ modes, if all of the return // statements are enumerator-like expressions of some type T, where // T has a name for linkage, then we infer the return type of the // block to be that type. // First case: no return statements, implicit void return type. ASTContext &Ctx = getASTContext(); if (CSI.Returns.empty()) { // It's possible there were simply no /valid/ return statements. // In this case, the first one we found may have at least given us a type. if (CSI.ReturnType.isNull()) CSI.ReturnType = Ctx.VoidTy; return; } // Second case: at least one return statement has dependent type. // Delay type checking until instantiation. assert(!CSI.ReturnType.isNull() && "We should have a tentative return type."); if (CSI.ReturnType->isDependentType()) return; // Try to apply the enum-fuzz rule. if (!getLangOpts().CPlusPlus) { assert(isa<BlockScopeInfo>(CSI)); const EnumDecl *ED = findCommonEnumForBlockReturns(CSI.Returns); if (ED) { CSI.ReturnType = Context.getTypeDeclType(ED); adjustBlockReturnsToEnum(*this, CSI.Returns, CSI.ReturnType); return; } } // Third case: only one return statement. Don't bother doing extra work! SmallVectorImpl<ReturnStmt*>::iterator I = CSI.Returns.begin(), E = CSI.Returns.end(); if (I+1 == E) return; // General case: many return statements. // Check that they all have compatible return types. // We require the return types to strictly match here. // Note that we've already done the required promotions as part of // processing the return statement. for (; I != E; ++I) { const ReturnStmt *RS = *I; const Expr *RetE = RS->getRetValue(); QualType ReturnType = (RetE ? RetE->getType() : Context.VoidTy).getUnqualifiedType(); if (Context.getCanonicalFunctionResultType(ReturnType) == Context.getCanonicalFunctionResultType(CSI.ReturnType)) continue; // FIXME: This is a poor diagnostic for ReturnStmts without expressions. // TODO: It's possible that the *first* return is the divergent one. Diag(RS->getLocStart(), diag::err_typecheck_missing_return_type_incompatible) << ReturnType << CSI.ReturnType << isa<LambdaScopeInfo>(CSI); // Continue iterating so that we keep emitting diagnostics. } } QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc, bool ByRef, IdentifierInfo *Id, bool IsDirectInit, Expr *&Init) { // Create an 'auto' or 'auto&' TypeSourceInfo that we can use to // deduce against. QualType DeductType = Context.getAutoDeductType(); TypeLocBuilder TLB; TLB.pushTypeSpec(DeductType).setNameLoc(Loc); if (ByRef) { DeductType = BuildReferenceType(DeductType, true, Loc, Id); assert(!DeductType.isNull() && "can't build reference to auto"); TLB.push<ReferenceTypeLoc>(DeductType).setSigilLoc(Loc); } TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType); // Deduce the type of the init capture. QualType DeducedType = deduceVarTypeFromInitializer( /*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI, SourceRange(Loc, Loc), IsDirectInit, Init); if (DeducedType.isNull()) return QualType(); // Are we a non-list direct initialization? ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init); // Perform initialization analysis and ensure any implicit conversions // (such as lvalue-to-rvalue) are enforced. InitializedEntity Entity = InitializedEntity::InitializeLambdaCapture(Id, DeducedType, Loc); InitializationKind Kind = IsDirectInit ? (CXXDirectInit ? InitializationKind::CreateDirect( Loc, Init->getLocStart(), Init->getLocEnd()) : InitializationKind::CreateDirectList(Loc)) : InitializationKind::CreateCopy(Loc, Init->getLocStart()); MultiExprArg Args = Init; if (CXXDirectInit) Args = MultiExprArg(CXXDirectInit->getExprs(), CXXDirectInit->getNumExprs()); QualType DclT; InitializationSequence InitSeq(*this, Entity, Kind, Args); ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT); if (Result.isInvalid()) return QualType(); Init = Result.getAs<Expr>(); // The init-capture initialization is a full-expression that must be // processed as one before we enter the declcontext of the lambda's // call-operator. Result = ActOnFinishFullExpr(Init, Loc, /*DiscardedValue*/ false, /*IsConstexpr*/ false, /*IsLambdaInitCaptureInitalizer*/ true); if (Result.isInvalid()) return QualType(); Init = Result.getAs<Expr>(); return DeducedType; } VarDecl *Sema::createLambdaInitCaptureVarDecl(SourceLocation Loc, QualType InitCaptureType, IdentifierInfo *Id, unsigned InitStyle, Expr *Init) { TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo(InitCaptureType, Loc); // Create a dummy variable representing the init-capture. This is not actually // used as a variable, and only exists as a way to name and refer to the // init-capture. // FIXME: Pass in separate source locations for '&' and identifier. VarDecl *NewVD = VarDecl::Create(Context, CurContext, Loc, Loc, Id, InitCaptureType, TSI, SC_Auto); NewVD->setInitCapture(true); NewVD->setReferenced(true); // FIXME: Pass in a VarDecl::InitializationStyle. NewVD->setInitStyle(static_cast<VarDecl::InitializationStyle>(InitStyle)); NewVD->markUsed(Context); NewVD->setInit(Init); return NewVD; } FieldDecl *Sema::buildInitCaptureField(LambdaScopeInfo *LSI, VarDecl *Var) { FieldDecl *Field = FieldDecl::Create( Context, LSI->Lambda, Var->getLocation(), Var->getLocation(), nullptr, Var->getType(), Var->getTypeSourceInfo(), nullptr, false, ICIS_NoInit); Field->setImplicit(true); Field->setAccess(AS_private); LSI->Lambda->addDecl(Field); LSI->addCapture(Var, /*isBlock*/false, Var->getType()->isReferenceType(), /*isNested*/false, Var->getLocation(), SourceLocation(), Var->getType(), Var->getInit()); return Field; } void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, Declarator &ParamInfo, Scope *CurScope) { // Determine if we're within a context where we know that the lambda will // be dependent, because there are template parameters in scope. bool KnownDependent = false; LambdaScopeInfo *const LSI = getCurLambda(); assert(LSI && "LambdaScopeInfo should be on stack!"); TemplateParameterList *TemplateParams = getGenericLambdaTemplateParameterList(LSI, *this); if (Scope *TmplScope = CurScope->getTemplateParamParent()) { // Since we have our own TemplateParams, so check if an outer scope // has template params, only then are we in a dependent scope. if (TemplateParams) { TmplScope = TmplScope->getParent(); TmplScope = TmplScope ? TmplScope->getTemplateParamParent() : nullptr; } if (TmplScope && !TmplScope->decl_empty()) KnownDependent = true; } // Determine the signature of the call operator. TypeSourceInfo *MethodTyInfo; bool ExplicitParams = true; bool ExplicitResultType = true; bool ContainsUnexpandedParameterPack = false; SourceLocation EndLoc; SmallVector<ParmVarDecl *, 8> Params; if (ParamInfo.getNumTypeObjects() == 0) { // C++11 [expr.prim.lambda]p4: // If a lambda-expression does not include a lambda-declarator, it is as // if the lambda-declarator were (). FunctionProtoType::ExtProtoInfo EPI(Context.getDefaultCallingConvention( /*IsVariadic=*/false, /*IsCXXMethod=*/true)); EPI.HasTrailingReturn = true; EPI.TypeQuals |= DeclSpec::TQ_const; // C++1y [expr.prim.lambda]: // The lambda return type is 'auto', which is replaced by the // trailing-return type if provided and/or deduced from 'return' // statements // We don't do this before C++1y, because we don't support deduced return // types there. QualType DefaultTypeForNoTrailingReturn = getLangOpts().CPlusPlus14 ? Context.getAutoDeductType() : Context.DependentTy; QualType MethodTy = Context.getFunctionType(DefaultTypeForNoTrailingReturn, None, EPI); MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy); ExplicitParams = false; ExplicitResultType = false; EndLoc = Intro.Range.getEnd(); } else { assert(ParamInfo.isFunctionDeclarator() && "lambda-declarator is a function"); DeclaratorChunk::FunctionTypeInfo &FTI = ParamInfo.getFunctionTypeInfo(); // C++11 [expr.prim.lambda]p5: // This function call operator is declared const (9.3.1) if and only if // the lambda-expression's parameter-declaration-clause is not followed // by mutable. It is neither virtual nor declared volatile. [...] if (!FTI.hasMutableQualifier()) FTI.TypeQuals |= DeclSpec::TQ_const; MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope); assert(MethodTyInfo && "no type from lambda-declarator"); EndLoc = ParamInfo.getSourceRange().getEnd(); ExplicitResultType = FTI.hasTrailingReturnType(); if (FTIHasNonVoidParameters(FTI)) { Params.reserve(FTI.NumParams); for (unsigned i = 0, e = FTI.NumParams; i != e; ++i) Params.push_back(cast<ParmVarDecl>(FTI.Params[i].Param)); } // Check for unexpanded parameter packs in the method type. if (MethodTyInfo->getType()->containsUnexpandedParameterPack()) ContainsUnexpandedParameterPack = true; } CXXRecordDecl *Class = createLambdaClosureType(Intro.Range, MethodTyInfo, KnownDependent, Intro.Default); CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range, MethodTyInfo, EndLoc, Params); if (ExplicitParams) CheckCXXDefaultArguments(Method); // Attributes on the lambda apply to the method. ProcessDeclAttributes(CurScope, Method, ParamInfo); // Introduce the function call operator as the current declaration context. PushDeclContext(CurScope, Method); // Build the lambda scope. buildLambdaScope(LSI, Method, Intro.Range, Intro.Default, Intro.DefaultLoc, ExplicitParams, ExplicitResultType, !Method->isConst()); // C++11 [expr.prim.lambda]p9: // A lambda-expression whose smallest enclosing scope is a block scope is a // local lambda expression; any other lambda expression shall not have a // capture-default or simple-capture in its lambda-introducer. // // For simple-captures, this is covered by the check below that any named // entity is a variable that can be captured. // // For DR1632, we also allow a capture-default in any context where we can // odr-use 'this' (in particular, in a default initializer for a non-static // data member). if (Intro.Default != LCD_None && !Class->getParent()->isFunctionOrMethod() && (getCurrentThisType().isNull() || CheckCXXThisCapture(SourceLocation(), /*Explicit*/true, /*BuildAndDiagnose*/false))) Diag(Intro.DefaultLoc, diag::err_capture_default_non_local); // Distinct capture names, for diagnostics. llvm::SmallSet<IdentifierInfo*, 8> CaptureNames; // Handle explicit captures. SourceLocation PrevCaptureLoc = Intro.Default == LCD_None? Intro.Range.getBegin() : Intro.DefaultLoc; for (auto C = Intro.Captures.begin(), E = Intro.Captures.end(); C != E; PrevCaptureLoc = C->Loc, ++C) { if (C->Kind == LCK_This) { // C++11 [expr.prim.lambda]p8: // An identifier or this shall not appear more than once in a // lambda-capture. if (LSI->isCXXThisCaptured()) { Diag(C->Loc, diag::err_capture_more_than_once) << "'this'" << SourceRange(LSI->getCXXThisCapture().getLocation()) << FixItHint::CreateRemoval( SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); continue; } // C++11 [expr.prim.lambda]p8: // If a lambda-capture includes a capture-default that is =, the // lambda-capture shall not contain this [...]. if (Intro.Default == LCD_ByCopy) { Diag(C->Loc, diag::err_this_capture_with_copy_default) << FixItHint::CreateRemoval( SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); continue; } // C++11 [expr.prim.lambda]p12: // If this is captured by a local lambda expression, its nearest // enclosing function shall be a non-static member function. QualType ThisCaptureType = getCurrentThisType(); if (ThisCaptureType.isNull()) { Diag(C->Loc, diag::err_this_capture) << true; continue; } CheckCXXThisCapture(C->Loc, /*Explicit=*/true); continue; } assert(C->Id && "missing identifier for capture"); if (C->Init.isInvalid()) continue; VarDecl *Var = nullptr; if (C->Init.isUsable()) { Diag(C->Loc, getLangOpts().CPlusPlus14 ? diag::warn_cxx11_compat_init_capture : diag::ext_init_capture); if (C->Init.get()->containsUnexpandedParameterPack()) ContainsUnexpandedParameterPack = true; // If the initializer expression is usable, but the InitCaptureType // is not, then an error has occurred - so ignore the capture for now. // for e.g., [n{0}] { }; <-- if no <initializer_list> is included. // FIXME: we should create the init capture variable and mark it invalid // in this case. if (C->InitCaptureType.get().isNull()) continue; unsigned InitStyle; switch (C->InitKind) { case LambdaCaptureInitKind::NoInit: llvm_unreachable("not an init-capture?"); case LambdaCaptureInitKind::CopyInit: InitStyle = VarDecl::CInit; break; case LambdaCaptureInitKind::DirectInit: InitStyle = VarDecl::CallInit; break; case LambdaCaptureInitKind::ListInit: InitStyle = VarDecl::ListInit; break; } Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(), C->Id, InitStyle, C->Init.get()); // C++1y [expr.prim.lambda]p11: // An init-capture behaves as if it declares and explicitly // captures a variable [...] whose declarative region is the // lambda-expression's compound-statement if (Var) PushOnScopeChains(Var, CurScope, false); } else { assert(C->InitKind == LambdaCaptureInitKind::NoInit && "init capture has valid but null init?"); // C++11 [expr.prim.lambda]p8: // If a lambda-capture includes a capture-default that is &, the // identifiers in the lambda-capture shall not be preceded by &. // If a lambda-capture includes a capture-default that is =, [...] // each identifier it contains shall be preceded by &. if (C->Kind == LCK_ByRef && Intro.Default == LCD_ByRef) { Diag(C->Loc, diag::err_reference_capture_with_reference_default) << FixItHint::CreateRemoval( SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); continue; } else if (C->Kind == LCK_ByCopy && Intro.Default == LCD_ByCopy) { Diag(C->Loc, diag::err_copy_capture_with_copy_default) << FixItHint::CreateRemoval( SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); continue; } // C++11 [expr.prim.lambda]p10: // The identifiers in a capture-list are looked up using the usual // rules for unqualified name lookup (3.4.1) DeclarationNameInfo Name(C->Id, C->Loc); LookupResult R(*this, Name, LookupOrdinaryName); LookupName(R, CurScope); if (R.isAmbiguous()) continue; if (R.empty()) { // FIXME: Disable corrections that would add qualification? CXXScopeSpec ScopeSpec; if (DiagnoseEmptyLookup(CurScope, ScopeSpec, R, llvm::make_unique<DeclFilterCCC<VarDecl>>())) continue; } Var = R.getAsSingle<VarDecl>(); if (Var && DiagnoseUseOfDecl(Var, C->Loc)) continue; } // C++11 [expr.prim.lambda]p8: // An identifier or this shall not appear more than once in a // lambda-capture. if (!CaptureNames.insert(C->Id).second) { if (Var && LSI->isCaptured(Var)) { Diag(C->Loc, diag::err_capture_more_than_once) << C->Id << SourceRange(LSI->getCapture(Var).getLocation()) << FixItHint::CreateRemoval( SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); } else // Previous capture captured something different (one or both was // an init-cpature): no fixit. Diag(C->Loc, diag::err_capture_more_than_once) << C->Id; continue; } // C++11 [expr.prim.lambda]p10: // [...] each such lookup shall find a variable with automatic storage // duration declared in the reaching scope of the local lambda expression. // Note that the 'reaching scope' check happens in tryCaptureVariable(). if (!Var) { Diag(C->Loc, diag::err_capture_does_not_name_variable) << C->Id; continue; } // Ignore invalid decls; they'll just confuse the code later. if (Var->isInvalidDecl()) continue; if (!Var->hasLocalStorage()) { Diag(C->Loc, diag::err_capture_non_automatic_variable) << C->Id; Diag(Var->getLocation(), diag::note_previous_decl) << C->Id; continue; } // C++11 [expr.prim.lambda]p23: // A capture followed by an ellipsis is a pack expansion (14.5.3). SourceLocation EllipsisLoc; if (C->EllipsisLoc.isValid()) { if (Var->isParameterPack()) { EllipsisLoc = C->EllipsisLoc; } else { Diag(C->EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) << SourceRange(C->Loc); // Just ignore the ellipsis. } } else if (Var->isParameterPack()) { ContainsUnexpandedParameterPack = true; } if (C->Init.isUsable()) { buildInitCaptureField(LSI, Var); } else { TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef : TryCapture_ExplicitByVal; tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc); } } finishLambdaExplicitCaptures(LSI); LSI->ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; // Add lambda parameters into scope. addLambdaParameters(Method, CurScope); // Enter a new evaluation context to insulate the lambda from any // cleanups from the enclosing full-expression. PushExpressionEvaluationContext(PotentiallyEvaluated); } void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, bool IsInstantiation) { LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(FunctionScopes.back()); // Leave the expression-evaluation context. DiscardCleanupsInEvaluationContext(); PopExpressionEvaluationContext(); // Leave the context of the lambda. if (!IsInstantiation) PopDeclContext(); // Finalize the lambda. CXXRecordDecl *Class = LSI->Lambda; Class->setInvalidDecl(); SmallVector<Decl*, 4> Fields(Class->fields()); ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(), SourceLocation(), nullptr); CheckCompletedCXXClass(Class); PopFunctionScopeInfo(); } /// \brief Add a lambda's conversion to function pointer, as described in /// C++11 [expr.prim.lambda]p6. static void addFunctionPointerConversion(Sema &S, SourceRange IntroducerRange, CXXRecordDecl *Class, CXXMethodDecl *CallOperator) { // This conversion is explicitly disabled if the lambda's function has // pass_object_size attributes on any of its parameters. if (std::any_of(CallOperator->param_begin(), CallOperator->param_end(), std::mem_fn(&ParmVarDecl::hasAttr<PassObjectSizeAttr>))) return; // Add the conversion to function pointer. const FunctionProtoType *CallOpProto = CallOperator->getType()->getAs<FunctionProtoType>(); const FunctionProtoType::ExtProtoInfo CallOpExtInfo = CallOpProto->getExtProtoInfo(); QualType PtrToFunctionTy; QualType InvokerFunctionTy; { FunctionProtoType::ExtProtoInfo InvokerExtInfo = CallOpExtInfo; CallingConv CC = S.Context.getDefaultCallingConvention( CallOpProto->isVariadic(), /*IsCXXMethod=*/false); InvokerExtInfo.ExtInfo = InvokerExtInfo.ExtInfo.withCallingConv(CC); InvokerExtInfo.TypeQuals = 0; assert(InvokerExtInfo.RefQualifier == RQ_None && "Lambda's call operator should not have a reference qualifier"); InvokerFunctionTy = S.Context.getFunctionType(CallOpProto->getReturnType(), CallOpProto->getParamTypes(), InvokerExtInfo); PtrToFunctionTy = S.Context.getPointerType(InvokerFunctionTy); } // Create the type of the conversion function. FunctionProtoType::ExtProtoInfo ConvExtInfo( S.Context.getDefaultCallingConvention( /*IsVariadic=*/false, /*IsCXXMethod=*/true)); // The conversion function is always const. ConvExtInfo.TypeQuals = Qualifiers::Const; QualType ConvTy = S.Context.getFunctionType(PtrToFunctionTy, None, ConvExtInfo); SourceLocation Loc = IntroducerRange.getBegin(); DeclarationName ConversionName = S.Context.DeclarationNames.getCXXConversionFunctionName( S.Context.getCanonicalType(PtrToFunctionTy)); DeclarationNameLoc ConvNameLoc; // Construct a TypeSourceInfo for the conversion function, and wire // all the parameters appropriately for the FunctionProtoTypeLoc // so that everything works during transformation/instantiation of // generic lambdas. // The main reason for wiring up the parameters of the conversion // function with that of the call operator is so that constructs // like the following work: // auto L = [](auto b) { <-- 1 // return [](auto a) -> decltype(a) { <-- 2 // return a; // }; // }; // int (*fp)(int) = L(5); // Because the trailing return type can contain DeclRefExprs that refer // to the original call operator's variables, we hijack the call // operators ParmVarDecls below. TypeSourceInfo *ConvNamePtrToFunctionTSI = S.Context.getTrivialTypeSourceInfo(PtrToFunctionTy, Loc); ConvNameLoc.NamedType.TInfo = ConvNamePtrToFunctionTSI; // The conversion function is a conversion to a pointer-to-function. TypeSourceInfo *ConvTSI = S.Context.getTrivialTypeSourceInfo(ConvTy, Loc); FunctionProtoTypeLoc ConvTL = ConvTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>(); // Get the result of the conversion function which is a pointer-to-function. PointerTypeLoc PtrToFunctionTL = ConvTL.getReturnLoc().getAs<PointerTypeLoc>(); // Do the same for the TypeSourceInfo that is used to name the conversion // operator. PointerTypeLoc ConvNamePtrToFunctionTL = ConvNamePtrToFunctionTSI->getTypeLoc().getAs<PointerTypeLoc>(); // Get the underlying function types that the conversion function will // be converting to (should match the type of the call operator). FunctionProtoTypeLoc CallOpConvTL = PtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>(); FunctionProtoTypeLoc CallOpConvNameTL = ConvNamePtrToFunctionTL.getPointeeLoc().getAs<FunctionProtoTypeLoc>(); // Wire up the FunctionProtoTypeLocs with the call operator's parameters. // These parameter's are essentially used to transform the name and // the type of the conversion operator. By using the same parameters // as the call operator's we don't have to fix any back references that // the trailing return type of the call operator's uses (such as // decltype(some_type<decltype(a)>::type{} + decltype(a){}) etc.) // - we can simply use the return type of the call operator, and // everything should work. SmallVector<ParmVarDecl *, 4> InvokerParams; for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) { ParmVarDecl *From = CallOperator->getParamDecl(I); InvokerParams.push_back(ParmVarDecl::Create(S.Context, // Temporarily add to the TU. This is set to the invoker below. S.Context.getTranslationUnitDecl(), From->getLocStart(), From->getLocation(), From->getIdentifier(), From->getType(), From->getTypeSourceInfo(), From->getStorageClass(), /*DefaultArg=*/nullptr)); CallOpConvTL.setParam(I, From); CallOpConvNameTL.setParam(I, From); } CXXConversionDecl *Conversion = CXXConversionDecl::Create(S.Context, Class, Loc, DeclarationNameInfo(ConversionName, Loc, ConvNameLoc), ConvTy, ConvTSI, /*isInline=*/true, /*isExplicit=*/false, /*isConstexpr=*/false, CallOperator->getBody()->getLocEnd()); Conversion->setAccess(AS_public); Conversion->setImplicit(true); if (Class->isGenericLambda()) { // Create a template version of the conversion operator, using the template // parameter list of the function call operator. FunctionTemplateDecl *TemplateCallOperator = CallOperator->getDescribedFunctionTemplate(); FunctionTemplateDecl *ConversionTemplate = FunctionTemplateDecl::Create(S.Context, Class, Loc, ConversionName, TemplateCallOperator->getTemplateParameters(), Conversion); ConversionTemplate->setAccess(AS_public); ConversionTemplate->setImplicit(true); Conversion->setDescribedFunctionTemplate(ConversionTemplate); Class->addDecl(ConversionTemplate); } else Class->addDecl(Conversion); // Add a non-static member function that will be the result of // the conversion with a certain unique ID. DeclarationName InvokerName = &S.Context.Idents.get( getLambdaStaticInvokerName()); // FIXME: Instead of passing in the CallOperator->getTypeSourceInfo() // we should get a prebuilt TrivialTypeSourceInfo from Context // using FunctionTy & Loc and get its TypeLoc as a FunctionProtoTypeLoc // then rewire the parameters accordingly, by hoisting up the InvokeParams // loop below and then use its Params to set Invoke->setParams(...) below. // This would avoid the 'const' qualifier of the calloperator from // contaminating the type of the invoker, which is currently adjusted // in SemaTemplateDeduction.cpp:DeduceTemplateArguments. Fixing the // trailing return type of the invoker would require a visitor to rebuild // the trailing return type and adjusting all back DeclRefExpr's to refer // to the new static invoker parameters - not the call operator's. CXXMethodDecl *Invoke = CXXMethodDecl::Create(S.Context, Class, Loc, DeclarationNameInfo(InvokerName, Loc), InvokerFunctionTy, CallOperator->getTypeSourceInfo(), SC_Static, /*IsInline=*/true, /*IsConstexpr=*/false, CallOperator->getBody()->getLocEnd()); for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) InvokerParams[I]->setOwningFunction(Invoke); Invoke->setParams(InvokerParams); Invoke->setAccess(AS_private); Invoke->setImplicit(true); if (Class->isGenericLambda()) { FunctionTemplateDecl *TemplateCallOperator = CallOperator->getDescribedFunctionTemplate(); FunctionTemplateDecl *StaticInvokerTemplate = FunctionTemplateDecl::Create( S.Context, Class, Loc, InvokerName, TemplateCallOperator->getTemplateParameters(), Invoke); StaticInvokerTemplate->setAccess(AS_private); StaticInvokerTemplate->setImplicit(true); Invoke->setDescribedFunctionTemplate(StaticInvokerTemplate); Class->addDecl(StaticInvokerTemplate); } else Class->addDecl(Invoke); } /// \brief Add a lambda's conversion to block pointer. static void addBlockPointerConversion(Sema &S, SourceRange IntroducerRange, CXXRecordDecl *Class, CXXMethodDecl *CallOperator) { const FunctionProtoType *Proto = CallOperator->getType()->getAs<FunctionProtoType>(); // The function type inside the block pointer type is the same as the call // operator with some tweaks. The calling convention is the default free // function convention, and the type qualifications are lost. FunctionProtoType::ExtProtoInfo BlockEPI = Proto->getExtProtoInfo(); BlockEPI.ExtInfo = BlockEPI.ExtInfo.withCallingConv(S.Context.getDefaultCallingConvention( Proto->isVariadic(), /*IsCXXMethod=*/false)); BlockEPI.TypeQuals = 0; QualType FunctionTy = S.Context.getFunctionType( Proto->getReturnType(), Proto->getParamTypes(), BlockEPI); QualType BlockPtrTy = S.Context.getBlockPointerType(FunctionTy); FunctionProtoType::ExtProtoInfo ConversionEPI( S.Context.getDefaultCallingConvention( /*IsVariadic=*/false, /*IsCXXMethod=*/true)); ConversionEPI.TypeQuals = Qualifiers::Const; QualType ConvTy = S.Context.getFunctionType(BlockPtrTy, None, ConversionEPI); SourceLocation Loc = IntroducerRange.getBegin(); DeclarationName Name = S.Context.DeclarationNames.getCXXConversionFunctionName( S.Context.getCanonicalType(BlockPtrTy)); DeclarationNameLoc NameLoc; NameLoc.NamedType.TInfo = S.Context.getTrivialTypeSourceInfo(BlockPtrTy, Loc); CXXConversionDecl *Conversion = CXXConversionDecl::Create(S.Context, Class, Loc, DeclarationNameInfo(Name, Loc, NameLoc), ConvTy, S.Context.getTrivialTypeSourceInfo(ConvTy, Loc), /*isInline=*/true, /*isExplicit=*/false, /*isConstexpr=*/false, CallOperator->getBody()->getLocEnd()); Conversion->setAccess(AS_public); Conversion->setImplicit(true); Class->addDecl(Conversion); } static ExprResult performLambdaVarCaptureInitialization( Sema &S, LambdaScopeInfo::Capture &Capture, FieldDecl *Field, SmallVectorImpl<VarDecl *> &ArrayIndexVars, SmallVectorImpl<unsigned> &ArrayIndexStarts) { assert(Capture.isVariableCapture() && "not a variable capture"); auto *Var = Capture.getVariable(); SourceLocation Loc = Capture.getLocation(); // C++11 [expr.prim.lambda]p21: // When the lambda-expression is evaluated, the entities that // are captured by copy are used to direct-initialize each // corresponding non-static data member of the resulting closure // object. (For array members, the array elements are // direct-initialized in increasing subscript order.) These // initializations are performed in the (unspecified) order in // which the non-static data members are declared. // C++ [expr.prim.lambda]p12: // An entity captured by a lambda-expression is odr-used (3.2) in // the scope containing the lambda-expression. ExprResult RefResult = S.BuildDeclarationNameExpr( CXXScopeSpec(), DeclarationNameInfo(Var->getDeclName(), Loc), Var); if (RefResult.isInvalid()) return ExprError(); Expr *Ref = RefResult.get(); QualType FieldType = Field->getType(); // When the variable has array type, create index variables for each // dimension of the array. We use these index variables to subscript // the source array, and other clients (e.g., CodeGen) will perform // the necessary iteration with these index variables. // // FIXME: This is dumb. Add a proper AST representation for array // copy-construction and use it here. SmallVector<VarDecl *, 4> IndexVariables; QualType BaseType = FieldType; QualType SizeType = S.Context.getSizeType(); ArrayIndexStarts.push_back(ArrayIndexVars.size()); while (const ConstantArrayType *Array = S.Context.getAsConstantArrayType(BaseType)) { // Create the iteration variable for this array index. IdentifierInfo *IterationVarName = nullptr; { SmallString<8> Str; llvm::raw_svector_ostream OS(Str); OS << "__i" << IndexVariables.size(); IterationVarName = &S.Context.Idents.get(OS.str()); } VarDecl *IterationVar = VarDecl::Create( S.Context, S.CurContext, Loc, Loc, IterationVarName, SizeType, S.Context.getTrivialTypeSourceInfo(SizeType, Loc), SC_None); IterationVar->setImplicit(); IndexVariables.push_back(IterationVar); ArrayIndexVars.push_back(IterationVar); // Create a reference to the iteration variable. ExprResult IterationVarRef = S.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc); assert(!IterationVarRef.isInvalid() && "Reference to invented variable cannot fail!"); IterationVarRef = S.DefaultLvalueConversion(IterationVarRef.get()); assert(!IterationVarRef.isInvalid() && "Conversion of invented variable cannot fail!"); // Subscript the array with this iteration variable. ExprResult Subscript = S.CreateBuiltinArraySubscriptExpr(Ref, Loc, IterationVarRef.get(), Loc); if (Subscript.isInvalid()) return ExprError(); Ref = Subscript.get(); BaseType = Array->getElementType(); } // Construct the entity that we will be initializing. For an array, this // will be first element in the array, which may require several levels // of array-subscript entities. SmallVector<InitializedEntity, 4> Entities; Entities.reserve(1 + IndexVariables.size()); Entities.push_back(InitializedEntity::InitializeLambdaCapture( Var->getIdentifier(), FieldType, Loc)); for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I) Entities.push_back( InitializedEntity::InitializeElement(S.Context, 0, Entities.back())); InitializationKind InitKind = InitializationKind::CreateDirect(Loc, Loc, Loc); InitializationSequence Init(S, Entities.back(), InitKind, Ref); return Init.Perform(S, Entities.back(), InitKind, Ref); } ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, Scope *CurScope) { LambdaScopeInfo LSI = *cast<LambdaScopeInfo>(FunctionScopes.back()); ActOnFinishFunctionBody(LSI.CallOperator, Body); return BuildLambdaExpr(StartLoc, Body->getLocEnd(), &LSI); } static LambdaCaptureDefault mapImplicitCaptureStyle(CapturingScopeInfo::ImplicitCaptureStyle ICS) { switch (ICS) { case CapturingScopeInfo::ImpCap_None: return LCD_None; case CapturingScopeInfo::ImpCap_LambdaByval: return LCD_ByCopy; case CapturingScopeInfo::ImpCap_CapturedRegion: case CapturingScopeInfo::ImpCap_LambdaByref: return LCD_ByRef; case CapturingScopeInfo::ImpCap_Block: llvm_unreachable("block capture in lambda"); } llvm_unreachable("Unknown implicit capture style"); } ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, LambdaScopeInfo *LSI) { // Collect information from the lambda scope. SmallVector<LambdaCapture, 4> Captures; SmallVector<Expr *, 4> CaptureInits; SourceLocation CaptureDefaultLoc = LSI->CaptureDefaultLoc; LambdaCaptureDefault CaptureDefault = mapImplicitCaptureStyle(LSI->ImpCaptureStyle); CXXRecordDecl *Class; CXXMethodDecl *CallOperator; SourceRange IntroducerRange; bool ExplicitParams; bool ExplicitResultType; bool LambdaExprNeedsCleanups; bool ContainsUnexpandedParameterPack; SmallVector<VarDecl *, 4> ArrayIndexVars; SmallVector<unsigned, 4> ArrayIndexStarts; { CallOperator = LSI->CallOperator; Class = LSI->Lambda; IntroducerRange = LSI->IntroducerRange; ExplicitParams = LSI->ExplicitParams; ExplicitResultType = !LSI->HasImplicitReturnType; LambdaExprNeedsCleanups = LSI->ExprNeedsCleanups; ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack; CallOperator->setLexicalDeclContext(Class); Decl *TemplateOrNonTemplateCallOperatorDecl = CallOperator->getDescribedFunctionTemplate() ? CallOperator->getDescribedFunctionTemplate() : cast<Decl>(CallOperator); TemplateOrNonTemplateCallOperatorDecl->setLexicalDeclContext(Class); Class->addDecl(TemplateOrNonTemplateCallOperatorDecl); PopExpressionEvaluationContext(); // Translate captures. auto CurField = Class->field_begin(); for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I, ++CurField) { LambdaScopeInfo::Capture From = LSI->Captures[I]; assert(!From.isBlockCapture() && "Cannot capture __block variables"); bool IsImplicit = I >= LSI->NumExplicitCaptures; // Handle 'this' capture. if (From.isThisCapture()) { Captures.push_back( LambdaCapture(From.getLocation(), IsImplicit, LCK_This)); CaptureInits.push_back(new (Context) CXXThisExpr(From.getLocation(), getCurrentThisType(), /*isImplicit=*/true)); ArrayIndexStarts.push_back(ArrayIndexVars.size()); continue; } if (From.isVLATypeCapture()) { Captures.push_back( LambdaCapture(From.getLocation(), IsImplicit, LCK_VLAType)); CaptureInits.push_back(nullptr); ArrayIndexStarts.push_back(ArrayIndexVars.size()); continue; } VarDecl *Var = From.getVariable(); LambdaCaptureKind Kind = From.isCopyCapture() ? LCK_ByCopy : LCK_ByRef; Captures.push_back(LambdaCapture(From.getLocation(), IsImplicit, Kind, Var, From.getEllipsisLoc())); Expr *Init = From.getInitExpr(); if (!Init) { auto InitResult = performLambdaVarCaptureInitialization( *this, From, *CurField, ArrayIndexVars, ArrayIndexStarts); if (InitResult.isInvalid()) return ExprError(); Init = InitResult.get(); } else { ArrayIndexStarts.push_back(ArrayIndexVars.size()); } CaptureInits.push_back(Init); } // C++11 [expr.prim.lambda]p6: // The closure type for a lambda-expression with no lambda-capture // has a public non-virtual non-explicit const conversion function // to pointer to function having the same parameter and return // types as the closure type's function call operator. if (Captures.empty() && CaptureDefault == LCD_None) addFunctionPointerConversion(*this, IntroducerRange, Class, CallOperator); // Objective-C++: // The closure type for a lambda-expression has a public non-virtual // non-explicit const conversion function to a block pointer having the // same parameter and return types as the closure type's function call // operator. // FIXME: Fix generic lambda to block conversions. if (getLangOpts().Blocks && getLangOpts().ObjC1 && !Class->isGenericLambda()) addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator); // Finalize the lambda class. SmallVector<Decl*, 4> Fields(Class->fields()); ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(), SourceLocation(), nullptr); CheckCompletedCXXClass(Class); } if (LambdaExprNeedsCleanups) ExprNeedsCleanups = true; LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange, CaptureDefault, CaptureDefaultLoc, Captures, ExplicitParams, ExplicitResultType, CaptureInits, ArrayIndexVars, ArrayIndexStarts, EndLoc, ContainsUnexpandedParameterPack); if (!CurContext->isDependentContext()) { switch (ExprEvalContexts.back().Context) { // C++11 [expr.prim.lambda]p2: // A lambda-expression shall not appear in an unevaluated operand // (Clause 5). case Unevaluated: case UnevaluatedAbstract: // C++1y [expr.const]p2: // A conditional-expression e is a core constant expression unless the // evaluation of e, following the rules of the abstract machine, would // evaluate [...] a lambda-expression. // // This is technically incorrect, there are some constant evaluated contexts // where this should be allowed. We should probably fix this when DR1607 is // ratified, it lays out the exact set of conditions where we shouldn't // allow a lambda-expression. case ConstantEvaluated: // We don't actually diagnose this case immediately, because we // could be within a context where we might find out later that // the expression is potentially evaluated (e.g., for typeid). ExprEvalContexts.back().Lambdas.push_back(Lambda); break; case PotentiallyEvaluated: case PotentiallyEvaluatedIfUsed: break; } } return MaybeBindToTemporary(Lambda); } ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, SourceLocation ConvLocation, CXXConversionDecl *Conv, Expr *Src) { // Make sure that the lambda call operator is marked used. CXXRecordDecl *Lambda = Conv->getParent(); CXXMethodDecl *CallOperator = cast<CXXMethodDecl>( Lambda->lookup( Context.DeclarationNames.getCXXOperatorName(OO_Call)).front()); CallOperator->setReferenced(); CallOperator->markUsed(Context); ExprResult Init = PerformCopyInitialization( InitializedEntity::InitializeBlock(ConvLocation, Src->getType(), /*NRVO=*/false), CurrentLocation, Src); if (!Init.isInvalid()) Init = ActOnFinishFullExpr(Init.get()); if (Init.isInvalid()) return ExprError(); // Create the new block to be returned. BlockDecl *Block = BlockDecl::Create(Context, CurContext, ConvLocation); // Set the type information. Block->setSignatureAsWritten(CallOperator->getTypeSourceInfo()); Block->setIsVariadic(CallOperator->isVariadic()); Block->setBlockMissingReturnType(false); // Add parameters. SmallVector<ParmVarDecl *, 4> BlockParams; for (unsigned I = 0, N = CallOperator->getNumParams(); I != N; ++I) { ParmVarDecl *From = CallOperator->getParamDecl(I); BlockParams.push_back(ParmVarDecl::Create(Context, Block, From->getLocStart(), From->getLocation(), From->getIdentifier(), From->getType(), From->getTypeSourceInfo(), From->getStorageClass(), /*DefaultArg=*/nullptr)); } Block->setParams(BlockParams); Block->setIsConversionFromLambda(true); // Add capture. The capture uses a fake variable, which doesn't correspond // to any actual memory location. However, the initializer copy-initializes // the lambda object. TypeSourceInfo *CapVarTSI = Context.getTrivialTypeSourceInfo(Src->getType()); VarDecl *CapVar = VarDecl::Create(Context, Block, ConvLocation, ConvLocation, nullptr, Src->getType(), CapVarTSI, SC_None); BlockDecl::Capture Capture(/*Variable=*/CapVar, /*ByRef=*/false, /*Nested=*/false, /*Copy=*/Init.get()); Block->setCaptures(Context, Capture, /*CapturesCXXThis=*/false); // Add a fake function body to the block. IR generation is responsible // for filling in the actual body, which cannot be expressed as an AST. Block->setBody(new (Context) CompoundStmt(ConvLocation)); // Create the block literal expression. Expr *BuildBlock = new (Context) BlockExpr(Block, Conv->getConversionType()); ExprCleanupObjects.push_back(Block); ExprNeedsCleanups = true; return BuildBlock; }