@@ -947,6 +947,26 @@ void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
947947 });
948948}
949949
950+ void TextNodeDumper::dumpTemplateArgument (const TemplateArgument &TA) {
951+ llvm::SmallString<128 > Str;
952+ {
953+ llvm::raw_svector_ostream SS (Str);
954+ TA.print (PrintPolicy, SS, /* IncludeType=*/ true );
955+ }
956+ OS << " '" << Str << " '" ;
957+
958+ if (TemplateArgument CanonTA = Context->getCanonicalTemplateArgument (TA);
959+ !CanonTA.structurallyEquals (TA)) {
960+ llvm::SmallString<128 > CanonStr;
961+ {
962+ llvm::raw_svector_ostream SS (CanonStr);
963+ CanonTA.print (PrintPolicy, SS, /* IncludeType=*/ true );
964+ }
965+ if (CanonStr != Str)
966+ OS << " :'" << CanonStr << " '" ;
967+ }
968+ }
969+
950970const char *TextNodeDumper::getCommandName (unsigned CommandID) {
951971 if (Traits)
952972 return Traits->getCommandInfo (CommandID)->Name ;
@@ -1086,45 +1106,100 @@ void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
10861106
10871107void TextNodeDumper::VisitTypeTemplateArgument (const TemplateArgument &TA) {
10881108 OS << " type" ;
1089- dumpType (TA. getAsType () );
1109+ dumpTemplateArgument (TA);
10901110}
10911111
10921112void TextNodeDumper::VisitDeclarationTemplateArgument (
10931113 const TemplateArgument &TA) {
10941114 OS << " decl" ;
1115+ dumpTemplateArgument (TA);
10951116 dumpDeclRef (TA.getAsDecl ());
10961117}
10971118
1098- void TextNodeDumper::VisitNullPtrTemplateArgument (const TemplateArgument &) {
1119+ void TextNodeDumper::VisitNullPtrTemplateArgument (const TemplateArgument &TA ) {
10991120 OS << " nullptr" ;
1121+ dumpTemplateArgument (TA);
11001122}
11011123
11021124void TextNodeDumper::VisitIntegralTemplateArgument (const TemplateArgument &TA) {
1103- OS << " integral " << TA.getAsIntegral ();
1125+ OS << " integral" ;
1126+ dumpTemplateArgument (TA);
1127+ }
1128+
1129+ void TextNodeDumper::dumpTemplateName (TemplateName TN) {
1130+ switch (TN.getKind ()) {
1131+ case TemplateName::Template:
1132+ AddChild ([=] { Visit (TN.getAsTemplateDecl ()); });
1133+ return ;
1134+ case TemplateName::UsingTemplate: {
1135+ const UsingShadowDecl *USD = TN.getAsUsingShadowDecl ();
1136+ AddChild ([=] { Visit (USD); });
1137+ AddChild (" target" , [=] { Visit (USD->getTargetDecl ()); });
1138+ return ;
1139+ }
1140+ case TemplateName::QualifiedTemplate: {
1141+ OS << " qualified" ;
1142+ const QualifiedTemplateName *QTN = TN.getAsQualifiedTemplateName ();
1143+ if (QTN->hasTemplateKeyword ())
1144+ OS << " keyword" ;
1145+ dumpNestedNameSpecifier (QTN->getQualifier ());
1146+ dumpTemplateName (QTN->getUnderlyingTemplate ());
1147+ return ;
1148+ }
1149+ case TemplateName::DependentTemplate: {
1150+ OS << " dependent" ;
1151+ const DependentTemplateName *DTN = TN.getAsDependentTemplateName ();
1152+ dumpNestedNameSpecifier (DTN->getQualifier ());
1153+ return ;
1154+ }
1155+ case TemplateName::SubstTemplateTemplateParm: {
1156+ const SubstTemplateTemplateParmStorage *STS =
1157+ TN.getAsSubstTemplateTemplateParm ();
1158+ OS << " subst index " << STS->getIndex ();
1159+ if (std::optional<unsigned int > PackIndex = STS->getPackIndex ())
1160+ OS << " pack_index " << *PackIndex;
1161+ if (const TemplateTemplateParmDecl *P = STS->getParameter ())
1162+ AddChild (" parameter" , [=] { Visit (P); });
1163+ dumpDeclRef (STS->getAssociatedDecl (), " associated" );
1164+ AddChild (" replacement" , [=] { dumpTemplateName (STS->getReplacement ()); });
1165+ return ;
1166+ }
1167+ // FIXME: Implement these.
1168+ case TemplateName::OverloadedTemplate:
1169+ OS << " overloaded" ;
1170+ return ;
1171+ case TemplateName::AssumedTemplate:
1172+ OS << " assumed" ;
1173+ return ;
1174+ case TemplateName::SubstTemplateTemplateParmPack:
1175+ OS << " subst_pack" ;
1176+ return ;
1177+ }
1178+ llvm_unreachable (" Unexpected TemplateName Kind" );
11041179}
11051180
11061181void TextNodeDumper::VisitTemplateTemplateArgument (const TemplateArgument &TA) {
1107- if (TA.getAsTemplate ().getKind () == TemplateName::UsingTemplate)
1108- OS << " using" ;
1109- OS << " template " ;
1110- TA.getAsTemplate ().dump (OS);
1182+ OS << " template" ;
1183+ dumpTemplateArgument (TA);
1184+ dumpTemplateName (TA.getAsTemplate ());
11111185}
11121186
11131187void TextNodeDumper::VisitTemplateExpansionTemplateArgument (
11141188 const TemplateArgument &TA) {
1115- if (TA.getAsTemplateOrTemplatePattern ().getKind () ==
1116- TemplateName::UsingTemplate)
1117- OS << " using" ;
1118- OS << " template expansion " ;
1119- TA.getAsTemplateOrTemplatePattern ().dump (OS);
1189+ OS << " template expansion" ;
1190+ dumpTemplateArgument (TA);
1191+ dumpTemplateName (TA.getAsTemplateOrTemplatePattern ());
11201192}
11211193
1122- void TextNodeDumper::VisitExpressionTemplateArgument (const TemplateArgument &) {
1194+ void TextNodeDumper::VisitExpressionTemplateArgument (
1195+ const TemplateArgument &TA) {
11231196 OS << " expr" ;
1197+ dumpTemplateArgument (TA);
11241198}
11251199
1126- void TextNodeDumper::VisitPackTemplateArgument (const TemplateArgument &) {
1200+ void TextNodeDumper::VisitPackTemplateArgument (const TemplateArgument &TA ) {
11271201 OS << " pack" ;
1202+ dumpTemplateArgument (TA);
11281203}
11291204
11301205static void dumpBasePath (raw_ostream &OS, const CastExpr *Node) {
0 commit comments