[clang] [Clang][C++26] Implement P3865R1 - CTAD for type template template parameters (PR #191409)

Oliver Hunt via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 15 11:09:59 PDT 2026


================
@@ -1604,3 +1604,60 @@ void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
 
   SavedContext.pop();
 }
+
+TypeAliasTemplateDecl *Sema::BuildAliasForCTADFromTypeTemplateParameter(
+    TemplateTemplateParmDecl *D, TemplateName Replacement, SourceLocation Loc) {
+
+  // [C++26] [over.match.class.deduct]p3
+  // When resolving a placeholder for a deduced class type where the
+  // template-name designates a type template template parameter P, let A be an
+  // alias template whose template parameter list is that of P and whose
+  // defining-type-id designates the type template template argument with a
+  // simpletemplate-id in which the template-argument-list consists of a list of
+  // identifiers naming each template-parameter of P, with the argument being a
+  // pack expansion if the template-parameter is a pack. A is then used instead
+  // of the original template-name to resolve the placeholder
+
+  LocalInstantiationScope Scope(SemaRef);
+
+  auto &AST = SemaRef.getASTContext();
+  auto *Ctx = CurContext->getParent();
+
+  MultiLevelTemplateArgumentList MTAL;
+  if (NamedDecl *Func = dyn_cast<NamedDecl>(CurContext))
+    MTAL = SemaRef.getTemplateInstantiationArgs(Func);
+
+  llvm::SmallVector<NamedDecl *> Parameters;
+  llvm::SmallVector<TemplateArgument> Args;
+  for (NamedDecl *P : D->getTemplateParameters()->asArray()) {
+    auto [Depth, Index] = getDepthAndIndex(P);
+    NamedDecl *NewParam =
+        transformTemplateParameter(*this, Ctx, P, MTAL, Index, Depth - 1);
+    if (!NewParam)
+      return nullptr;
+    Parameters.push_back(NewParam);
+    Args.push_back(SemaRef.Context.getInjectedTemplateArg(NewParam));
+  }
+
+  auto *ParamList =
+      TemplateParameterList::Create(AST, SourceLocation(), SourceLocation(),
+                                    Parameters, SourceLocation(), nullptr);
+
+  QualType Type = AST.getCanonicalType(AST.getTemplateSpecializationType(
+      ElaboratedTypeKeyword::Class, Replacement, Args, {}));
+
+  auto *Alias = TypeAliasDecl::Create(AST, Ctx, Loc, SourceLocation(), nullptr,
----------------
ojhunt wrote:

`/*ParameterNameHere=*/` :D (payback for all the time you forced me to make my code readable with this :D) 

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


More information about the cfe-commits mailing list