mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-08 03:13:58 +00:00
[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
This commit is contained in:
parent
f4f40c6dfd
commit
890f11d60f
@ -257,6 +257,9 @@ Bug Fixes to C++ Support
|
||||
(`#64172 <https://github.com/llvm/llvm-project/issues/64172>`_) and
|
||||
(`#64723 <https://github.com/llvm/llvm-project/issues/64723>`_).
|
||||
|
||||
Fix crash when parsing the requires clause of some generic lambdas.
|
||||
(`#64689 <https://github.com/llvm/llvm-project/issues/64689>`_`)
|
||||
|
||||
Bug Fixes to AST Handling
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
- Fixed an import failure of recursive friend class template.
|
||||
|
@ -7216,6 +7216,11 @@ public:
|
||||
|
||||
CXXMethodDecl *CreateLambdaCallOperator(SourceRange IntroducerRange,
|
||||
CXXRecordDecl *Class);
|
||||
|
||||
void AddTemplateParametersToLambdaCallOperator(
|
||||
CXXMethodDecl *CallOperator, CXXRecordDecl *Class,
|
||||
TemplateParameterList *TemplateParams);
|
||||
|
||||
void CompleteLambdaCallOperator(
|
||||
CXXMethodDecl *Method, SourceLocation LambdaLoc,
|
||||
SourceLocation CallOperatorLoc, Expr *TrailingRequiresClause,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -13558,6 +13558,9 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
|
||||
auto TPL = getDerived().TransformTemplateParameterList(
|
||||
E->getTemplateParameterList());
|
||||
LSI->GLTemplateParameterList = TPL;
|
||||
if (TPL)
|
||||
getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
|
||||
TPL);
|
||||
|
||||
// Transform the type of the original lambda's call operator.
|
||||
// The transformation MUST be done in the CurrentInstantiationScope since
|
||||
|
@ -70,3 +70,20 @@ static_assert(B<>(42) == 42);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace GH64689 {
|
||||
void f();
|
||||
void foo() {
|
||||
[]<typename T>(int)
|
||||
noexcept(requires(int t) { f(); })
|
||||
-> decltype(requires(int t) { f(); })
|
||||
requires requires(int t) { f(); }
|
||||
{return {};}.operator()<int>(0);
|
||||
[](auto)
|
||||
noexcept(requires(int t) { f(); })
|
||||
-> decltype(requires(int t) { f(); })
|
||||
requires requires(int t) { f(); }
|
||||
{return {};}(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user