aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaLambda.cpp
diff options
context:
space:
mode:
authorCorentin Jabot <corentinjabot@gmail.com>2023-09-01 08:45:16 +0200
committerCorentin Jabot <corentinjabot@gmail.com>2023-09-02 08:05:49 +0200
commit890f11d60feffed4207afa58229da7bfaaff276e (patch)
tree67fe1554d91a44605fbfdafc0140cba51d19d21e /clang/lib/Sema/SemaLambda.cpp
parentf4f40c6dfde46829438a7c4aa815fdffcc7a28e6 (diff)
downloadllvm-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.cpp32
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;
}