diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 57 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 5 |
3 files changed, 42 insertions, 22 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 0eb967a641b..8984398eae4 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1793,7 +1793,7 @@ LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) { // an associated template parameter list. LambdaScopeInfo *Sema::getCurGenericLambda() { if (LambdaScopeInfo *LSI = getCurLambda()) { - return (LSI->AutoTemplateParams.size() || + return (LSI->TemplateParams.size() || LSI->GLTemplateParameterList) ? LSI : nullptr; } return nullptr; diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 7ad39fd73ba..1966e9e0803 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -20,6 +20,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/SemaLambda.h" +#include "llvm/ADT/STLExtras.h" using namespace clang; using namespace sema; @@ -225,19 +226,14 @@ Optional<unsigned> clang::getStackIndexOfNearestEnclosingCaptureCapableLambda( static inline TemplateParameterList * getGenericLambdaTemplateParameterList(LambdaScopeInfo *LSI, Sema &SemaRef) { - if (LSI->GLTemplateParameterList) - return LSI->GLTemplateParameterList; - - if (!LSI->AutoTemplateParams.empty()) { - SourceRange IntroRange = LSI->IntroducerRange; - SourceLocation LAngleLoc = IntroRange.getBegin(); - SourceLocation RAngleLoc = IntroRange.getEnd(); + if (!LSI->GLTemplateParameterList && !LSI->TemplateParams.empty()) { LSI->GLTemplateParameterList = TemplateParameterList::Create( SemaRef.Context, - /*Template kw loc*/ SourceLocation(), LAngleLoc, - llvm::makeArrayRef((NamedDecl *const *)LSI->AutoTemplateParams.data(), - LSI->AutoTemplateParams.size()), - RAngleLoc, nullptr); + /*Template kw loc*/ SourceLocation(), + /*L angle loc*/ LSI->ExplicitTemplateParamsRange.getBegin(), + LSI->TemplateParams, + /*R angle loc*/LSI->ExplicitTemplateParamsRange.getEnd(), + nullptr); } return LSI->GLTemplateParameterList; } @@ -492,6 +488,23 @@ void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) { LSI->finishedExplicitCaptures(); } +void Sema::ActOnLambdaExplicitTemplateParameterList(SourceLocation LAngleLoc, + ArrayRef<NamedDecl *> TParams, + SourceLocation RAngleLoc) { + LambdaScopeInfo *LSI = getCurLambda(); + assert(LSI && "Expected a lambda scope"); + assert(LSI->NumExplicitTemplateParams == 0 && + "Already acted on explicit template parameters"); + assert(LSI->TemplateParams.empty() && + "Explicit template parameters should come " + "before invented (auto) ones"); + assert(!TParams.empty() && + "No template parameters to act on"); + LSI->TemplateParams.append(TParams.begin(), TParams.end()); + LSI->NumExplicitTemplateParams = TParams.size(); + LSI->ExplicitTemplateParamsRange = {LAngleLoc, RAngleLoc}; +} + void Sema::addLambdaParameters( ArrayRef<LambdaIntroducer::LambdaCapture> Captures, CXXMethodDecl *CallOperator, Scope *CurScope) { @@ -832,17 +845,23 @@ FieldDecl *Sema::buildInitCaptureField(LambdaScopeInfo *LSI, VarDecl *Var) { 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!"); - // The lambda-expression's closure type might be dependent even if its - // semantic context isn't, if it appears within a default argument of a - // function template. - if (CurScope->getTemplateParamParent()) - KnownDependent = true; + // 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; + if (LSI->NumExplicitTemplateParams > 0) { + auto *TemplateParamScope = CurScope->getTemplateParamParent(); + assert(TemplateParamScope && + "Lambda with explicit template param list should establish a " + "template param scope"); + assert(TemplateParamScope->getParent()); + KnownDependent = TemplateParamScope->getParent() + ->getTemplateParamParent() != nullptr; + } else { + KnownDependent = CurScope->getTemplateParamParent() != nullptr; + } // Determine the signature of the call operator. TypeSourceInfo *MethodTyInfo; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 3b25595a33a..318c6761731 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2935,7 +2935,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, sema::LambdaScopeInfo *LSI = SemaRef.getCurLambda(); assert(LSI && "No LambdaScopeInfo on the stack!"); const unsigned TemplateParameterDepth = LSI->AutoTemplateParameterDepth; - const unsigned AutoParameterPosition = LSI->AutoTemplateParams.size(); + const unsigned AutoParameterPosition = LSI->TemplateParams.size(); const bool IsParameterPack = D.hasEllipsis(); // Create the TemplateTypeParmDecl here to retrieve the corresponding @@ -2947,7 +2947,8 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, /*KeyLoc*/ SourceLocation(), /*NameLoc*/ D.getBeginLoc(), TemplateParameterDepth, AutoParameterPosition, /*Identifier*/ nullptr, false, IsParameterPack); - LSI->AutoTemplateParams.push_back(CorrespondingTemplateParam); + CorrespondingTemplateParam->setImplicit(); + LSI->TemplateParams.push_back(CorrespondingTemplateParam); // Replace the 'auto' in the function parameter with this invented // template type parameter. // FIXME: Retain some type sugar to indicate that this was written |