From dace95b13e2ceb0c3ec8de6babd926dc5114e1e5 Mon Sep 17 00:00:00 2001
From: Douglas Gregor <dgregor@apple.com>
Date: Mon, 20 Dec 2010 22:28:59 +0000
Subject: [PATCH] Clean up the printing of template argument packs; previously,
 we were getting extra "<>" delimiters around template argument packs.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122280 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/Type.h                      |  3 ++-
 lib/AST/TypePrinter.cpp                       | 27 ++++++++++++++-----
 test/CXX/temp/temp.decls/temp.variadic/p4.cpp |  2 +-
 test/CXX/temp/temp.decls/temp.variadic/p5.cpp |  2 +-
 4 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index f4898486e72..a2d9a17d31b 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -2796,7 +2796,8 @@ public:
   /// enclosing the template arguments.
   static std::string PrintTemplateArgumentList(const TemplateArgument *Args,
                                                unsigned NumArgs,
-                                               const PrintingPolicy &Policy);
+                                               const PrintingPolicy &Policy,
+                                               bool SkipBrackets = false);
 
   static std::string PrintTemplateArgumentList(const TemplateArgumentLoc *Args,
                                                unsigned NumArgs,
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index c11920ac28a..bd0467d246b 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -759,16 +759,23 @@ std::string
 TemplateSpecializationType::PrintTemplateArgumentList(
                                                 const TemplateArgument *Args,
                                                 unsigned NumArgs,
-                                                const PrintingPolicy &Policy) {
+                                                  const PrintingPolicy &Policy,
+                                                      bool SkipBrackets) {
   std::string SpecString;
-  SpecString += '<';
+  if (!SkipBrackets)
+    SpecString += '<';
+  
   for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
-    if (Arg)
+    if (SpecString.size() > !SkipBrackets)
       SpecString += ", ";
     
     // Print the argument into a string.
     std::string ArgString;
-    {
+    if (Args[Arg].getKind() == TemplateArgument::Pack) {
+      ArgString = PrintTemplateArgumentList(Args[Arg].pack_begin(), 
+                                            Args[Arg].pack_size(), 
+                                            Policy, true);
+    } else {
       llvm::raw_string_ostream ArgOut(ArgString);
       Args[Arg].print(Policy, ArgOut);
     }
@@ -788,7 +795,8 @@ TemplateSpecializationType::PrintTemplateArgumentList(
   if (SpecString[SpecString.size() - 1] == '>')
     SpecString += ' ';
   
-  SpecString += '>';
+  if (!SkipBrackets)
+    SpecString += '>';
   
   return SpecString;
 }
@@ -800,12 +808,17 @@ PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
   std::string SpecString;
   SpecString += '<';
   for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
-    if (Arg)
+    if (SpecString.size() > 1)
       SpecString += ", ";
     
     // Print the argument into a string.
     std::string ArgString;
-    {
+    if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) {
+      ArgString = PrintTemplateArgumentList(
+                                           Args[Arg].getArgument().pack_begin(), 
+                                            Args[Arg].getArgument().pack_size(), 
+                                            Policy, true);
+    } else {
       llvm::raw_string_ostream ArgOut(ArgString);
       Args[Arg].getArgument().print(Policy, ArgOut);
     }
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
index 47883fe423c..db4db7ddd26 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
@@ -12,4 +12,4 @@ struct tuple_of_refs {
 
 Tuple<int&, float&> *t_int_ref_float_ref;
 tuple_of_refs<int&, float&>::types *t_int_ref_float_ref_2 =  t_int_ref_float_ref;
-  
+
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
index 94d874fc8d7..aff9b44539f 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -30,7 +30,7 @@ ExpansionLengthMismatch<int, long>::Inner<unsigned int, unsigned long>::type
   *il_pairs;
 tuple<pair<int, unsigned int>, pair<long, unsigned long> >*il_pairs_2 = il_pairs;
 
-ExpansionLengthMismatch<short, int, long>::Inner<unsigned int, unsigned long>::type // expected-note{{in instantiation of}}
+ExpansionLengthMismatch<short, int, long>::Inner<unsigned int, unsigned long>::type // expected-note{{in instantiation of template class 'ExpansionLengthMismatch<short, int, long>::Inner<unsigned int, unsigned long>' requested here}}
   *il_pairs_bad; 
 
 
-- 
GitLab