================
@@ -2744,31 +2744,155 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, 
DeclContext *DC) {
   return false;
 }
 
+unsigned getTemplateDepth(NamedDecl *TemplateParam) {
+  if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
+    return TTP->getDepth();
+  if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
+    return TTP->getDepth();
+  if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
+    return NTTP->getDepth();
+  llvm_unreachable("Unhandled template parameter types");
+}
+
 NamedDecl *transformTemplateParameter(Sema &SemaRef, DeclContext *DC,
                                       NamedDecl *TemplateParam,
                                       MultiLevelTemplateArgumentList &Args,
-                                      unsigned NewIndex) {
+                                      unsigned NewIndex, unsigned NewDepth) {
   if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
-    return transformTemplateTypeParam(SemaRef, DC, TTP, Args, TTP->getDepth(),
+    return transformTemplateTypeParam(SemaRef, DC, TTP, Args, NewDepth,
                                       NewIndex);
   if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
     return transformTemplateParam(SemaRef, DC, TTP, Args, NewIndex,
-                                  TTP->getDepth());
+                                  NewDepth);
   if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
     return transformTemplateParam(SemaRef, DC, NTTP, Args, NewIndex,
-                                  NTTP->getDepth());
+                                  NewDepth);
   llvm_unreachable("Unhandled template parameter types");
 }
 
-Expr *transformRequireClause(Sema &SemaRef, FunctionTemplateDecl *FTD,
-                             llvm::ArrayRef<TemplateArgument> TransformedArgs) 
{
-  Expr *RC = FTD->getTemplateParameters()->getRequiresClause();
+// Transform the require-clause of F if any.
+// The return result is expected to be the require-clause for the synthesized
+// alias deduction guide.
+Expr *transformRequireClause(
+    Sema &SemaRef, FunctionTemplateDecl *F,
+    TypeAliasTemplateDecl *AliasTemplate,
+    ArrayRef<DeducedTemplateArgument> DeduceResults) {
+  Expr *RC = F->getTemplateParameters()->getRequiresClause();
   if (!RC)
     return nullptr;
+
+  auto &Context = SemaRef.Context;
+  LocalInstantiationScope Scope(SemaRef);
+
+  // In the clang AST, constraint nodes are not instantiated at all unless they
+  // are being evaluated. This means that occurrences of template parameters
+  // in the require-clause expr have subtle differences compared to occurrences
+  // in other places, such as function parameters. When transforming the
+  // require-clause, we must respect these differences, particularly regarding
+  // the 'depth' information:
+  //   1) In the transformed require-clause, occurrences of template parameters
+  //   must use the "uninstantiated" depth;
+  //   2) When substituting on the require-clause expr of the underlying
+  //   deduction guide, we must use the entire set of template argument lists.
+  //
+  // It's important to note that we're performing this transformation on an
+  // *instantiated* AliasTemplate.
+
+  // For 1), if the alias template is nested within a class template, we
+  // calcualte the 'uninstantiated' depth by adding the substitution level 
back.
+  unsigned AdjustDepth = 0;
+  if (auto *PrimaryTemplate = 
AliasTemplate->getInstantiatedFromMemberTemplate())
----------------
hokein wrote:

I've noticed that there are several places 
(e.g.,[1](https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaTemplate.cpp#L2374),
 
[2](https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/DeclCXX.cpp#L1943),
 
[3](https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/Decl.cpp#L4149))
 where we use a while-loop to retrieve the primary template. However, I'm not 
entirely clear on the rationale behind it. It appears that using 
`getInstantiatedFromMemberTemplate()` consistently provides the correct result 
for all cases I came up with. Interestingly, removing the while-loop from all 
occurrences [1], [2], [3] doesn't trigger any test failures on `check-clang`.

https://github.com/llvm/llvm-project/pull/90961
_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to