[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