[clang] [Sema] 81145 (PR #81150)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 8 07:45:56 PST 2024
https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/81150
None
>From e2ea5d44935209d13c9eb33c089e4f58f2231acd Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Thu, 8 Feb 2024 23:44:56 +0800
Subject: [PATCH] [Sema] 81145
---
clang/lib/Sema/SemaTemplateInstantiate.cpp | 11 +++++-
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 11 ++++++
clang/test/SemaTemplate/concepts-lambda.cpp | 39 +++++++++++++++++++
3 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 6d59180bc446d..d757923b3e92e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1231,6 +1231,8 @@ namespace {
// Whether to evaluate the C++20 constraints or simply substitute into them.
bool EvaluateConstraints = true;
+ std::optional<LocalInstantiationScope> LambdaInstantiationScope;
+
public:
typedef TreeTransform<TemplateInstantiator> inherited;
@@ -1479,8 +1481,15 @@ namespace {
SubstTemplateTypeParmPackTypeLoc TL,
bool SuppressObjCLifetime);
+ ExprResult TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) {
+ LambdaInstantiationScope.emplace(SemaRef, /*CombineWithOuterScope=*/true);
+ return inherited::TransformUnresolvedMemberExpr(Old);
+ }
+
ExprResult TransformLambdaExpr(LambdaExpr *E) {
- LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
+ std::optional<LocalInstantiationScope> LocalScope;
+ if (!LambdaInstantiationScope)
+ LocalScope.emplace(SemaRef, /*CombineWithOuterScope=*/true);
Sema::ConstraintEvalRAII<TemplateInstantiator> RAII(*this);
ExprResult Result = inherited::TransformLambdaExpr(E);
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index d67b21b4449e0..90e274aba2e48 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6316,6 +6316,17 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
// anonymous unions in class templates).
}
+ bool IsInsideLambda =
+ isa<CXXRecordDecl>(ParentDC) && cast<CXXRecordDecl>(ParentDC)->isLambda();
+
+ if (CurrentInstantiationScope && IsInsideLambda) {
+ if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) {
+ return cast<NamedDecl>(CurrentInstantiationScope
+ ->findInstantiationOf(FTD->getTemplatedDecl())
+ ->get<Decl *>());
+ }
+ }
+
if (!ParentDependsOnArgs)
return D;
diff --git a/clang/test/SemaTemplate/concepts-lambda.cpp b/clang/test/SemaTemplate/concepts-lambda.cpp
index 0b7580f91043c..19075f787eb3c 100644
--- a/clang/test/SemaTemplate/concepts-lambda.cpp
+++ b/clang/test/SemaTemplate/concepts-lambda.cpp
@@ -150,6 +150,26 @@ void foo() {
}
} // namespace ReturnTypeRequirementInLambda
+namespace TypeAliasTemplateDecl {
+
+template <class>
+concept C = true;
+
+template <class T, class U>
+concept D = C<T> && C<U>;
+
+template <class T>
+struct S {
+ template <class U>
+ using Type = decltype([]<C V> {
+ return V();
+ }.template operator()<U>());
+};
+
+S<int>::Type<int> V;
+
+}
+
namespace GH73418 {
void foo() {
int x;
@@ -167,3 +187,22 @@ void foo() {
}(x);
}
} // namespace GH73418
+
+// namespace GH70601 {
+
+// template <class>
+// concept C = true;
+
+// template <class T, class U>
+// concept D = C<T> && C<U>;
+
+// template <class T>
+// using Type = decltype([]<C U> {
+// return []<D<U> V>(V val) {
+// return val;
+// }(U());
+// }.template operator()<T>());
+
+// static_assert(__is_same(Type<int>, int));
+
+// } // namespace GH70601
More information about the cfe-commits
mailing list