diff options
author | Corentin Jabot <corentinjabot@gmail.com> | 2023-09-01 08:45:16 +0200 |
---|---|---|
committer | Corentin Jabot <corentinjabot@gmail.com> | 2023-09-02 08:05:49 +0200 |
commit | 890f11d60feffed4207afa58229da7bfaaff276e (patch) | |
tree | 67fe1554d91a44605fbfdafc0140cba51d19d21e /clang/lib/Sema/SemaLambda.cpp | |
parent | f4f40c6dfde46829438a7c4aa815fdffcc7a28e6 (diff) | |
download | llvm-890f11d60feffed4207afa58229da7bfaaff276e.zip llvm-890f11d60feffed4207afa58229da7bfaaff276e.tar.gz llvm-890f11d60feffed4207afa58229da7bfaaff276e.tar.bz2 |
[Clang] Realize generic lambda call operators are dependent sooner
When parsing a trailing return type / noexcept / constraint
of a generic lambda, we need to know that we are in a dependent
context. We currently don't because we only create a TemplateDecl
for the call operator one its fully parsed.
This patch attach a template decl to the call operator as soon
as the parameter declaration clause is parsed - the point at which
we have collected all template parameters
Fixes #64689
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D159358
Diffstat (limited to 'clang/lib/Sema/SemaLambda.cpp')
-rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 26d3a66..5256d91 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -912,6 +912,17 @@ CXXMethodDecl *Sema::CreateLambdaCallOperator(SourceRange IntroducerRange, return Method; } +void Sema::AddTemplateParametersToLambdaCallOperator( + CXXMethodDecl *CallOperator, CXXRecordDecl *Class, + TemplateParameterList *TemplateParams) { + assert(TemplateParams && "no template parameters"); + FunctionTemplateDecl *TemplateMethod = FunctionTemplateDecl::Create( + Context, Class, CallOperator->getLocation(), CallOperator->getDeclName(), + TemplateParams, CallOperator); + TemplateMethod->setAccess(AS_public); + CallOperator->setDescribedFunctionTemplate(TemplateMethod); +} + void Sema::CompleteLambdaCallOperator( CXXMethodDecl *Method, SourceLocation LambdaLoc, SourceLocation CallOperatorLoc, Expr *TrailingRequiresClause, @@ -930,11 +941,11 @@ void Sema::CompleteLambdaCallOperator( DeclContext *DC = Method->getLexicalDeclContext(); Method->setLexicalDeclContext(LSI->Lambda); if (TemplateParams) { - FunctionTemplateDecl *TemplateMethod = FunctionTemplateDecl::Create( - Context, LSI->Lambda, Method->getLocation(), Method->getDeclName(), - TemplateParams, Method); - TemplateMethod->setAccess(AS_public); - Method->setDescribedFunctionTemplate(TemplateMethod); + FunctionTemplateDecl *TemplateMethod = + Method->getDescribedFunctionTemplate(); + assert(TemplateMethod && + "AddTemplateParametersToLambdaCallOperator should have been called"); + LSI->Lambda->addDecl(TemplateMethod); TemplateMethod->setLexicalDeclContext(DC); } else { @@ -1262,6 +1273,17 @@ void Sema::ActOnLambdaClosureParameters( PushOnScopeChains(Param, LambdaScope, false); } + // After the parameter list, we may parse a noexcept/requires/trailing return + // type which need to know whether the call operator constiture a dependent + // context, so we need to setup the FunctionTemplateDecl of generic lambdas + // now. + TemplateParameterList *TemplateParams = + getGenericLambdaTemplateParameterList(LSI, *this); + if (TemplateParams) { + AddTemplateParametersToLambdaCallOperator(LSI->CallOperator, LSI->Lambda, + TemplateParams); + LSI->Lambda->setLambdaIsGeneric(true); + } LSI->AfterParameterList = true; } |