diff options
author | Hamza Sood <hamza_sood@me.com> | 2019-05-04 10:49:46 +0000 |
---|---|---|
committer | Hamza Sood <hamza_sood@me.com> | 2019-05-04 10:49:46 +0000 |
commit | 8205a814a691bfa62fed911b58b0a306ab5efe31 (patch) | |
tree | cbd4d43e2edb58be4b532986547b842cf2be207c /clang/lib/Sema/SemaLambda.cpp | |
parent | 9c32fa1b1f60ea95e627a485b7a8e766ba3e622c (diff) | |
download | bcm5719-llvm-8205a814a691bfa62fed911b58b0a306ab5efe31.tar.gz bcm5719-llvm-8205a814a691bfa62fed911b58b0a306ab5efe31.zip |
[c++20] Implement P0428R2 - Familiar template syntax for generic lambdas
Differential Revision: https://reviews.llvm.org/D36527
llvm-svn: 359967
Diffstat (limited to 'clang/lib/Sema/SemaLambda.cpp')
-rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 57 |
1 files changed, 38 insertions, 19 deletions
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; |