Add pretty-printing for class template specializations, e.g.,
'struct A<double, int>'
In the "template instantiation depth exceeded" message, print
"-ftemplate-depth-N" rather than "-ftemplate-depth=N".
An unnamed tag type that is declared with a typedef, e.g.,
typedef struct { int x, y; } Point;
can be used as a template argument. Allow this, and check that we get
sensible pretty-printing for such things.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66560 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index f9cf847..205ebef 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1287,10 +1287,11 @@
InnerString = Name->getName() + InnerString;
}
-void
-ClassTemplateSpecializationType::
-getAsStringInternal(std::string &InnerString) const {
- std::string SpecString = Template->getNameAsString();
+/// \brief Print a template argument list, including the '<' and '>'
+/// enclosing the template arguments.
+static std::string printTemplateArgumentList(const TemplateArgument *Args,
+ unsigned NumArgs) {
+ std::string SpecString;
SpecString += '<';
for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
if (Arg)
@@ -1298,22 +1299,22 @@
// Print the argument into a string.
std::string ArgString;
- switch (getArg(Arg).getKind()) {
+ switch (Args[Arg].getKind()) {
case TemplateArgument::Type:
- getArg(Arg).getAsType().getAsStringInternal(ArgString);
+ Args[Arg].getAsType().getAsStringInternal(ArgString);
break;
case TemplateArgument::Declaration:
- ArgString = cast<NamedDecl>(getArg(Arg).getAsDecl())->getNameAsString();
+ ArgString = cast<NamedDecl>(Args[Arg].getAsDecl())->getNameAsString();
break;
case TemplateArgument::Integral:
- ArgString = getArg(Arg).getAsIntegral()->toString(10, true);
+ ArgString = Args[Arg].getAsIntegral()->toString(10, true);
break;
case TemplateArgument::Expression: {
llvm::raw_string_ostream s(ArgString);
- getArg(Arg).getAsExpr()->printPretty(s);
+ Args[Arg].getAsExpr()->printPretty(s);
break;
}
}
@@ -1335,6 +1336,14 @@
SpecString += '>';
+ return SpecString;
+}
+
+void
+ClassTemplateSpecializationType::
+getAsStringInternal(std::string &InnerString) const {
+ std::string SpecString = Template->getNameAsString();
+ SpecString += printTemplateArgumentList(getArgs(), getNumArgs());
if (InnerString.empty())
InnerString.swap(SpecString);
else
@@ -1395,6 +1404,16 @@
} else
ID = "<anonymous>";
+ // If this is a class template specialization, print the template
+ // arguments.
+ if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(getDecl())) {
+ std::string TemplateArgs
+ = printTemplateArgumentList(Spec->getTemplateArgs(),
+ Spec->getNumTemplateArgs());
+ InnerString = TemplateArgs + InnerString;
+ }
+
if (Kind)
InnerString = std::string(Kind) + " " + ID + InnerString;
else