[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 12 01:00:25 PDT 2024


================
@@ -139,28 +165,61 @@ TemplateName::NameKind TemplateName::getKind() const {
     return AssumedTemplate;
   if (uncommon->getAsSubstTemplateTemplateParm())
     return SubstTemplateTemplateParm;
+  if (uncommon->getAsDeducedTemplateName())
+    return DeducedTemplate;
+
+  assert(uncommon->getAsSubstTemplateTemplateParmPack() != nullptr);
   return SubstTemplateTemplateParmPack;
 }
 
 TemplateDecl *TemplateName::getAsTemplateDecl() const {
-  if (Decl *TemplateOrUsing = Storage.dyn_cast<Decl *>()) {
-    if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(TemplateOrUsing))
-      return cast<TemplateDecl>(USD->getTargetDecl());
+  TemplateName Name = *this;
+  while (std::optional<TemplateName> UnderlyingOrNone =
+             Name.desugar(/*IgnoreDeduced=*/false))
+    Name = *UnderlyingOrNone;
 
-    assert(isa<TemplateDecl>(TemplateOrUsing));
+  if (Decl *TemplateOrUsing = Name.Storage.dyn_cast<Decl *>())
     return cast<TemplateDecl>(TemplateOrUsing);
+  return nullptr;
+}
+
+std::pair<TemplateDecl *, DefaultArguments>
+TemplateName::getTemplateDeclAndDefaultArgs() const {
+  DefaultArguments DefArgs;
+  for (TemplateName Name = *this; /**/; /**/) {
+    if (!DefArgs && Name.getKind() == TemplateName::DeducedTemplate) {
+      DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+      Name = DTS->getUnderlying();
+      DefArgs = DTS->getDefaultArguments();
+      continue;
+    }
+    if (std::optional<TemplateName> UnderlyingOrNone =
+            Name.desugar(/*IgnoreDeduced=*/DefArgs)) {
+      Name = *UnderlyingOrNone;
+      continue;
+    }
+    TemplateDecl *TD = Name.getAsTemplateDecl();
+    if (TD && DefArgs != 0)
+      assert(DefArgs.StartPos + DefArgs.Args.size() <=
+             TD->getTemplateParameters()->size());
+    return {TD, DefArgs};
   }
+}
----------------
cor3ntin wrote:

This is too clever.

I'd do

```cpp
static std::pair<TemplateDecl *, DefaultArguments>
getTemplateDeclAndDefaultArgs(const TemplateName N&,  DefaultArguments Args) {
    if(...) {
        return getTemplateDeclAndDefaultArgs(DTS->getUnderlying(), DTS->getDefaultArguments()) ;
    }
   // ...
}

std::pair<TemplateDecl *, DefaultArguments>
TemplateName::getTemplateDeclAndDefaultArgs() const {
    return getTemplateDeclAndDefaultArgs(*this, {});
}

```





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


More information about the cfe-commits mailing list