diff options
author | dim <dim@FreeBSD.org> | 2014-11-24 18:11:16 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-11-24 18:11:16 +0000 |
commit | 6148c19c738a92f344008aa3f88f4e008bada0ee (patch) | |
tree | d4426858455f04d0d8c25a2f9eb9ea5582ffe1b6 /contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp | |
parent | 2c8643c6396b0a3db33430cf9380e70bbb9efce0 (diff) | |
parent | 173a4f43a911175643bda81ee675e8d9269056ea (diff) | |
download | FreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.zip FreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.tar.gz |
Merge clang 3.5.0 release from ^/vendor/clang/dist, resolve conflicts,
and preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp | 460 |
1 files changed, 277 insertions, 183 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp index a7d5b65..0cf4ed7 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp @@ -11,125 +11,214 @@ // //===----------------------------------------------------------------------===// #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/Lex/Preprocessor.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" -#include "TypeLocBuilder.h" using namespace clang; using namespace sema; -// returns -1 if none of the lambdas on the scope stack can capture. -// A lambda 'L' is capture-ready for a certain variable 'V' if, -// - its enclosing context is non-dependent -// - and if the chain of lambdas between L and the lambda in which -// V is potentially used, call all capture or have captured V. -static inline int GetScopeIndexOfNearestCaptureReadyLambda( - ArrayRef<clang::sema::FunctionScopeInfo*> FunctionScopes, - DeclContext *const CurContext, VarDecl *VD) { +/// \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"); - DeclContext *EnclosingDC = CurContext; - // If VD is null, we are attempting to capture 'this' - const bool IsCapturingThis = !VD; + // If VarToCapture is null, we are attempting to capture 'this'. + const bool IsCapturingThis = !VarToCapture; const bool IsCapturingVariable = !IsCapturingThis; - int RetIndex = -1; + + // Start with the current lambda at the top of the stack (highest index). unsigned CurScopeIndex = FunctionScopes.size() - 1; - while (!EnclosingDC->isTranslationUnit() && - EnclosingDC->isDependentContext() && isLambdaCallOperator(EnclosingDC)) { - RetIndex = CurScopeIndex; - clang::sema::LambdaScopeInfo *LSI = - cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]); - // We have crawled up to an intervening lambda that contains the - // variable declaration - so not only does it not need to capture; - // none of the enclosing lambdas need to capture it, and since all - // other nested lambdas are dependent (otherwise we wouldn't have - // arrived here) - we don't yet have a lambda that can capture the + 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. - if (IsCapturingVariable && VD->getDeclContext()->Equals(EnclosingDC)) - return -1; - // All intervening lambda call operators have to be able to capture. + // 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 + // 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(VD)) - return -1; + if (IsCapturingVariable && !LSI->isCaptured(VarToCapture)) + return NoLambdaIsCaptureReady; if (IsCapturingThis && !LSI->isCXXThisCaptured()) - return -1; + 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 - // is capture-ready. + // (one index above) is capture-ready. if (!EnclosingDC->isDependentContext()) - return RetIndex; - return -1; + return CurScopeIndex + 1; + return NoLambdaIsCaptureReady; } -// Given a lambda's call operator and a variable (or null for 'this'), -// compute the nearest enclosing lambda that is capture-ready (i.e -// the enclosing context is not dependent, and all intervening lambdas can -// either implicitly or explicitly capture Var) -// -// The approach is as follows, for the entity VD ('this' if null): -// - start with the current lambda -// - if it is non-dependent and can capture VD, return it. -// - if it is dependent and has an implicit or explicit capture, check its parent -// whether the parent is non-depdendent and all its intervening lambdas -// can capture, if so return the child. -// [Note: When we hit a generic lambda specialization, do not climb up -// the scope stack any further since not only do we not need to, -// the scope stack will often not be synchronized with any lambdas -// enclosing the specialized generic lambda] -// -// Return the CallOperator of the capturable lambda and set function scope -// index to the correct index within the function scope stack to correspond -// to the capturable lambda. -// If VarDecl *VD is null, we check for 'this' capture. -CXXMethodDecl* clang::GetInnermostEnclosingCapturableLambda( - ArrayRef<sema::FunctionScopeInfo*> FunctionScopes, - unsigned &FunctionScopeIndex, - DeclContext *const CurContext, VarDecl *VD, - Sema &S) { - - const int IndexOfCaptureReadyLambda = - GetScopeIndexOfNearestCaptureReadyLambda(FunctionScopes,CurContext, VD); - if (IndexOfCaptureReadyLambda == -1) return 0; - assert(IndexOfCaptureReadyLambda >= 0); - const unsigned IndexOfCaptureReadyLambdaU = - static_cast<unsigned>(IndexOfCaptureReadyLambda); - sema::LambdaScopeInfo *const CaptureReadyLambdaLSI = - cast<sema::LambdaScopeInfo>(FunctionScopes[IndexOfCaptureReadyLambdaU]); - // If VD is null, we are attempting to capture 'this' - const bool IsCapturingThis = !VD; + +/// \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) { - // Now check to see if this lambda can truly capture, and also - // if all enclosing lambdas of this lambda allow this capture. + // 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(VD, - /*ExprVarIsUsedInLoc*/SourceLocation(), clang::Sema::TryCapture_Implicit, - /*EllipsisLoc*/ SourceLocation(), - /*BuildAndDiagnose*/false, CaptureType, DeclRefType, - &IndexOfCaptureReadyLambdaU); - if (!CanCaptureVariable) return 0; - } else { - const bool CanCaptureThis = !S.CheckCXXThisCapture( - CaptureReadyLambdaLSI->PotentialThisCaptureLocation, false, false, - &IndexOfCaptureReadyLambdaU); - if (!CanCaptureThis) return 0; - } // end 'this' capture test - FunctionScopeIndex = IndexOfCaptureReadyLambdaU; - return CaptureReadyLambdaLSI->CallOperator; + 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 * @@ -142,17 +231,14 @@ getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) { 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); + 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, @@ -169,7 +255,7 @@ CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange, IsGenericLambda, CaptureDefault); DC->addDecl(Class); - + return Class; } @@ -230,18 +316,18 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC, if ((IsInNonspecializedTemplate && !(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) || isInInlineFunction(CurContext)) { - ManglingContextDecl = 0; + ManglingContextDecl = nullptr; return &Context.getManglingNumberContext(DC); } - ManglingContextDecl = 0; - return 0; + ManglingContextDecl = nullptr; + return nullptr; case StaticDataMember: // -- the initializers of nonspecialized static members of template classes if (!IsInNonspecializedTemplate) { - ManglingContextDecl = 0; - return 0; + ManglingContextDecl = nullptr; + return nullptr; } // Fall through to get the current context. @@ -277,10 +363,10 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, // dependent type. if (Class->isDependentContext() || TemplateParams) { const FunctionProtoType *FPT = MethodType->castAs<FunctionProtoType>(); - QualType Result = FPT->getResultType(); + QualType Result = FPT->getReturnType(); if (Result->isUndeducedType()) { Result = SubstAutoType(Result, Context.DependentTy); - MethodType = Context.getFunctionType(Result, FPT->getArgTypes(), + MethodType = Context.getFunctionType(Result, FPT->getParamTypes(), FPT->getExtProtoInfo()); } } @@ -317,7 +403,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, FunctionTemplateDecl::Create(Context, Class, Method->getLocation(), MethodName, TemplateParams, - Method) : 0; + Method) : nullptr; if (TemplateMethod) { TemplateMethod->setLexicalDeclContext(CurContext); TemplateMethod->setAccess(AS_public); @@ -331,10 +417,8 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, const_cast<ParmVarDecl **>(Params.end()), /*CheckParameterNames=*/false); - for (CXXMethodDecl::param_iterator P = Method->param_begin(), - PEnd = Method->param_end(); - P != PEnd; ++P) - (*P)->setOwningFunction(Method); + for (auto P : Method->params()) + P->setOwningFunction(Method); } Decl *ManglingContextDecl; @@ -369,8 +453,8 @@ void Sema::buildLambdaScope(LambdaScopeInfo *LSI, LSI->Mutable = Mutable; if (ExplicitResultType) { - LSI->ReturnType = CallOperator->getResultType(); - + LSI->ReturnType = CallOperator->getReturnType(); + if (!LSI->ReturnType->isDependentType() && !LSI->ReturnType->isVoidType()) { if (RequireCompleteType(CallOperator->getLocStart(), LSI->ReturnType, @@ -420,7 +504,7 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) { = dyn_cast<EnumConstantDecl>(DRE->getDecl())) { return cast<EnumDecl>(D->getDeclContext()); } - return 0; + return nullptr; } // - it is a comma expression whose RHS is an enumerator-like @@ -428,7 +512,7 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) { if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { if (BO->getOpcode() == BO_Comma) return findEnumForBlockReturn(BO->getRHS()); - return 0; + return nullptr; } // - it is a statement-expression whose value expression is an @@ -436,7 +520,7 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) { if (StmtExpr *SE = dyn_cast<StmtExpr>(E)) { if (Expr *last = dyn_cast_or_null<Expr>(SE->getSubStmt()->body_back())) return findEnumForBlockReturn(last); - return 0; + return nullptr; } // - it is a ternary conditional operator (not the GNU ?: @@ -446,7 +530,7 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) { if (EnumDecl *ED = findEnumForBlockReturn(CO->getTrueExpr())) if (ED == findEnumForBlockReturn(CO->getFalseExpr())) return ED; - return 0; + return nullptr; } // (implicitly:) @@ -467,7 +551,7 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) { } // Otherwise, nope. - return 0; + return nullptr; } /// Attempt to find a type T for which the returned expression of the @@ -475,7 +559,7 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) { static EnumDecl *findEnumForBlockReturn(ReturnStmt *ret) { if (Expr *retValue = ret->getRetValue()) return findEnumForBlockReturn(retValue); - return 0; + return nullptr; } /// Attempt to find a common type T for which all of the returned @@ -486,16 +570,16 @@ static EnumDecl *findCommonEnumForBlockReturns(ArrayRef<ReturnStmt*> returns) { // Try to find one for the first return. EnumDecl *ED = findEnumForBlockReturn(*i); - if (!ED) return 0; + 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 0; + return nullptr; } // Never infer an anonymous enum type. - if (!ED->hasNameForLinkage()) return 0; + if (!ED->hasNameForLinkage()) return nullptr; return ED; } @@ -519,7 +603,7 @@ static void adjustBlockReturnsToEnum(Sema &S, ArrayRef<ReturnStmt*> returns, Expr *E = (cleanups ? cleanups->getSubExpr() : retValue); E = ImplicitCastExpr::Create(S.Context, returnType, CK_IntegralCast, - E, /*base path*/ 0, VK_RValue); + E, /*base path*/ nullptr, VK_RValue); if (cleanups) { cleanups->setSubExpr(E); } else { @@ -651,6 +735,9 @@ QualType Sema::performLambdaInitCaptureInitialization(SourceLocation Loc, return QualType(); } else { DeduceInit = CXXDirectInit->getExpr(0); + if (isa<InitListExpr>(DeduceInit)) + Diag(CXXDirectInit->getLocStart(), diag::err_init_capture_paren_braces) + << DeclarationName(Id) << Loc; } } @@ -695,7 +782,7 @@ QualType Sema::performLambdaInitCaptureInitialization(SourceLocation Loc, if (Result.isInvalid()) return QualType(); - Init = Result.takeAs<Expr>(); + 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 @@ -706,7 +793,7 @@ QualType Sema::performLambdaInitCaptureInitialization(SourceLocation Loc, if (Result.isInvalid()) return QualType(); - Init = Result.takeAs<Expr>(); + Init = Result.getAs<Expr>(); return DeducedType; } @@ -732,7 +819,8 @@ VarDecl *Sema::createLambdaInitCaptureVarDecl(SourceLocation Loc, FieldDecl *Sema::buildInitCaptureField(LambdaScopeInfo *LSI, VarDecl *Var) { FieldDecl *Field = FieldDecl::Create( Context, LSI->Lambda, Var->getLocation(), Var->getLocation(), - 0, Var->getType(), Var->getTypeSourceInfo(), 0, false, ICIS_NoInit); + nullptr, Var->getType(), Var->getTypeSourceInfo(), nullptr, false, + ICIS_NoInit); Field->setImplicit(true); Field->setAccess(AS_private); LSI->Lambda->addDecl(Field); @@ -758,7 +846,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, // has template params, only then are we in a dependent scope. if (TemplateParams) { TmplScope = TmplScope->getParent(); - TmplScope = TmplScope ? TmplScope->getTemplateParamParent() : 0; + TmplScope = TmplScope ? TmplScope->getTemplateParamParent() : nullptr; } if (TmplScope && !TmplScope->decl_empty()) KnownDependent = true; @@ -811,14 +899,10 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, ExplicitResultType = FTI.hasTrailingReturnType(); - if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 && - cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) { - // Empty arg list, don't push any params. - checkVoidParamDecl(cast<ParmVarDecl>(FTI.ArgInfo[0].Param)); - } else { - Params.reserve(FTI.NumArgs); - for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) - Params.push_back(cast<ParmVarDecl>(FTI.ArgInfo[i].Param)); + 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. @@ -848,27 +932,40 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, 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 (SmallVectorImpl<LambdaCapture>::const_iterator - C = Intro.Captures.begin(), - E = Intro.Captures.end(); - C != E; + 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(PP.getLocForEndOfToken(PrevCaptureLoc), C->Loc)); + Diag(C->Loc, diag::err_capture_more_than_once) + << "'this'" << SourceRange(LSI->getCXXThisCapture().getLocation()) + << FixItHint::CreateRemoval( + SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); continue; } @@ -877,8 +974,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, // lambda-capture shall not contain this [...]. if (Intro.Default == LCD_ByCopy) { Diag(C->Loc, diag::err_this_capture_with_copy_default) - << FixItHint::CreateRemoval( - SourceRange(PP.getLocForEndOfToken(PrevCaptureLoc), C->Loc)); + << FixItHint::CreateRemoval( + SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); continue; } @@ -900,7 +997,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, if (C->Init.isInvalid()) continue; - VarDecl *Var = 0; + VarDecl *Var = nullptr; if (C->Init.isUsable()) { Diag(C->Loc, getLangOpts().CPlusPlus1y ? diag::warn_cxx11_compat_init_capture @@ -916,7 +1013,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, if (C->InitCaptureType.get().isNull()) continue; Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(), - C->Id, C->Init.take()); + C->Id, 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 @@ -931,13 +1028,13 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, // 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(PP.getLocForEndOfToken(PrevCaptureLoc), C->Loc)); + << 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(PP.getLocForEndOfToken(PrevCaptureLoc), C->Loc)); + << FixItHint::CreateRemoval( + SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); continue; } @@ -958,6 +1055,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, } Var = R.getAsSingle<VarDecl>(); + if (Var && DiagnoseUseOfDecl(Var, C->Loc)) + continue; } // C++11 [expr.prim.lambda]p8: @@ -966,9 +1065,9 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, if (!CaptureNames.insert(C->Id)) { if (Var && LSI->isCaptured(Var)) { Diag(C->Loc, diag::err_capture_more_than_once) - << C->Id << SourceRange(LSI->getCapture(Var).getLocation()) - << FixItHint::CreateRemoval( - SourceRange(PP.getLocForEndOfToken(PrevCaptureLoc), C->Loc)); + << 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. @@ -1033,6 +1132,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, bool IsInstantiation) { + LambdaScopeInfo *LSI = getCurLambda(); + // Leave the expression-evaluation context. DiscardCleanupsInEvaluationContext(); PopExpressionEvaluationContext(); @@ -1042,15 +1143,11 @@ void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, PopDeclContext(); // Finalize the lambda. - LambdaScopeInfo *LSI = getCurLambda(); CXXRecordDecl *Class = LSI->Lambda; Class->setInvalidDecl(); - SmallVector<Decl*, 4> Fields; - for (RecordDecl::field_iterator i = Class->field_begin(), - e = Class->field_end(); i != e; ++i) - Fields.push_back(*i); - ActOnFields(0, Class->getLocation(), Class, Fields, - SourceLocation(), SourceLocation(), 0); + SmallVector<Decl*, 4> Fields(Class->fields()); + ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(), + SourceLocation(), nullptr); CheckCompletedCXXClass(Class); PopFunctionScopeInfo(); @@ -1077,8 +1174,9 @@ static void addFunctionPointerConversion(Sema &S, InvokerExtInfo.TypeQuals = 0; assert(InvokerExtInfo.RefQualifier == RQ_None && "Lambda's call operator should not have a reference qualifier"); - InvokerFunctionTy = S.Context.getFunctionType(CallOpProto->getResultType(), - CallOpProto->getArgTypes(), InvokerExtInfo); + InvokerFunctionTy = + S.Context.getFunctionType(CallOpProto->getReturnType(), + CallOpProto->getParamTypes(), InvokerExtInfo); PtrToFunctionTy = S.Context.getPointerType(InvokerFunctionTy); } @@ -1122,7 +1220,7 @@ static void addFunctionPointerConversion(Sema &S, ConvTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>(); // Get the result of the conversion function which is a pointer-to-function. PointerTypeLoc PtrToFunctionTL = - ConvTL.getResultLoc().getAs<PointerTypeLoc>(); + ConvTL.getReturnLoc().getAs<PointerTypeLoc>(); // Do the same for the TypeSourceInfo that is used to name the conversion // operator. PointerTypeLoc ConvNamePtrToFunctionTL = @@ -1156,9 +1254,9 @@ static void addFunctionPointerConversion(Sema &S, From->getType(), From->getTypeSourceInfo(), From->getStorageClass(), - /*DefaultArg=*/0)); - CallOpConvTL.setArg(I, From); - CallOpConvNameTL.setArg(I, From); + /*DefaultArg=*/nullptr)); + CallOpConvTL.setParam(I, From); + CallOpConvNameTL.setParam(I, From); } CXXConversionDecl *Conversion @@ -1244,7 +1342,7 @@ static void addBlockPointerConversion(Sema &S, FunctionProtoType::ExtProtoInfo ExtInfo = Proto->getExtProtoInfo(); ExtInfo.TypeQuals = 0; QualType FunctionTy = S.Context.getFunctionType( - Proto->getResultType(), Proto->getArgTypes(), ExtInfo); + Proto->getReturnType(), Proto->getParamTypes(), ExtInfo); BlockPtrTy = S.Context.getBlockPointerType(FunctionTy); } @@ -1276,7 +1374,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, Scope *CurScope, bool IsInstantiation) { // Collect information from the lambda scope. - SmallVector<LambdaExpr::Capture, 4> Captures; + SmallVector<LambdaCapture, 4> Captures; SmallVector<Expr *, 4> CaptureInits; LambdaCaptureDefault CaptureDefault; SourceLocation CaptureDefaultLoc; @@ -1309,9 +1407,8 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, // Handle 'this' capture. if (From.isThisCapture()) { - Captures.push_back(LambdaExpr::Capture(From.getLocation(), - IsImplicit, - LCK_This)); + Captures.push_back( + LambdaCapture(From.getLocation(), IsImplicit, LCK_This)); CaptureInits.push_back(new (Context) CXXThisExpr(From.getLocation(), getCurrentThisType(), /*isImplicit=*/true)); @@ -1320,8 +1417,8 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, VarDecl *Var = From.getVariable(); LambdaCaptureKind Kind = From.isCopyCapture()? LCK_ByCopy : LCK_ByRef; - Captures.push_back(LambdaExpr::Capture(From.getLocation(), IsImplicit, - Kind, Var, From.getEllipsisLoc())); + Captures.push_back(LambdaCapture(From.getLocation(), IsImplicit, Kind, + Var, From.getEllipsisLoc())); CaptureInits.push_back(From.getInitExpr()); } @@ -1369,7 +1466,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, const FunctionProtoType *Proto = CallOperator->getType()->getAs<FunctionProtoType>(); QualType FunctionTy = Context.getFunctionType( - LSI->ReturnType, Proto->getArgTypes(), Proto->getExtProtoInfo()); + LSI->ReturnType, Proto->getParamTypes(), Proto->getExtProtoInfo()); CallOperator->setType(FunctionTy); } // C++ [expr.prim.lambda]p7: @@ -1407,12 +1504,9 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator); // Finalize the lambda class. - SmallVector<Decl*, 4> Fields; - for (RecordDecl::field_iterator i = Class->field_begin(), - e = Class->field_end(); i != e; ++i) - Fields.push_back(*i); - ActOnFields(0, Class->getLocation(), Class, Fields, - SourceLocation(), SourceLocation(), 0); + SmallVector<Decl*, 4> Fields(Class->fields()); + ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(), + SourceLocation(), nullptr); CheckCompletedCXXClass(Class); } @@ -1478,7 +1572,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, /*NRVO=*/false), CurrentLocation, Src); if (!Init.isInvalid()) - Init = ActOnFinishFullExpr(Init.take()); + Init = ActOnFinishFullExpr(Init.get()); if (Init.isInvalid()) return ExprError(); @@ -1502,7 +1596,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, From->getType(), From->getTypeSourceInfo(), From->getStorageClass(), - /*DefaultArg=*/0)); + /*DefaultArg=*/nullptr)); } Block->setParams(BlockParams); @@ -1514,11 +1608,11 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, TypeSourceInfo *CapVarTSI = Context.getTrivialTypeSourceInfo(Src->getType()); VarDecl *CapVar = VarDecl::Create(Context, Block, ConvLocation, - ConvLocation, 0, + ConvLocation, nullptr, Src->getType(), CapVarTSI, SC_None); BlockDecl::Capture Capture(/*Variable=*/CapVar, /*ByRef=*/false, - /*Nested=*/false, /*Copy=*/Init.take()); + /*Nested=*/false, /*Copy=*/Init.get()); Block->setCaptures(Context, &Capture, &Capture + 1, /*CapturesCXXThis=*/false); |