[clang] [clang] deprecate frelaxed-template-template-args, make it on by default (PR #89807)

Matheus Izvekov via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 24 10:09:51 PDT 2024


================
@@ -507,10 +507,62 @@ static TemplateDeductionResult DeduceNonTypeTemplateArgument(
       S, TemplateParams, NTTP, DeducedTemplateArgument(New), T, Info, Deduced);
 }
 
+static NamedDecl *DeduceTemplateArguments(Sema &S, NamedDecl *A,
+                                          TemplateArgument Default) {
+  switch (A->getKind()) {
+  case Decl::TemplateTypeParm: {
+    auto *T = cast<TemplateTypeParmDecl>(A);
+    // FIXME: DefaultArgument can't represent a pack.
+    if (T->isParameterPack())
+      return A;
+    auto *R = TemplateTypeParmDecl::Create(
+        S.Context, A->getDeclContext(), SourceLocation(), SourceLocation(),
+        T->getDepth(), T->getIndex(), T->getIdentifier(),
+        T->wasDeclaredWithTypename(), /*ParameterPack=*/false,
+        T->hasTypeConstraint());
+    R->setDefaultArgument(
+        S.Context.getTrivialTypeSourceInfo(Default.getAsType()));
+    if (R->hasTypeConstraint()) {
+      auto *C = R->getTypeConstraint();
+      R->setTypeConstraint(C->getConceptReference(),
+                           C->getImmediatelyDeclaredConstraint());
+    }
+    return R;
+  }
+  case Decl::NonTypeTemplateParm: {
+    auto *T = cast<NonTypeTemplateParmDecl>(A);
+    // FIXME: DefaultArgument can't represent a pack.
+    if (T->isParameterPack())
+      return A;
+    auto *R = NonTypeTemplateParmDecl::Create(
+        S.Context, A->getDeclContext(), SourceLocation(), SourceLocation(),
+        T->getDepth(), T->getIndex(), T->getIdentifier(), T->getType(),
+        /*ParameterPack=*/false, T->getTypeSourceInfo());
+    R->setDefaultArgument(Default.getAsExpr());
+    if (auto *PTC = T->getPlaceholderTypeConstraint())
+      R->setPlaceholderTypeConstraint(PTC);
+    return R;
+  }
+  case Decl::TemplateTemplateParm: {
----------------
mizvekov wrote:

A template template parameter can have a template template parameter as a parameter. These parameters can have default arguments too.

I thought I saw this test case covered in the clang test suite, but I was mistaken.

Here is one example test that will hit this case:
```C++
template <class> struct X {};

template<class T1, template <class T7> class T2 = X> struct A {};

template<class T3> struct B {};

template<template<class> class TT1, class T4> struct B<TT1<T4>>; // #1
template<template<class, template <class T8> class> class TT2, class T5, template <class T7> class T6> struct B<TT2<T5, T6>> {}; // #2

template struct B<A<int>>;
```

https://github.com/llvm/llvm-project/pull/89807


More information about the cfe-commits mailing list