[clang] [clang-tools-extra] [clang] Implement CWG2398 provisional TTP matching to class templates (PR #94981)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 5 09:50:36 PDT 2024
================
@@ -139,28 +165,63 @@ 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());
-
- assert(isa<TemplateDecl>(TemplateOrUsing));
- return cast<TemplateDecl>(TemplateOrUsing);
- }
+TemplateDecl *TemplateName::getAsTemplateDecl(bool IgnoreDeduced) const {
+ TemplateName Name = *this;
+ while (std::optional<TemplateName> UnderlyingOrNone =
+ Name.desugar(IgnoreDeduced))
+ Name = *UnderlyingOrNone;
- if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
- return QTN->getUnderlyingTemplate().getAsTemplateDecl();
+ if (!IgnoreDeduced)
+ assert(Name.getAsDeducedTemplateName() == nullptr &&
+ "Unexpected canonical DeducedTemplateName; Did you mean to use "
+ "getTemplateDeclAndDefaultArgs instead?");
- if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
- return sub->getReplacement().getAsTemplateDecl();
+ return cast_if_present<TemplateDecl>(Name.Storage.dyn_cast<Decl *>());
+}
- if (UsingShadowDecl *USD = getAsUsingShadowDecl())
- return cast<TemplateDecl>(USD->getTargetDecl());
+std::pair<TemplateDecl *, DefaultArguments>
+TemplateName::getTemplateDeclAndDefaultArgs() const {
+ for (TemplateName Name = *this; /**/; /**/) {
+ if (Name.getKind() == TemplateName::DeducedTemplate) {
+ DeducedTemplateStorage *DTS = Name.getAsDeducedTemplateName();
+ TemplateDecl *TD =
+ DTS->getUnderlying().getAsTemplateDecl(/*IgnoreDeduced=*/true);
+ DefaultArguments DefArgs = DTS->getDefaultArguments();
+ if (TD && DefArgs)
+ assert(DefArgs.StartPos + DefArgs.Args.size() <=
+ TD->getTemplateParameters()->size());
+ return {TD, DTS->getDefaultArguments()};
+ }
+ if (std::optional<TemplateName> UnderlyingOrNone =
+ Name.desugar(/*IgnoreDeduced=*/false)) {
+ Name = *UnderlyingOrNone;
+ continue;
+ }
+ return {cast_if_present<TemplateDecl>(Name.Storage.dyn_cast<Decl *>()), {}};
+ }
+}
- return nullptr;
+std::optional<TemplateName> TemplateName::desugar(bool IgnoreDeduced) const {
----------------
cor3ntin wrote:
I am surprise that we don't have something to desugar template names already?
https://github.com/llvm/llvm-project/pull/94981
More information about the cfe-commits
mailing list