[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-08 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

@jcsxky At the glance of the stacktrace, I suspect we probably need some 
mechanism of deferral codegen while instantiating the enclosing struct. Can you 
please file a separate issue?

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-08 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

> > Still crash on
> > ```c++
> > template constexpr auto x = F();
> > template constexpr int a() { return 1; }
> > 
> > template 
> > struct A {
> > using Func = decltype(
> > [](T) {
> > return x<[] constexpr { return a(); }>;
> > // return x<[] constexpr { return b(); }>;
> > }.template operator()('2')
> > );
> > };
> > A::Func y;
> > ```
> 
> That is a distinct case: Func does _not_ form a `TypeAliasTemplateDecl`, and 
> thus it is _not_ supposed to be covered by this PR. Please submit a new issue 
> for it.

Consider this one,
```cpp
template constexpr auto x = F();
template constexpr int a() { return 1; }

template 
struct A {
template
using Func = decltype(
[](T) {
return x<[] constexpr { return a(); }>;
}.template operator()('2')
);
};
A::Func y;
```
`Func` is a `TypeAliasTemplateDecl` and crashes as well.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-08 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

> Still crash on
> 
> ```c++
> template constexpr auto x = F();
> template constexpr int a() { return 1; }
> 
> template 
> struct A {
> using Func = decltype(
> [](T) {
> return x<[] constexpr { return a(); }>;
> // return x<[] constexpr { return b(); }>;
> }.template operator()('2')
> );
> };
> A::Func y;
> ```

That is a distinct case: Func does *not* form a `TypeAliasTemplateDecl`, and 
thus it is *not* supposed to be covered by this PR. Please submit a new issue 
for it.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-08 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

Still crash on
```cpp
template constexpr auto x = F();
template constexpr int a() { return 1; }

template 
struct A {
using Func = decltype(
[](T) {
return x<[] constexpr { return a(); }>;
// return x<[] constexpr { return b(); }>;
}.template operator()('2')
);
};
A::Func y;
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-04 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 closed 
https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-04 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

Thank you folks for the insightful review! I'm merging this PR now.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-04 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 edited 
https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-04 Thread Younan Zhang via cfe-commits


@@ -80,6 +80,81 @@ struct Response {
 return R;
   }
 };
+
+// Retrieve the primary template for a lambda call operator. It's
+// unfortunate that we only have the mappings of call operators rather
+// than lambda classes.
+const FunctionDecl *
+getPrimaryTemplateOfGenericLambda(const FunctionDecl *LambdaCallOperator) {
+  while (true) {

zyn0217 wrote:

(Sorry for replying this late, I just got around to this PR.)

> What cases do we have where this takes more than 1 step?
The lambda itself might be defined within a template, and I presume 
transforming that template introduces multilevel mappings.

> I also wonder if we'd be better off finding the primary `CXXRecordDecl`, then 
> picking it up from there? We could use `getTemplateInstantiationPattern` then 
> `getDescribedClassTemplate` I think?

If we examine `TemplateInstantiator::transformedLocalDecl`, we'd see there's 
only handling for `CXXMethodDecls` of adding such mappings that we can extract 
from the Decls themselves. I think it is possible that we can use the primary 
`CXXRecordDecl` approach, although looking for that Decl might involve handling 
`LocalInstantiationScopes`, which IMO is not super straightforward.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-04 Thread Shafik Yaghmour via cfe-commits

shafik wrote:

ping @cor3ntin 

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-01 Thread Erich Keane via cfe-commits


@@ -80,6 +80,81 @@ struct Response {
 return R;
   }
 };
+
+// Retrieve the primary template for a lambda call operator. It's
+// unfortunate that we only have the mappings of call operators rather
+// than lambda classes.
+const FunctionDecl *
+getPrimaryTemplateOfGenericLambda(const FunctionDecl *LambdaCallOperator) {
+  while (true) {

erichkeane wrote:

What cases do we have where this takes more than 1 step?  I also wonder if we'd 
be better off finding the primary `CXXRecordDecl`, then picking it up from 
there?  We could use `getTemplateInstantiationPattern` then 
`getDescribedClassTemplate` I think?

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-01 Thread Erich Keane via cfe-commits

https://github.com/erichkeane edited 
https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-01 Thread Erich Keane via cfe-commits

https://github.com/erichkeane commented:

1 thought, else I don't see anything.  @cor3ntin is coming back in a few days, 
so I'd like him to do a final once over.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-04-01 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

Friendly ping @cor3ntin and @erichkeane if you're back in the offices.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-12 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

> I think some `static_assert` statements are required to demonstrate it does 
> deduce the type of template parameters correctly.

Added. Although the patch doesn't touch that type deduction part and thus they 
are theoretically not affected.


https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-12 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/82310

>From 25f493da55e5cd7d46dda6fca6062aa56b6a3fd0 Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Tue, 20 Feb 2024 14:54:14 +0800
Subject: [PATCH 1/7] The lambda call inside of a type alias

---
 clang/docs/ReleaseNotes.rst   |  2 +
 clang/include/clang/AST/DeclCXX.h |  4 +
 clang/include/clang/Sema/Sema.h   |  8 ++
 clang/lib/Frontend/FrontendActions.cpp|  2 +
 clang/lib/Sema/SemaConcept.cpp| 15 ++--
 clang/lib/Sema/SemaTemplate.cpp   |  9 +-
 clang/lib/Sema/SemaTemplateInstantiate.cpp| 64 ++-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  5 ++
 clang/lib/Sema/TreeTransform.h|  9 ++
 .../alias-template-with-lambdas.cpp   | 82 +++
 10 files changed, 186 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/SemaTemplate/alias-template-with-lambdas.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 690fc7ed271a3db..f5dc956cf5fc4aa 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -344,6 +344,8 @@ Bug Fixes to C++ Support
   when one of the function had more specialized templates.
   Fixes (`#82509 `_)
   and (`#74494 `_)
+- Clang now supports direct lambda calls inside of a type alias template 
declarations.
+  This addresses (#GH70601), (#GH76674), (#GH79555), (#GH81145) and so on.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 9cebaff63bb0dbe..7aed4d5cbc002e2 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1869,6 +1869,10 @@ class CXXRecordDecl : public RecordDecl {
 DL.MethodTyInfo = TS;
   }
 
+  void setLambdaDependencyKind(unsigned Kind) {
+getLambdaData().DependencyKind = Kind;
+  }
+
   void setLambdaIsGeneric(bool IsGeneric) {
 assert(DefinitionData && DefinitionData->IsLambda &&
"setting lambda property of non-lambda class");
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index cfc1c3b34947880..a5520e19a14327d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10145,6 +10145,8 @@ class Sema final {
 
   /// We are building deduction guides for a class.
   BuildingDeductionGuides,
+
+  TypeAliasTemplateInstantiation,
 } Kind;
 
 /// Was the enclosing context a non-instantiation SFINAE context?
@@ -10234,6 +10236,12 @@ class Sema final {
   FunctionDecl *Entity, ExceptionSpecification,
   SourceRange InstantiationRange = SourceRange());
 
+/// Note that we are instantiating a type alias template declaration.
+InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
+  TypeAliasTemplateDecl *Template,
+  ArrayRef TemplateArgs,
+  SourceRange InstantiationRange = SourceRange());
+
 /// Note that we are instantiating a default argument in a
 /// template-id.
 InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
diff --git a/clang/lib/Frontend/FrontendActions.cpp 
b/clang/lib/Frontend/FrontendActions.cpp
index 50338bfa670f830..5f0299dfa32e24b 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -452,6 +452,8 @@ class DefaultTemplateInstCallback : public 
TemplateInstantiationCallback {
   return "BuildingBuiltinDumpStructCall";
 case CodeSynthesisContext::BuildingDeductionGuides:
   return "BuildingDeductionGuides";
+case Sema::CodeSynthesisContext::TypeAliasTemplateInstantiation:
+  return "TypeAliasTemplateInstantiation";
 }
 return "";
   }
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index a8e387e35fb4c90..0b84d83b4fb4b81 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -615,14 +615,13 @@ bool Sema::SetupConstraintScope(
 // reference the original primary template.
 // We walk up the instantiated template chain so that nested lambdas get
 // handled properly.
-for (FunctionTemplateDecl *FromMemTempl =
- PrimaryTemplate->getInstantiatedFromMemberTemplate();
- FromMemTempl;
- FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate()) {
-  if (addInstantiatedParametersToScope(FD, 
FromMemTempl->getTemplatedDecl(),
-   Scope, MLTAL))
-return true;
-}
+FunctionTemplateDecl *FromMemTempl =
+PrimaryTemplate->getInstantiatedFromMemberTemplate();
+while (FromMemTempl && FromMemTempl->getInstantiatedFromMemberTemplate())
+  FromMemTempl = 

[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-12 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/82310

>From 25f493da55e5cd7d46dda6fca6062aa56b6a3fd0 Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Tue, 20 Feb 2024 14:54:14 +0800
Subject: [PATCH 1/7] The lambda call inside of a type alias

---
 clang/docs/ReleaseNotes.rst   |  2 +
 clang/include/clang/AST/DeclCXX.h |  4 +
 clang/include/clang/Sema/Sema.h   |  8 ++
 clang/lib/Frontend/FrontendActions.cpp|  2 +
 clang/lib/Sema/SemaConcept.cpp| 15 ++--
 clang/lib/Sema/SemaTemplate.cpp   |  9 +-
 clang/lib/Sema/SemaTemplateInstantiate.cpp| 64 ++-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  5 ++
 clang/lib/Sema/TreeTransform.h|  9 ++
 .../alias-template-with-lambdas.cpp   | 82 +++
 10 files changed, 186 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/SemaTemplate/alias-template-with-lambdas.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 690fc7ed271a3db..f5dc956cf5fc4aa 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -344,6 +344,8 @@ Bug Fixes to C++ Support
   when one of the function had more specialized templates.
   Fixes (`#82509 `_)
   and (`#74494 `_)
+- Clang now supports direct lambda calls inside of a type alias template 
declarations.
+  This addresses (#GH70601), (#GH76674), (#GH79555), (#GH81145) and so on.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 9cebaff63bb0dbe..7aed4d5cbc002e2 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1869,6 +1869,10 @@ class CXXRecordDecl : public RecordDecl {
 DL.MethodTyInfo = TS;
   }
 
+  void setLambdaDependencyKind(unsigned Kind) {
+getLambdaData().DependencyKind = Kind;
+  }
+
   void setLambdaIsGeneric(bool IsGeneric) {
 assert(DefinitionData && DefinitionData->IsLambda &&
"setting lambda property of non-lambda class");
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index cfc1c3b34947880..a5520e19a14327d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10145,6 +10145,8 @@ class Sema final {
 
   /// We are building deduction guides for a class.
   BuildingDeductionGuides,
+
+  TypeAliasTemplateInstantiation,
 } Kind;
 
 /// Was the enclosing context a non-instantiation SFINAE context?
@@ -10234,6 +10236,12 @@ class Sema final {
   FunctionDecl *Entity, ExceptionSpecification,
   SourceRange InstantiationRange = SourceRange());
 
+/// Note that we are instantiating a type alias template declaration.
+InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
+  TypeAliasTemplateDecl *Template,
+  ArrayRef TemplateArgs,
+  SourceRange InstantiationRange = SourceRange());
+
 /// Note that we are instantiating a default argument in a
 /// template-id.
 InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
diff --git a/clang/lib/Frontend/FrontendActions.cpp 
b/clang/lib/Frontend/FrontendActions.cpp
index 50338bfa670f830..5f0299dfa32e24b 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -452,6 +452,8 @@ class DefaultTemplateInstCallback : public 
TemplateInstantiationCallback {
   return "BuildingBuiltinDumpStructCall";
 case CodeSynthesisContext::BuildingDeductionGuides:
   return "BuildingDeductionGuides";
+case Sema::CodeSynthesisContext::TypeAliasTemplateInstantiation:
+  return "TypeAliasTemplateInstantiation";
 }
 return "";
   }
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index a8e387e35fb4c90..0b84d83b4fb4b81 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -615,14 +615,13 @@ bool Sema::SetupConstraintScope(
 // reference the original primary template.
 // We walk up the instantiated template chain so that nested lambdas get
 // handled properly.
-for (FunctionTemplateDecl *FromMemTempl =
- PrimaryTemplate->getInstantiatedFromMemberTemplate();
- FromMemTempl;
- FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate()) {
-  if (addInstantiatedParametersToScope(FD, 
FromMemTempl->getTemplatedDecl(),
-   Scope, MLTAL))
-return true;
-}
+FunctionTemplateDecl *FromMemTempl =
+PrimaryTemplate->getInstantiatedFromMemberTemplate();
+while (FromMemTempl && FromMemTempl->getInstantiatedFromMemberTemplate())
+  FromMemTempl = 

[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-12 Thread Qizhi Hu via cfe-commits

jcsxky wrote:

Probably I haven't understand these code deeply and I have some confusions on 
this patch. I wonder has this patch solved essential issue, or it just fixed 
the crash. I think some `static_assert` statements are required to demonstrate 
it does deduce the type of template parameters correctly.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-08 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 edited 
https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-08 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

So, I have:
1. rebased the patch on top of the recent Sema refactors.
2. incorporated the fix for https://github.com/llvm/llvm-project/issues/82104, 
which is a slight change on `HandleFunction`.
3. separated the `CodeSynthesisContext` iteration logic into three helper 
functions i.e. `getPrimaryTemplateOfGenericLambda`, 
`getEnclosingTypeAliasTemplateDecl` and `isLambdaEnclosedByTypeAliasDecl` - I 
hope this looks clearer.
4. clarified some comments.

In terms of the lambda dependencies, I'm not entirely sure if we can accept the 
current approach. In practice, it is possible to avoid such a hack at the 
moment, since we don't actually rely on the lambda substitution but rather the 
template arguments.

Do you think it will be useful in the future that we need something more e.g. 
the substituted parameters, to compute the dependency? @cor3ntin 

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-08 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll commented:

`Sema.h` changes look good to me.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-08 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/82310

>From f340fb3dd66e436566d5a65da0a35d77a6a0bde6 Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Tue, 20 Feb 2024 14:54:14 +0800
Subject: [PATCH 1/6] The lambda call inside of a type alias

---
 clang/docs/ReleaseNotes.rst   |  2 +
 clang/include/clang/AST/DeclCXX.h |  4 +
 clang/include/clang/Sema/Sema.h   |  8 ++
 clang/lib/Frontend/FrontendActions.cpp|  2 +
 clang/lib/Sema/SemaConcept.cpp| 15 ++--
 clang/lib/Sema/SemaTemplate.cpp   |  9 +-
 clang/lib/Sema/SemaTemplateInstantiate.cpp| 64 ++-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  5 ++
 clang/lib/Sema/TreeTransform.h|  9 ++
 .../alias-template-with-lambdas.cpp   | 82 +++
 10 files changed, 186 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/SemaTemplate/alias-template-with-lambdas.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1b901a27fd19d1..bfe00cb6b21ee6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -329,6 +329,8 @@ Bug Fixes to C++ Support
   when one of the function had more specialized templates.
   Fixes (`#82509 `_)
   and (`#74494 `_)
+- Clang now supports direct lambda calls inside of a type alias template 
declarations.
+  This addresses (#GH70601), (#GH76674), (#GH79555), (#GH81145) and so on.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 9cebaff63bb0db..7aed4d5cbc002e 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1869,6 +1869,10 @@ class CXXRecordDecl : public RecordDecl {
 DL.MethodTyInfo = TS;
   }
 
+  void setLambdaDependencyKind(unsigned Kind) {
+getLambdaData().DependencyKind = Kind;
+  }
+
   void setLambdaIsGeneric(bool IsGeneric) {
 assert(DefinitionData && DefinitionData->IsLambda &&
"setting lambda property of non-lambda class");
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 592c7871a4a55d..c6c40b1811442d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10131,6 +10131,8 @@ class Sema final {
 
   /// We are building deduction guides for a class.
   BuildingDeductionGuides,
+
+  TypeAliasTemplateInstantiation,
 } Kind;
 
 /// Was the enclosing context a non-instantiation SFINAE context?
@@ -10220,6 +10222,12 @@ class Sema final {
   FunctionDecl *Entity, ExceptionSpecification,
   SourceRange InstantiationRange = SourceRange());
 
+/// Note that we are instantiating a type alias template declaration.
+InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
+  TypeAliasTemplateDecl *Template,
+  ArrayRef TemplateArgs,
+  SourceRange InstantiationRange = SourceRange());
+
 /// Note that we are instantiating a default argument in a
 /// template-id.
 InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
diff --git a/clang/lib/Frontend/FrontendActions.cpp 
b/clang/lib/Frontend/FrontendActions.cpp
index b9ed5dedfa4223..43d6e2230fb129 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -426,6 +426,8 @@ class DefaultTemplateInstCallback : public 
TemplateInstantiationCallback {
   return "BuildingBuiltinDumpStructCall";
 case CodeSynthesisContext::BuildingDeductionGuides:
   return "BuildingDeductionGuides";
+case Sema::CodeSynthesisContext::TypeAliasTemplateInstantiation:
+  return "TypeAliasTemplateInstantiation";
 }
 return "";
   }
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 2878e4d31ee8fe..5cc6236c3991b6 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -614,14 +614,13 @@ bool Sema::SetupConstraintScope(
 // reference the original primary template.
 // We walk up the instantiated template chain so that nested lambdas get
 // handled properly.
-for (FunctionTemplateDecl *FromMemTempl =
- PrimaryTemplate->getInstantiatedFromMemberTemplate();
- FromMemTempl;
- FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate()) {
-  if (addInstantiatedParametersToScope(FD, 
FromMemTempl->getTemplatedDecl(),
-   Scope, MLTAL))
-return true;
-}
+FunctionTemplateDecl *FromMemTempl =
+PrimaryTemplate->getInstantiatedFromMemberTemplate();
+while (FromMemTempl && FromMemTempl->getInstantiatedFromMemberTemplate())
+  FromMemTempl = 

[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-08 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/82310

>From f340fb3dd66e436566d5a65da0a35d77a6a0bde6 Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Tue, 20 Feb 2024 14:54:14 +0800
Subject: [PATCH 1/5] The lambda call inside of a type alias

---
 clang/docs/ReleaseNotes.rst   |  2 +
 clang/include/clang/AST/DeclCXX.h |  4 +
 clang/include/clang/Sema/Sema.h   |  8 ++
 clang/lib/Frontend/FrontendActions.cpp|  2 +
 clang/lib/Sema/SemaConcept.cpp| 15 ++--
 clang/lib/Sema/SemaTemplate.cpp   |  9 +-
 clang/lib/Sema/SemaTemplateInstantiate.cpp| 64 ++-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  5 ++
 clang/lib/Sema/TreeTransform.h|  9 ++
 .../alias-template-with-lambdas.cpp   | 82 +++
 10 files changed, 186 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/SemaTemplate/alias-template-with-lambdas.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1b901a27fd19d1..bfe00cb6b21ee6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -329,6 +329,8 @@ Bug Fixes to C++ Support
   when one of the function had more specialized templates.
   Fixes (`#82509 `_)
   and (`#74494 `_)
+- Clang now supports direct lambda calls inside of a type alias template 
declarations.
+  This addresses (#GH70601), (#GH76674), (#GH79555), (#GH81145) and so on.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 9cebaff63bb0db..7aed4d5cbc002e 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1869,6 +1869,10 @@ class CXXRecordDecl : public RecordDecl {
 DL.MethodTyInfo = TS;
   }
 
+  void setLambdaDependencyKind(unsigned Kind) {
+getLambdaData().DependencyKind = Kind;
+  }
+
   void setLambdaIsGeneric(bool IsGeneric) {
 assert(DefinitionData && DefinitionData->IsLambda &&
"setting lambda property of non-lambda class");
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 592c7871a4a55d..c6c40b1811442d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10131,6 +10131,8 @@ class Sema final {
 
   /// We are building deduction guides for a class.
   BuildingDeductionGuides,
+
+  TypeAliasTemplateInstantiation,
 } Kind;
 
 /// Was the enclosing context a non-instantiation SFINAE context?
@@ -10220,6 +10222,12 @@ class Sema final {
   FunctionDecl *Entity, ExceptionSpecification,
   SourceRange InstantiationRange = SourceRange());
 
+/// Note that we are instantiating a type alias template declaration.
+InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
+  TypeAliasTemplateDecl *Template,
+  ArrayRef TemplateArgs,
+  SourceRange InstantiationRange = SourceRange());
+
 /// Note that we are instantiating a default argument in a
 /// template-id.
 InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
diff --git a/clang/lib/Frontend/FrontendActions.cpp 
b/clang/lib/Frontend/FrontendActions.cpp
index b9ed5dedfa4223..43d6e2230fb129 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -426,6 +426,8 @@ class DefaultTemplateInstCallback : public 
TemplateInstantiationCallback {
   return "BuildingBuiltinDumpStructCall";
 case CodeSynthesisContext::BuildingDeductionGuides:
   return "BuildingDeductionGuides";
+case Sema::CodeSynthesisContext::TypeAliasTemplateInstantiation:
+  return "TypeAliasTemplateInstantiation";
 }
 return "";
   }
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 2878e4d31ee8fe..5cc6236c3991b6 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -614,14 +614,13 @@ bool Sema::SetupConstraintScope(
 // reference the original primary template.
 // We walk up the instantiated template chain so that nested lambdas get
 // handled properly.
-for (FunctionTemplateDecl *FromMemTempl =
- PrimaryTemplate->getInstantiatedFromMemberTemplate();
- FromMemTempl;
- FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate()) {
-  if (addInstantiatedParametersToScope(FD, 
FromMemTempl->getTemplatedDecl(),
-   Scope, MLTAL))
-return true;
-}
+FunctionTemplateDecl *FromMemTempl =
+PrimaryTemplate->getInstantiatedFromMemberTemplate();
+while (FromMemTempl && FromMemTempl->getInstantiatedFromMemberTemplate())
+  FromMemTempl = 

[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-08 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/82310

>From f340fb3dd66e436566d5a65da0a35d77a6a0bde6 Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Tue, 20 Feb 2024 14:54:14 +0800
Subject: [PATCH 1/4] The lambda call inside of a type alias

---
 clang/docs/ReleaseNotes.rst   |  2 +
 clang/include/clang/AST/DeclCXX.h |  4 +
 clang/include/clang/Sema/Sema.h   |  8 ++
 clang/lib/Frontend/FrontendActions.cpp|  2 +
 clang/lib/Sema/SemaConcept.cpp| 15 ++--
 clang/lib/Sema/SemaTemplate.cpp   |  9 +-
 clang/lib/Sema/SemaTemplateInstantiate.cpp| 64 ++-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  5 ++
 clang/lib/Sema/TreeTransform.h|  9 ++
 .../alias-template-with-lambdas.cpp   | 82 +++
 10 files changed, 186 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/SemaTemplate/alias-template-with-lambdas.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1b901a27fd19d1..bfe00cb6b21ee6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -329,6 +329,8 @@ Bug Fixes to C++ Support
   when one of the function had more specialized templates.
   Fixes (`#82509 `_)
   and (`#74494 `_)
+- Clang now supports direct lambda calls inside of a type alias template 
declarations.
+  This addresses (#GH70601), (#GH76674), (#GH79555), (#GH81145) and so on.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 9cebaff63bb0db..7aed4d5cbc002e 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1869,6 +1869,10 @@ class CXXRecordDecl : public RecordDecl {
 DL.MethodTyInfo = TS;
   }
 
+  void setLambdaDependencyKind(unsigned Kind) {
+getLambdaData().DependencyKind = Kind;
+  }
+
   void setLambdaIsGeneric(bool IsGeneric) {
 assert(DefinitionData && DefinitionData->IsLambda &&
"setting lambda property of non-lambda class");
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 592c7871a4a55d..c6c40b1811442d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10131,6 +10131,8 @@ class Sema final {
 
   /// We are building deduction guides for a class.
   BuildingDeductionGuides,
+
+  TypeAliasTemplateInstantiation,
 } Kind;
 
 /// Was the enclosing context a non-instantiation SFINAE context?
@@ -10220,6 +10222,12 @@ class Sema final {
   FunctionDecl *Entity, ExceptionSpecification,
   SourceRange InstantiationRange = SourceRange());
 
+/// Note that we are instantiating a type alias template declaration.
+InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
+  TypeAliasTemplateDecl *Template,
+  ArrayRef TemplateArgs,
+  SourceRange InstantiationRange = SourceRange());
+
 /// Note that we are instantiating a default argument in a
 /// template-id.
 InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
diff --git a/clang/lib/Frontend/FrontendActions.cpp 
b/clang/lib/Frontend/FrontendActions.cpp
index b9ed5dedfa4223..43d6e2230fb129 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -426,6 +426,8 @@ class DefaultTemplateInstCallback : public 
TemplateInstantiationCallback {
   return "BuildingBuiltinDumpStructCall";
 case CodeSynthesisContext::BuildingDeductionGuides:
   return "BuildingDeductionGuides";
+case Sema::CodeSynthesisContext::TypeAliasTemplateInstantiation:
+  return "TypeAliasTemplateInstantiation";
 }
 return "";
   }
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 2878e4d31ee8fe..5cc6236c3991b6 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -614,14 +614,13 @@ bool Sema::SetupConstraintScope(
 // reference the original primary template.
 // We walk up the instantiated template chain so that nested lambdas get
 // handled properly.
-for (FunctionTemplateDecl *FromMemTempl =
- PrimaryTemplate->getInstantiatedFromMemberTemplate();
- FromMemTempl;
- FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate()) {
-  if (addInstantiatedParametersToScope(FD, 
FromMemTempl->getTemplatedDecl(),
-   Scope, MLTAL))
-return true;
-}
+FunctionTemplateDecl *FromMemTempl =
+PrimaryTemplate->getInstantiatedFromMemberTemplate();
+while (FromMemTempl && FromMemTempl->getInstantiatedFromMemberTemplate())
+  FromMemTempl = 

[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -13905,6 +13911,31 @@ TreeTransform::TransformLambdaExpr(LambdaExpr 
*E) {
 /*IsInstantiation*/ true);
   SavedContext.pop();
 
+  // Recompute the dependency of the lambda so that we can defer the lambda 
call
+  // construction until after we have sufficient template arguments. For
+  // example, template  struct S {
+  //   template 
+  //   using Type = decltype([](U){}(42.0));
+  // };
+  // void foo() {
+  //   using T = S::Type;
+  // ^~
+  // }
+  // We would end up here from instantiating the S as we're ensuring the
+  // completeness. That would make us transform the lambda call expression
+  // despite the fact that we don't see the argument for U yet. We have a
+  // mechanism that circumvents the semantic checking if the CallExpr is
+  // dependent. We can harness that by recomputing the lambda dependency from
+  // the instantiation arguments. I'm putting it here rather than the above
+  // since we can see transformed lambda parameters in case that they're
+  // useful for calculation.
+  DependencyKind = getDerived().ComputeLambdaDependency();
+  Class->setLambdaDependencyKind(DependencyKind);
+  // Clean up the type cache created previously. Then, we re-create a type for
+  // such Decl with the new DependencyKind.
+  Class->setTypeForDecl(nullptr);
+  getSema().Context.getTypeDeclType(Class);
+

cor3ntin wrote:

This is not great, but I am not sure how we can improve. 
I think it's worth a fixme
@erichkeane 

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -313,9 +313,75 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
 
   // This is to make sure we pick up the VarTemplateSpecializationDecl that 
this
   // lambda is defined inside of.
-  if (Rec->isLambda())
+  if (Rec->isLambda()) {
 if (const Decl *LCD = Rec->getLambdaContextDecl())
   return Response::ChangeDecl(LCD);
+// Attempt to retrieve the template arguments for a using alias 
declaration.
+// This is necessary for constraint checking, since we always keep
+// constraints relative to the primary template.
+if (ForConstraintInstantiation && !SemaRef.CodeSynthesisContexts.empty()) {
+  for (auto  : llvm::reverse(SemaRef.CodeSynthesisContexts)) {
+if (CSC.Kind != Sema::CodeSynthesisContext::SynthesisKind::
+TypeAliasTemplateInstantiation)
+  continue;
+auto *TATD = cast(CSC.Entity),
+ *CurrentTATD = TATD;
+FunctionDecl *LambdaCallOperator = Rec->getLambdaCallOperator();
+// Retrieve the 'primary' template for a lambda call operator. It's
+// unfortunate that we only have the mappings of call operators rather
+// than lambda classes.
+while (true) {
+  auto *FTD = dyn_cast_if_present(
+  LambdaCallOperator->getDescribedTemplate());
+  if (FTD && FTD->getInstantiatedFromMemberTemplate()) {
+LambdaCallOperator =
+FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
+  } else if (auto *Prev = cast(LambdaCallOperator)
+  ->getInstantiatedFromMemberFunction())
+LambdaCallOperator = Prev;
+  else
+break;
+}
+// Same applies for type alias Decl. We perform this to obtain the
+// "canonical" template parameter depths.
+while (TATD->getInstantiatedFromMemberTemplate())
+  TATD = TATD->getInstantiatedFromMemberTemplate();
+// Tell if we're currently inside of a lambda expression that is
+// surrounded by a using alias declaration. e.g.
+//   template  using type = decltype([](auto) { ^ }());
+// By checking if:
+//  1. The lambda expression and the using alias declaration share the
+//  same declaration context.
+//  2. They have the same template depth.
+// Then we assume the template arguments from the using alias
+// declaration are essential for constraint instantiation. We have to 
do
+// so since a TypeAliasTemplateDecl (or a TypeAliasDecl) is never a
+// DeclContext, nor does it have an associated specialization Decl from
+// which we could collect these template arguments.
+if (cast(LambdaCallOperator->getDeclContext())
+->getTemplateDepth() == TATD->getTemplateDepth() &&
+getLambdaAwareParentOfDeclContext(LambdaCallOperator) ==
+TATD->getDeclContext()) {
+  Result.addOuterTemplateArguments(CurrentTATD,
+   CSC.template_arguments(),
+   /*Final=*/false);
+  // Visit the parent of the current type alias declaration rather than
+  // the lambda thereof. We have the following case:

cor3ntin wrote:

```suggestion
  // Visit the parent of the current type alias declaration rather than
  // the lambda thereof. 
  E.g, in the following example:
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -13905,6 +13911,31 @@ TreeTransform::TransformLambdaExpr(LambdaExpr 
*E) {
 /*IsInstantiation*/ true);
   SavedContext.pop();
 
+  // Recompute the dependency of the lambda so that we can defer the lambda 
call
+  // construction until after we have sufficient template arguments. For
+  // example, template  struct S {
+  //   template 
+  //   using Type = decltype([](U){}(42.0));
+  // };
+  // void foo() {
+  //   using T = S::Type;
+  // ^~
+  // }
+  // We would end up here from instantiating the S as we're ensuring the
+  // completeness. That would make us transform the lambda call expression
+  // despite the fact that we don't see the argument for U yet. We have a

cor3ntin wrote:

```suggestion
  // We would end up here from instantiating S when ensuring its
  // completeness. That would make us transform the lambda call expression
  // despite the fact that we don't have a corresponding argument for U yet. We 
have a
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -313,9 +313,75 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
 
   // This is to make sure we pick up the VarTemplateSpecializationDecl that 
this
   // lambda is defined inside of.
-  if (Rec->isLambda())
+  if (Rec->isLambda()) {
 if (const Decl *LCD = Rec->getLambdaContextDecl())
   return Response::ChangeDecl(LCD);
+// Attempt to retrieve the template arguments for a using alias 
declaration.
+// This is necessary for constraint checking, since we always keep
+// constraints relative to the primary template.
+if (ForConstraintInstantiation && !SemaRef.CodeSynthesisContexts.empty()) {
+  for (auto  : llvm::reverse(SemaRef.CodeSynthesisContexts)) {
+if (CSC.Kind != Sema::CodeSynthesisContext::SynthesisKind::
+TypeAliasTemplateInstantiation)
+  continue;
+auto *TATD = cast(CSC.Entity),
+ *CurrentTATD = TATD;
+FunctionDecl *LambdaCallOperator = Rec->getLambdaCallOperator();
+// Retrieve the 'primary' template for a lambda call operator. It's
+// unfortunate that we only have the mappings of call operators rather
+// than lambda classes.
+while (true) {
+  auto *FTD = dyn_cast_if_present(
+  LambdaCallOperator->getDescribedTemplate());
+  if (FTD && FTD->getInstantiatedFromMemberTemplate()) {
+LambdaCallOperator =
+FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
+  } else if (auto *Prev = cast(LambdaCallOperator)
+  ->getInstantiatedFromMemberFunction())
+LambdaCallOperator = Prev;
+  else
+break;
+}
+// Same applies for type alias Decl. We perform this to obtain the
+// "canonical" template parameter depths.
+while (TATD->getInstantiatedFromMemberTemplate())
+  TATD = TATD->getInstantiatedFromMemberTemplate();
+// Tell if we're currently inside of a lambda expression that is
+// surrounded by a using alias declaration. e.g.
+//   template  using type = decltype([](auto) { ^ }());
+// By checking if:
+//  1. The lambda expression and the using alias declaration share the
+//  same declaration context.
+//  2. They have the same template depth.
+// Then we assume the template arguments from the using alias
+// declaration are essential for constraint instantiation. We have to 
do

cor3ntin wrote:

```suggestion
// Then we assume the template arguments of the using alias
// declaration are necessary for constraint instantiation. We have to do
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -614,6 +682,15 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
   PointOfInstantiation, InstantiationRange, Param, Template,
   TemplateArgs) {}
 
+Sema::InstantiatingTemplate::InstantiatingTemplate(
+Sema , SourceLocation PointOfInstantiation,
+TypeAliasTemplateDecl *Template, ArrayRef TemplateArgs,
+SourceRange InstantiationRange)
+: InstantiatingTemplate(
+  SemaRef, Sema::CodeSynthesisContext::TypeAliasTemplateInstantiation,
+  PointOfInstantiation, InstantiationRange, /*Entity=*/Template,
+  nullptr, TemplateArgs) {}

cor3ntin wrote:

Can you add a comment for the `nullptr`?

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -13905,6 +13911,31 @@ TreeTransform::TransformLambdaExpr(LambdaExpr 
*E) {
 /*IsInstantiation*/ true);
   SavedContext.pop();
 
+  // Recompute the dependency of the lambda so that we can defer the lambda 
call
+  // construction until after we have sufficient template arguments. For
+  // example, template  struct S {
+  //   template 

cor3ntin wrote:

```suggestion
  // example, given
  // template  struct S {
  //   template 
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -313,9 +313,75 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
 
   // This is to make sure we pick up the VarTemplateSpecializationDecl that 
this
   // lambda is defined inside of.
-  if (Rec->isLambda())
+  if (Rec->isLambda()) {
 if (const Decl *LCD = Rec->getLambdaContextDecl())
   return Response::ChangeDecl(LCD);
+// Attempt to retrieve the template arguments for a using alias 
declaration.
+// This is necessary for constraint checking, since we always keep
+// constraints relative to the primary template.
+if (ForConstraintInstantiation && !SemaRef.CodeSynthesisContexts.empty()) {
+  for (auto  : llvm::reverse(SemaRef.CodeSynthesisContexts)) {
+if (CSC.Kind != Sema::CodeSynthesisContext::SynthesisKind::
+TypeAliasTemplateInstantiation)
+  continue;
+auto *TATD = cast(CSC.Entity),
+ *CurrentTATD = TATD;
+FunctionDecl *LambdaCallOperator = Rec->getLambdaCallOperator();
+// Retrieve the 'primary' template for a lambda call operator. It's
+// unfortunate that we only have the mappings of call operators rather
+// than lambda classes.
+while (true) {
+  auto *FTD = dyn_cast_if_present(
+  LambdaCallOperator->getDescribedTemplate());
+  if (FTD && FTD->getInstantiatedFromMemberTemplate()) {
+LambdaCallOperator =
+FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
+  } else if (auto *Prev = cast(LambdaCallOperator)
+  ->getInstantiatedFromMemberFunction())
+LambdaCallOperator = Prev;
+  else
+break;
+}
+// Same applies for type alias Decl. We perform this to obtain the
+// "canonical" template parameter depths.

cor3ntin wrote:

```suggestion
// canonical template parameter depth.
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -313,9 +313,75 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
 
   // This is to make sure we pick up the VarTemplateSpecializationDecl that 
this
   // lambda is defined inside of.
-  if (Rec->isLambda())
+  if (Rec->isLambda()) {
 if (const Decl *LCD = Rec->getLambdaContextDecl())
   return Response::ChangeDecl(LCD);
+// Attempt to retrieve the template arguments for a using alias 
declaration.
+// This is necessary for constraint checking, since we always keep
+// constraints relative to the primary template.
+if (ForConstraintInstantiation && !SemaRef.CodeSynthesisContexts.empty()) {
+  for (auto  : llvm::reverse(SemaRef.CodeSynthesisContexts)) {
+if (CSC.Kind != Sema::CodeSynthesisContext::SynthesisKind::
+TypeAliasTemplateInstantiation)
+  continue;
+auto *TATD = cast(CSC.Entity),
+ *CurrentTATD = TATD;
+FunctionDecl *LambdaCallOperator = Rec->getLambdaCallOperator();
+// Retrieve the 'primary' template for a lambda call operator. It's
+// unfortunate that we only have the mappings of call operators rather
+// than lambda classes.
+while (true) {
+  auto *FTD = dyn_cast_if_present(
+  LambdaCallOperator->getDescribedTemplate());
+  if (FTD && FTD->getInstantiatedFromMemberTemplate()) {
+LambdaCallOperator =
+FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
+  } else if (auto *Prev = cast(LambdaCallOperator)
+  ->getInstantiatedFromMemberFunction())
+LambdaCallOperator = Prev;
+  else
+break;
+}
+// Same applies for type alias Decl. We perform this to obtain the
+// "canonical" template parameter depths.
+while (TATD->getInstantiatedFromMemberTemplate())
+  TATD = TATD->getInstantiatedFromMemberTemplate();
+// Tell if we're currently inside of a lambda expression that is

cor3ntin wrote:

```suggestion
// Check if we are currently inside of a lambda expression that is
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -13905,6 +13911,31 @@ TreeTransform::TransformLambdaExpr(LambdaExpr 
*E) {
 /*IsInstantiation*/ true);
   SavedContext.pop();
 
+  // Recompute the dependency of the lambda so that we can defer the lambda 
call
+  // construction until after we have sufficient template arguments. For

cor3ntin wrote:

```suggestion
  // construction until after we have all the necessary template arguments. For
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -313,9 +313,75 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
 
   // This is to make sure we pick up the VarTemplateSpecializationDecl that 
this
   // lambda is defined inside of.
-  if (Rec->isLambda())
+  if (Rec->isLambda()) {
 if (const Decl *LCD = Rec->getLambdaContextDecl())
   return Response::ChangeDecl(LCD);
+// Attempt to retrieve the template arguments for a using alias 
declaration.
+// This is necessary for constraint checking, since we always keep
+// constraints relative to the primary template.
+if (ForConstraintInstantiation && !SemaRef.CodeSynthesisContexts.empty()) {
+  for (auto  : llvm::reverse(SemaRef.CodeSynthesisContexts)) {
+if (CSC.Kind != Sema::CodeSynthesisContext::SynthesisKind::
+TypeAliasTemplateInstantiation)
+  continue;
+auto *TATD = cast(CSC.Entity),
+ *CurrentTATD = TATD;
+FunctionDecl *LambdaCallOperator = Rec->getLambdaCallOperator();
+// Retrieve the 'primary' template for a lambda call operator. It's
+// unfortunate that we only have the mappings of call operators rather
+// than lambda classes.
+while (true) {
+  auto *FTD = dyn_cast_if_present(
+  LambdaCallOperator->getDescribedTemplate());
+  if (FTD && FTD->getInstantiatedFromMemberTemplate()) {
+LambdaCallOperator =
+FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
+  } else if (auto *Prev = cast(LambdaCallOperator)
+  ->getInstantiatedFromMemberFunction())
+LambdaCallOperator = Prev;
+  else
+break;
+}
+// Same applies for type alias Decl. We perform this to obtain the
+// "canonical" template parameter depths.
+while (TATD->getInstantiatedFromMemberTemplate())
+  TATD = TATD->getInstantiatedFromMemberTemplate();
+// Tell if we're currently inside of a lambda expression that is
+// surrounded by a using alias declaration. e.g.
+//   template  using type = decltype([](auto) { ^ }());
+// By checking if:
+//  1. The lambda expression and the using alias declaration share the
+//  same declaration context.
+//  2. They have the same template depth.
+// Then we assume the template arguments from the using alias
+// declaration are essential for constraint instantiation. We have to 
do
+// so since a TypeAliasTemplateDecl (or a TypeAliasDecl) is never a
+// DeclContext, nor does it have an associated specialization Decl from
+// which we could collect these template arguments.
+if (cast(LambdaCallOperator->getDeclContext())
+->getTemplateDepth() == TATD->getTemplateDepth() &&
+getLambdaAwareParentOfDeclContext(LambdaCallOperator) ==
+TATD->getDeclContext()) {
+  Result.addOuterTemplateArguments(CurrentTATD,
+   CSC.template_arguments(),
+   /*Final=*/false);
+  // Visit the parent of the current type alias declaration rather than
+  // the lambda thereof. We have the following case:
+  // struct S {
+  //  template  using T = decltype([] {} ());
+  // };
+  // void foo() {
+  //   S::T var;
+  // }
+  // The instantiated lambda expression (which we're visiting at 'var')
+  // has a function DeclContext 'foo' rather than the Record 
DeclContext
+  // S. This seems to be an oversight that we may want to set a Sema
+  // Context from the CXXScopeSpec before substituting into T to me.

cor3ntin wrote:

@erichkeane Opinion?

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -313,9 +313,75 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
 
   // This is to make sure we pick up the VarTemplateSpecializationDecl that 
this
   // lambda is defined inside of.
-  if (Rec->isLambda())
+  if (Rec->isLambda()) {
 if (const Decl *LCD = Rec->getLambdaContextDecl())
   return Response::ChangeDecl(LCD);
+// Attempt to retrieve the template arguments for a using alias 
declaration.
+// This is necessary for constraint checking, since we always keep
+// constraints relative to the primary template.
+if (ForConstraintInstantiation && !SemaRef.CodeSynthesisContexts.empty()) {
+  for (auto  : llvm::reverse(SemaRef.CodeSynthesisContexts)) {
+if (CSC.Kind != Sema::CodeSynthesisContext::SynthesisKind::
+TypeAliasTemplateInstantiation)
+  continue;
+auto *TATD = cast(CSC.Entity),
+ *CurrentTATD = TATD;
+FunctionDecl *LambdaCallOperator = Rec->getLambdaCallOperator();
+// Retrieve the 'primary' template for a lambda call operator. It's
+// unfortunate that we only have the mappings of call operators rather
+// than lambda classes.
+while (true) {
+  auto *FTD = dyn_cast_if_present(
+  LambdaCallOperator->getDescribedTemplate());
+  if (FTD && FTD->getInstantiatedFromMemberTemplate()) {
+LambdaCallOperator =
+FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
+  } else if (auto *Prev = cast(LambdaCallOperator)
+  ->getInstantiatedFromMemberFunction())
+LambdaCallOperator = Prev;
+  else
+break;
+}

cor3ntin wrote:

```suggestion
  if (auto *FTD = dyn_cast_if_present(
  LambdaCallOperator->getDescribedTemplate(); FTD && 
FTD->getInstantiatedFromMemberTemplate()) {
LambdaCallOperator =
FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
  } else if (auto *Prev = cast(LambdaCallOperator)
  ->getInstantiatedFromMemberFunction())
LambdaCallOperator = Prev;
  else
break;
}
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -313,9 +313,75 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
 
   // This is to make sure we pick up the VarTemplateSpecializationDecl that 
this
   // lambda is defined inside of.
-  if (Rec->isLambda())
+  if (Rec->isLambda()) {
 if (const Decl *LCD = Rec->getLambdaContextDecl())
   return Response::ChangeDecl(LCD);
+// Attempt to retrieve the template arguments for a using alias 
declaration.
+// This is necessary for constraint checking, since we always keep
+// constraints relative to the primary template.
+if (ForConstraintInstantiation && !SemaRef.CodeSynthesisContexts.empty()) {

cor3ntin wrote:

```suggestion
if (ForConstraintInstantiation) {
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -614,10 +614,14 @@ bool Sema::SetupConstraintScope(
 // reference the original primary template.
 // We walk up the instantiated template chain so that nested lambdas get
 // handled properly.
-for (FunctionTemplateDecl *FromMemTempl =
- PrimaryTemplate->getInstantiatedFromMemberTemplate();
- FromMemTempl;
- FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate()) {
+// Note that we shall not collect instantiated parameters from
+// 'intermediate' transformed function templates but the primary template
+// for which we have built up the template arguments relative to. 
Otherwise,
+// we may have mismatched template parameter depth!

cor3ntin wrote:

```suggestion
// We should only collect instantiated parameters from 
// the primary template. Otherwise, we may have mismatched template 
parameter depth!
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -313,9 +313,75 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
 
   // This is to make sure we pick up the VarTemplateSpecializationDecl that 
this
   // lambda is defined inside of.
-  if (Rec->isLambda())
+  if (Rec->isLambda()) {
 if (const Decl *LCD = Rec->getLambdaContextDecl())
   return Response::ChangeDecl(LCD);
+// Attempt to retrieve the template arguments for a using alias 
declaration.

cor3ntin wrote:

```suggestion
// Retrieve the template arguments for a using alias declaration.
```

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-03-05 Thread via cfe-commits


@@ -313,9 +313,75 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
 
   // This is to make sure we pick up the VarTemplateSpecializationDecl that 
this
   // lambda is defined inside of.
-  if (Rec->isLambda())
+  if (Rec->isLambda()) {
 if (const Decl *LCD = Rec->getLambdaContextDecl())
   return Response::ChangeDecl(LCD);
+// Attempt to retrieve the template arguments for a using alias 
declaration.
+// This is necessary for constraint checking, since we always keep
+// constraints relative to the primary template.
+if (ForConstraintInstantiation && !SemaRef.CodeSynthesisContexts.empty()) {
+  for (auto  : llvm::reverse(SemaRef.CodeSynthesisContexts)) {
+if (CSC.Kind != Sema::CodeSynthesisContext::SynthesisKind::
+TypeAliasTemplateInstantiation)
+  continue;
+auto *TATD = cast(CSC.Entity),
+ *CurrentTATD = TATD;
+FunctionDecl *LambdaCallOperator = Rec->getLambdaCallOperator();
+// Retrieve the 'primary' template for a lambda call operator. It's
+// unfortunate that we only have the mappings of call operators rather
+// than lambda classes.
+while (true) {
+  auto *FTD = dyn_cast_if_present(
+  LambdaCallOperator->getDescribedTemplate());
+  if (FTD && FTD->getInstantiatedFromMemberTemplate()) {
+LambdaCallOperator =
+FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
+  } else if (auto *Prev = cast(LambdaCallOperator)
+  ->getInstantiatedFromMemberFunction())
+LambdaCallOperator = Prev;
+  else
+break;
+}
+// Same applies for type alias Decl. We perform this to obtain the

cor3ntin wrote:

> Same applies for type alias Decl

I'm not sure I understand this comment. What does "Same" refer to? Can you 
rephrase?

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-02-28 Thread Erich Keane via cfe-commits

https://github.com/erichkeane commented:

I don't have any concerns, but want @cor3ntin to take a look.  He's under the 
weather at the moment, so he might be a few days.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-02-28 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

Friendly ping. I'm looking for your feedback before fixing other similar bugs, 
e.g. #82104.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-02-20 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

Although this patch doesn't fix 
https://github.com/llvm/llvm-project/issues/82104 yet, which is a crash caused 
by a mismatch in the template argument during the return type deduction, I 
still tried a temporary workaround (turning some switches off / on for 
getTemplateInstantiationArgs), and that proves we can move forward the fix with 
this patch.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-02-20 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/82310

>From 0f97fae5d1ba4debe04824e5d2d98598504d003d Mon Sep 17 00:00:00 2001
From: Younan Zhang 
Date: Tue, 20 Feb 2024 14:54:14 +0800
Subject: [PATCH 1/3] The lambda call inside of a type alias

---
 clang/docs/ReleaseNotes.rst   |  5 ++
 clang/include/clang/AST/DeclCXX.h |  4 +
 clang/include/clang/Sema/Sema.h   |  8 ++
 clang/lib/Frontend/FrontendActions.cpp|  2 +
 clang/lib/Sema/SemaConcept.cpp| 15 ++--
 clang/lib/Sema/SemaTemplate.cpp   |  9 +-
 clang/lib/Sema/SemaTemplateInstantiate.cpp| 64 ++-
 .../lib/Sema/SemaTemplateInstantiateDecl.cpp  |  5 ++
 clang/lib/Sema/TreeTransform.h|  9 ++
 .../alias-template-with-lambdas.cpp   | 82 +++
 10 files changed, 189 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/SemaTemplate/alias-template-with-lambdas.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 649ad655905af2..7988912faa2075 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -267,6 +267,11 @@ Bug Fixes to C++ Support
   was only accepted at namespace scope but not at local function scope.
 - Clang no longer tries to call consteval constructors at runtime when they 
appear in a member initializer.
   (`#782154 `_`)
+- Clang now supports direct lambda calls inside of a type alias template 
declarations.
+  This addresses (`#70601 
`_),
+  (`#76674 `_),
+  (`#79555 `_),
+  (`#81145 `_), and so on.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 9cebaff63bb0db..7aed4d5cbc002e 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1869,6 +1869,10 @@ class CXXRecordDecl : public RecordDecl {
 DL.MethodTyInfo = TS;
   }
 
+  void setLambdaDependencyKind(unsigned Kind) {
+getLambdaData().DependencyKind = Kind;
+  }
+
   void setLambdaIsGeneric(bool IsGeneric) {
 assert(DefinitionData && DefinitionData->IsLambda &&
"setting lambda property of non-lambda class");
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e9cd42ae777df5..488d2e07a2732e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9622,6 +9622,8 @@ class Sema final {
 
   /// We are building deduction guides for a class.
   BuildingDeductionGuides,
+
+  TypeAliasTemplateInstantiation,
 } Kind;
 
 /// Was the enclosing context a non-instantiation SFINAE context?
@@ -9812,6 +9814,12 @@ class Sema final {
   FunctionDecl *Entity, ExceptionSpecification,
   SourceRange InstantiationRange = SourceRange());
 
+/// Note that we are instantiating a type alias template declaration.
+InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
+  TypeAliasTemplateDecl *Template,
+  ArrayRef TemplateArgs,
+  SourceRange InstantiationRange = SourceRange());
+
 /// Note that we are instantiating a default argument in a
 /// template-id.
 InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
diff --git a/clang/lib/Frontend/FrontendActions.cpp 
b/clang/lib/Frontend/FrontendActions.cpp
index b9ed5dedfa4223..43d6e2230fb129 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -426,6 +426,8 @@ class DefaultTemplateInstCallback : public 
TemplateInstantiationCallback {
   return "BuildingBuiltinDumpStructCall";
 case CodeSynthesisContext::BuildingDeductionGuides:
   return "BuildingDeductionGuides";
+case Sema::CodeSynthesisContext::TypeAliasTemplateInstantiation:
+  return "TypeAliasTemplateInstantiation";
 }
 return "";
   }
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 2878e4d31ee8fe..5cc6236c3991b6 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -614,14 +614,13 @@ bool Sema::SetupConstraintScope(
 // reference the original primary template.
 // We walk up the instantiated template chain so that nested lambdas get
 // handled properly.
-for (FunctionTemplateDecl *FromMemTempl =
- PrimaryTemplate->getInstantiatedFromMemberTemplate();
- FromMemTempl;
- FromMemTempl = FromMemTempl->getInstantiatedFromMemberTemplate()) {
-  if (addInstantiatedParametersToScope(FD, 
FromMemTempl->getTemplatedDecl(),
-   Scope, 

[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-02-20 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

Also added @shafik for some insights on tests / other existing issues.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-02-20 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 edited 
https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-02-20 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Younan Zhang (zyn0217)


Changes

This patch attempts to fix the lambda call expression inside of a type alias 
declaration from two aspects:
1. Defer the lambda call expression building until after we have sufficient 
template arguments. This avoids the overeager (and often wrong) semantic 
checking before the type alias instantiation.
2. Properly obtain template arguments involving a template type alias for 
constraint checking.

It is unfortunate that a `TypeAliasTemplateDecl` (or a `TypeAliasDecl`) is 
never a `DeclContext`, nor does it have an associated specialization Decl from 
which we could collect these template arguments. Thus, I added a new 
CodeSynthesisContext to record template arguments for alias declarations.

Fixes https://github.com/llvm/llvm-project/issues/70601
Fixes https://github.com/llvm/llvm-project/issues/76674
Fixes https://github.com/llvm/llvm-project/issues/79555
Fixes https://github.com/llvm/llvm-project/issues/81145

Note that this doesn't involve the fix for 
https://github.com/llvm/llvm-project/issues/23317. That seems different, and 
I'd like to leave it as a follow-up.

---
Full diff: https://github.com/llvm/llvm-project/pull/82310.diff


10 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+5) 
- (modified) clang/include/clang/AST/DeclCXX.h (+4) 
- (modified) clang/include/clang/Sema/Sema.h (+9) 
- (modified) clang/lib/Frontend/FrontendActions.cpp (+2) 
- (modified) clang/lib/Sema/SemaConcept.cpp (+8-4) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+7-3) 
- (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+95-3) 
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+5) 
- (modified) clang/lib/Sema/TreeTransform.h (+31) 
- (added) clang/test/SemaTemplate/alias-template-with-lambdas.cpp (+82) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 649ad655905af2..7988912faa2075 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -267,6 +267,11 @@ Bug Fixes to C++ Support
   was only accepted at namespace scope but not at local function scope.
 - Clang no longer tries to call consteval constructors at runtime when they 
appear in a member initializer.
   (`#782154 `_`)
+- Clang now supports direct lambda calls inside of a type alias template 
declarations.
+  This addresses (`#70601 
`_),
+  (`#76674 `_),
+  (`#79555 `_),
+  (`#81145 `_), and so on.
 
 Bug Fixes to AST Handling
 ^
diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index 9cebaff63bb0db..7aed4d5cbc002e 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1869,6 +1869,10 @@ class CXXRecordDecl : public RecordDecl {
 DL.MethodTyInfo = TS;
   }
 
+  void setLambdaDependencyKind(unsigned Kind) {
+getLambdaData().DependencyKind = Kind;
+  }
+
   void setLambdaIsGeneric(bool IsGeneric) {
 assert(DefinitionData && DefinitionData->IsLambda &&
"setting lambda property of non-lambda class");
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e9cd42ae777df5..5847b0301a4ca4 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9622,6 +9622,9 @@ class Sema final {
 
   /// We are building deduction guides for a class.
   BuildingDeductionGuides,
+
+  /// We are instantiating a type alias template declaration.
+  TypeAliasTemplateInstantiation,
 } Kind;
 
 /// Was the enclosing context a non-instantiation SFINAE context?
@@ -9812,6 +9815,12 @@ class Sema final {
   FunctionDecl *Entity, ExceptionSpecification,
   SourceRange InstantiationRange = SourceRange());
 
+/// Note that we are instantiating a type alias template declaration.
+InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
+  TypeAliasTemplateDecl *Template,
+  ArrayRef TemplateArgs,
+  SourceRange InstantiationRange = SourceRange());
+
 /// Note that we are instantiating a default argument in a
 /// template-id.
 InstantiatingTemplate(Sema , SourceLocation PointOfInstantiation,
diff --git a/clang/lib/Frontend/FrontendActions.cpp 
b/clang/lib/Frontend/FrontendActions.cpp
index b9ed5dedfa4223..43d6e2230fb129 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -426,6 +426,8 @@ class DefaultTemplateInstCallback : public 
TemplateInstantiationCallback {
   return "BuildingBuiltinDumpStructCall";
 case CodeSynthesisContext::BuildingDeductionGuides:
   

[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-02-20 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 ready_for_review 
https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-02-20 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

Result for libc++ tests:
```

Failed Tests (1):
  llvm-libc++-shared.cfg.in :: libcxx/headers_in_modulemap.sh.py


Testing Time: 1232.89s

Total Discovered Tests: 9673
  Unsupported  :  585 (6.05%)
  Passed   : 9062 (93.68%)
  Expectedly Failed:   25 (0.26%)
  Failed   :1 (0.01%)
```

The failing test seems to be my local configuration issue and doesn't relate to 
this patch IIUC.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-02-20 Thread Younan Zhang via cfe-commits

zyn0217 wrote:

The Windows CI is still broken and I have to run the libc++ tests locally.

https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema] Fix the lambda call expression inside of a type alias declaration (PR #82310)

2024-02-20 Thread Younan Zhang via cfe-commits

https://github.com/zyn0217 edited 
https://github.com/llvm/llvm-project/pull/82310
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits