schroedersi updated this revision to Diff 104649.
schroedersi added a comment.

In https://reviews.llvm.org/D30946#792798, @rsmith wrote:

> I'd be interested to see how much complexity that adds, if you're prepared to 
> give it a try.


Thanks for your feedback :). I added a printing context and moved 
`TemporarySuppressScope` from `PrintingPolicy` to the printing context. The 
printing context is currently passed around by value. This is not ideal because 
changes to the context made inside a function are not available in the caller 
but it is sufficient for the temporary suppress scope functionality. And it 
gives an overview of the amount of code changes.

Passing the context around by reference would be better but it would also 
necessitate the creation of a overloaded version of almost each affected 
function. (Something like this:

  void print(const PrintingPolicy& Policy, PrintingContext& Context) { /*...*/ }
  
  void print(const PrintingPolicy& Policy) {
    PrintingContext Context;
    print(Policy, Context);
  }

).

> Yes, I think that's right -- `SuppressScope` isn't really an externally 
> useful "print without scopes" mechanism, it's an internal mechanism / 
> implementation detail used for printing an "inner" AST node when we've 
> already printed a scope for it based on outer sugar (eg, the entity is a type 
> component of a nested name specifier, or the type inside an elaborated type 
> specifier, or the class name in a destructor name). It's not really 
> `SuppressScope`, it's 
> `ScopeWasAlreadyPrintedForWhateverTopLevelThingIAskedYouToPrint` =)

Thanks for clarification :)


https://reviews.llvm.org/D30946

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclBase.h
  include/clang/AST/NestedNameSpecifier.h
  include/clang/AST/PrettyPrinter.h
  include/clang/AST/TemplateBase.h
  include/clang/AST/TemplateName.h
  include/clang/AST/Type.h
  lib/AST/Decl.cpp
  lib/AST/DeclPrinter.cpp
  lib/AST/NestedNameSpecifier.cpp
  lib/AST/TemplateBase.cpp
  lib/AST/TemplateName.cpp
  lib/AST/TypePrinter.cpp

Index: lib/AST/TypePrinter.cpp
===================================================================
--- lib/AST/TypePrinter.cpp
+++ lib/AST/TypePrinter.cpp
@@ -63,30 +63,28 @@
     bool SuppressTagKeyword;
     
   public:
-    explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy,
-                                      bool TemporarySuppressScope = true)
-        : Policy(Policy) {
+    explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {
       SuppressTagKeyword = Policy.SuppressTagKeyword;
       Policy.SuppressTagKeyword = true;
-      Policy.TemporarySuppressScope = TemporarySuppressScope;
     }
     
     ~ElaboratedTypePolicyRAII() {
       Policy.SuppressTagKeyword = SuppressTagKeyword;
-      Policy.TemporarySuppressScope = false;
     }
   };
   
   class TypePrinter {
     PrintingPolicy Policy;
+    PrintingContext Context;
     unsigned Indentation;
     bool HasEmptyPlaceHolder;
     bool InsideCCAttribute;
 
   public:
-    explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0)
-      : Policy(Policy), Indentation(Indentation),
-        HasEmptyPlaceHolder(false), InsideCCAttribute(false) { }
+    explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0,
+                         PrintingContext Context = PrintingContext())
+        : Policy(Policy), Context(Context), Indentation(Indentation),
+          HasEmptyPlaceHolder(false), InsideCCAttribute(false) {}
 
     void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
                StringRef PlaceHolder);
@@ -415,7 +413,8 @@
 
   PrintingPolicy InnerPolicy(Policy);
   InnerPolicy.IncludeTagDefinition = false;
-  TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
+  TypePrinter(InnerPolicy, 0, Context)
+      .print(QualType(T->getClass(), 0), OS, StringRef());
 
   OS << "::*";
 }
@@ -590,21 +589,20 @@
   OS << ")))";
 }
 
-void 
-FunctionProtoType::printExceptionSpecification(raw_ostream &OS, 
-                                               const PrintingPolicy &Policy)
-                                                                         const {
-  
+void FunctionProtoType::printExceptionSpecification(
+    raw_ostream &OS, const PrintingPolicy &Policy,
+    PrintingContext Context) const {
+
   if (hasDynamicExceptionSpec()) {
     OS << " throw(";
     if (getExceptionSpecType() == EST_MSAny)
       OS << "...";
     else
       for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
         if (I)
           OS << ", ";
-        
-        OS << getExceptionType(I).stream(Policy);
+
+        OS << getExceptionType(I).stream(Policy, Twine(), 0, Context);
       }
     OS << ')';
   } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
@@ -768,7 +766,7 @@
     OS << " &&";
     break;
   }
-  T->printExceptionSpecification(OS, Policy);
+  T->printExceptionSpecification(OS, Policy, Context);
 
   if (T->hasTrailingReturn()) {
     OS << " -> ";
@@ -800,7 +798,7 @@
 
 void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
   if (Policy.Scope != ScopePrintingKind::SuppressScope &&
-      !Policy.TemporarySuppressScope) {
+      !Context.TemporarySuppressScope) {
     // Print the scope:
     AppendScope(D->getDeclContext(), OS);
   }
@@ -901,7 +899,7 @@
     printBefore(T->getDeducedType(), OS);
   } else {
     IncludeStrongLifetimeRAII Strong(Policy);
-    T->getTemplateName().print(OS, Policy);
+    T->getTemplateName().print(OS, Policy, Context);
     spaceBeforePlaceHolder(OS);
   }
 }
@@ -961,7 +959,7 @@
     OS << Spec->getIdentifier()->getName();
     const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
     TemplateSpecializationType::PrintTemplateArgumentList(
-        OS, TemplateArgs.asArray(), Policy);
+        OS, TemplateArgs.asArray(), Policy, false, Context);
     OS << "::";
   } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
     if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
@@ -977,7 +975,7 @@
   if (Policy.IncludeTagDefinition) {
     PrintingPolicy SubPolicy = Policy;
     SubPolicy.IncludeTagDefinition = false;
-    D->print(OS, SubPolicy, Indentation);
+    D->print(OS, SubPolicy, Indentation, false, Context);
     spaceBeforePlaceHolder(OS);
     return;
   }
@@ -996,7 +994,7 @@
   // In C, this will always be empty except when the type
   // being printed is anonymous within other Record.
   if (Policy.Scope != ScopePrintingKind::SuppressScope &&
-      !Policy.TemporarySuppressScope)
+      !Context.TemporarySuppressScope)
     AppendScope(D->getDeclContext(), OS);
 
   if (const IdentifierInfo *II = D->getIdentifier())
@@ -1035,7 +1033,7 @@
     OS << (Policy.MSVCFormatting ? '\'' : ')');
   }
 
-  Policy.TemporarySuppressScope = false;
+  Context.TemporarySuppressScope = false;
 
   // If this is a class template specialization, print the template
   // arguments.
@@ -1051,7 +1049,8 @@
       Args = TemplateArgs.asArray();
     }
     IncludeStrongLifetimeRAII Strong(Policy);
-    TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, Policy);
+    TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, Policy,
+                                                          false, Context);
   }
 
   spaceBeforePlaceHolder(OS);
@@ -1107,12 +1106,12 @@
 void TypePrinter::printTemplateSpecializationBefore(
     const TemplateSpecializationType *T, raw_ostream &OS) {
   IncludeStrongLifetimeRAII Strong(Policy);
-  T->getTemplateName().print(OS, Policy);
+  T->getTemplateName().print(OS, Policy, Context);
 
-  Policy.TemporarySuppressScope = false;
+  Context.TemporarySuppressScope = false;
 
   TemplateSpecializationType::PrintTemplateArgumentList(
-      OS, T->template_arguments(), Policy);
+      OS, T->template_arguments(), Policy, false, Context);
   spaceBeforePlaceHolder(OS);
 }
 void TypePrinter::printTemplateSpecializationAfter(
@@ -1136,7 +1135,7 @@
       OS << " ";
     NestedNameSpecifier *Qualifier = T->getQualifier();
     if (Qualifier) {
-      Qualifier->print(OS, Policy);
+      Qualifier->print(OS, Policy, Context);
       ScopeHasBeenPrinted = true;
     }
     // If there are no nested name specifiers, the complete scope will be
@@ -1155,9 +1154,9 @@
 
   // Suppress the outer nested name specifier of the underlying type in case
   // of DefaultScope and if a scope has already been printed.
-  bool temporarySuppressScope =
+  Context.TemporarySuppressScope =
       Policy.Scope == ScopePrintingKind::DefaultScope || ScopeHasBeenPrinted;
-  ElaboratedTypePolicyRAII PolicyRAII(Policy, temporarySuppressScope);
+  ElaboratedTypePolicyRAII PolicyRAII(Policy);
   printBefore(T->getNamedType(), OS);
 }
 void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
@@ -1186,8 +1185,8 @@
   OS << TypeWithKeyword::getKeywordName(T->getKeyword());
   if (T->getKeyword() != ETK_None)
     OS << " ";
-  T->getQualifier()->print(OS, Policy);
-  
+  T->getQualifier()->print(OS, Policy, Context);
+
   OS << T->getIdentifier()->getName();
   spaceBeforePlaceHolder(OS);
 }
@@ -1203,14 +1202,13 @@
     OS << " ";
 
   if (T->getQualifier())
-    T->getQualifier()->print(OS, Policy);
+    T->getQualifier()->print(OS, Policy, Context);
   OS << T->getIdentifier()->getName();
 
-  Policy.TemporarySuppressScope = false;
+  Context.TemporarySuppressScope = false;
 
-  TemplateSpecializationType::PrintTemplateArgumentList(OS,
-                                                        T->template_arguments(),
-                                                        Policy);
+  TemplateSpecializationType::PrintTemplateArgumentList(
+      OS, T->template_arguments(), Policy, false, Context);
   spaceBeforePlaceHolder(OS);
 }
 void TypePrinter::printDependentTemplateSpecializationAfter(
@@ -1514,18 +1512,17 @@
 void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T, 
                                               raw_ostream &OS) { }
 
-void TemplateSpecializationType::
-  PrintTemplateArgumentList(raw_ostream &OS,
-                            const TemplateArgumentListInfo &Args,
-                            const PrintingPolicy &Policy) {
-  return PrintTemplateArgumentList(OS,
-                                   Args.arguments(),
-                                   Policy);
+void TemplateSpecializationType::PrintTemplateArgumentList(
+    raw_ostream &OS, const TemplateArgumentListInfo &Args,
+    const PrintingPolicy &Policy, PrintingContext Context) {
+  return PrintTemplateArgumentList(OS, Args.arguments(), Policy, Context);
 }
 
 void TemplateSpecializationType::PrintTemplateArgumentList(
     raw_ostream &OS, ArrayRef<TemplateArgument> Args,
-    const PrintingPolicy &Policy, bool SkipBrackets) {
+    const PrintingPolicy &Policy, bool SkipBrackets, PrintingContext Context) {
+  assert(!Context.TemporarySuppressScope &&
+         "Suppressing the scope of each argument is not supported.");
   const char *Comma = Policy.MSVCFormatting ? "," : ", ";
   if (!SkipBrackets)
     OS << '<';
@@ -1539,13 +1536,12 @@
     if (Arg.getKind() == TemplateArgument::Pack) {
       if (Arg.pack_size() && !FirstArg)
         OS << Comma;
-      PrintTemplateArgumentList(ArgOS,
-                                Arg.getPackAsArray(),
-                                Policy, true);
+      PrintTemplateArgumentList(ArgOS, Arg.getPackAsArray(), Policy, true,
+                                Context);
     } else {
       if (!FirstArg)
         OS << Comma;
-      Arg.print(Policy, ArgOS);
+      Arg.print(Policy, ArgOS, Context);
     }
     StringRef ArgString = ArgOS.str();
 
@@ -1572,10 +1568,9 @@
 }
 
 // Sadly, repeat all that with TemplateArgLoc.
-void TemplateSpecializationType::
-PrintTemplateArgumentList(raw_ostream &OS,
-                          ArrayRef<TemplateArgumentLoc> Args,
-                          const PrintingPolicy &Policy) {
+void TemplateSpecializationType::PrintTemplateArgumentList(
+    raw_ostream &OS, ArrayRef<TemplateArgumentLoc> Args,
+    const PrintingPolicy &Policy, PrintingContext Context) {
   OS << '<';
   const char *Comma = Policy.MSVCFormatting ? "," : ", ";
 
@@ -1589,11 +1584,10 @@
     SmallString<128> Buf;
     llvm::raw_svector_ostream ArgOS(Buf);
     if (Arg.getArgument().getKind() == TemplateArgument::Pack) {
-      PrintTemplateArgumentList(ArgOS,
-                                Arg.getArgument().getPackAsArray(),
-                                Policy, true);
+      PrintTemplateArgumentList(ArgOS, Arg.getArgument().getPackAsArray(),
+                                Policy, true, Context);
     } else {
-      Arg.getArgument().print(Policy, ArgOS);
+      Arg.getArgument().print(Policy, ArgOS, Context);
     }
     StringRef ArgString = ArgOS.str();
 
@@ -1745,13 +1739,13 @@
   return buffer;
 }
 
-void QualType::print(const Type *ty, Qualifiers qs,
-                     raw_ostream &OS, const PrintingPolicy &policy,
-                     const Twine &PlaceHolder, unsigned Indentation) {
+void QualType::print(const Type *ty, Qualifiers qs, raw_ostream &OS,
+                     const PrintingPolicy &policy, const Twine &PlaceHolder,
+                     unsigned Indentation, PrintingContext Context) {
   SmallString<128> PHBuf;
   StringRef PH = PlaceHolder.toStringRef(PHBuf);
 
-  TypePrinter(policy, Indentation).print(ty, qs, OS, PH);
+  TypePrinter(policy, Indentation, Context).print(ty, qs, OS, PH);
 }
 
 void QualType::getAsStringInternal(const Type *ty, Qualifiers qs,
Index: lib/AST/TemplateName.cpp
===================================================================
--- lib/AST/TemplateName.cpp
+++ lib/AST/TemplateName.cpp
@@ -174,23 +174,24 @@
   return getAsSubstTemplateTemplateParmPack() != nullptr;
 }
 
-void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy) const {
+void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
+                         PrintingContext Context) const {
   if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>()) {
     if (Policy.Scope == ScopePrintingKind::FullScope &&
-        !Policy.TemporarySuppressScope) {
-      Template->printQualifiedName(OS, Policy);
+        !Context.TemporarySuppressScope) {
+      Template->printQualifiedName(OS, Policy, Context);
     } else {
       OS << *Template;
     }
   } else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
-    if (!Policy.TemporarySuppressScope)
-      QTN->getQualifier()->print(OS, Policy);
+    if (!Context.TemporarySuppressScope)
+      QTN->getQualifier()->print(OS, Policy, Context);
     if (QTN->hasTemplateKeyword())
       OS << "template ";
     OS << *QTN->getDecl();
   } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
-    if (!Policy.TemporarySuppressScope && DTN->getQualifier())
-      DTN->getQualifier()->print(OS, Policy);
+    if (!Context.TemporarySuppressScope && DTN->getQualifier())
+      DTN->getQualifier()->print(OS, Policy, Context);
     OS << "template ";
     
     if (DTN->isIdentifier())
Index: lib/AST/TemplateBase.cpp
===================================================================
--- lib/AST/TemplateBase.cpp
+++ lib/AST/TemplateBase.cpp
@@ -35,8 +35,9 @@
 /// \param Out the raw_ostream instance to use for printing.
 ///
 /// \param Policy the printing policy for EnumConstantDecl printing.
-static void printIntegral(const TemplateArgument &TemplArg,
-                          raw_ostream &Out, const PrintingPolicy& Policy) {
+static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
+                          const PrintingPolicy &Policy,
+                          PrintingContext Context = PrintingContext()) {
   const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
   const llvm::APSInt &Val = TemplArg.getAsIntegral();
 
@@ -47,7 +48,7 @@
       // may create a size difference between the enum value and template
       // argument value, requiring isSameValue here instead of operator==.
       if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
-        ECD->printQualifiedName(Out, Policy);
+        ECD->printQualifiedName(Out, Policy, Context);
         return;
       }
     }
@@ -376,26 +377,26 @@
   llvm_unreachable("Invalid TemplateArgument Kind!");
 }
 
-void TemplateArgument::print(const PrintingPolicy &Policy, 
-                             raw_ostream &Out) const {
+void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
+                             PrintingContext Context) const {
   switch (getKind()) {
   case Null:
     Out << "(no value)";
     break;
     
   case Type: {
     PrintingPolicy SubPolicy(Policy);
     SubPolicy.SuppressStrongLifetime = true;
-    getAsType().print(Out, SubPolicy);
+    getAsType().print(Out, SubPolicy, Twine(), 0, Context);
     break;
   }
     
   case Declaration: {
     NamedDecl *ND = cast<NamedDecl>(getAsDecl());
     Out << '&';
     if (ND->getDeclName()) {
       // FIXME: distinguish between pointer and reference args?
-      ND->printQualifiedName(Out);
+      ND->printQualifiedName(Out, Context);
     } else {
       Out << "(anonymous)";
     }
@@ -407,16 +408,16 @@
     break;
 
   case Template:
-    getAsTemplate().print(Out, Policy);
+    getAsTemplate().print(Out, Policy, Context);
     break;
 
   case TemplateExpansion:
-    getAsTemplateOrTemplatePattern().print(Out, Policy);
+    getAsTemplateOrTemplatePattern().print(Out, Policy, Context);
     Out << "...";
     break;
       
   case Integral: {
-    printIntegral(*this, Out, Policy);
+    printIntegral(*this, Out, Policy, Context);
     break;
   }
     
@@ -432,8 +433,8 @@
         First = false;
       else
         Out << ", ";
-      
-      P.print(Policy, Out);
+
+      P.print(Policy, Out, Context);
     }
     Out << ">";
     break;        
Index: lib/AST/NestedNameSpecifier.cpp
===================================================================
--- lib/AST/NestedNameSpecifier.cpp
+++ lib/AST/NestedNameSpecifier.cpp
@@ -258,11 +258,10 @@
 
 /// \brief Print this nested name specifier to the given output
 /// stream.
-void
-NestedNameSpecifier::print(raw_ostream &OS,
-                           const PrintingPolicy &Policy) const {
+void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
+                                PrintingContext Context) const {
   if (Policy.Scope == ScopePrintingKind::SuppressScope ||
-      Policy.TemporarySuppressScope) {
+      Context.TemporarySuppressScope) {
     return;
   }
 
@@ -338,9 +337,8 @@
     // dependent template-id types (e.g., Outer<T>::template Inner<U>),
     // the type requires its own nested-name-specifier for uniqueness, so we
     // suppress that nested-name-specifier during printing.
-    PrintingPolicy InnerPolicy(Policy);
-    InnerPolicy.TemporarySuppressScope = true;
-    QualType(T, 0).print(OS, InnerPolicy);
+    Context.TemporarySuppressScope = true;
+    QualType(T, 0).print(OS, Policy, Twine(), 0, Context);
     break;
   }
   }
Index: lib/AST/DeclPrinter.cpp
===================================================================
--- lib/AST/DeclPrinter.cpp
+++ lib/AST/DeclPrinter.cpp
@@ -28,6 +28,7 @@
   class DeclPrinter : public DeclVisitor<DeclPrinter> {
     raw_ostream &Out;
     PrintingPolicy Policy;
+    PrintingContext Context;
     unsigned Indentation;
     bool PrintInstantiation;
 
@@ -48,9 +49,10 @@
 
   public:
     DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
-                unsigned Indentation = 0, bool PrintInstantiation = false)
-      : Out(Out), Policy(Policy), Indentation(Indentation),
-        PrintInstantiation(PrintInstantiation) { }
+                unsigned Indentation = 0, bool PrintInstantiation = false,
+                PrintingContext Context = PrintingContext())
+        : Out(Out), Policy(Policy), Context(Context), Indentation(Indentation),
+          PrintInstantiation(PrintInstantiation) {}
 
     void VisitDeclContext(DeclContext *DC, bool Indent = true);
 
@@ -114,8 +116,9 @@
 }
 
 void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy,
-                 unsigned Indentation, bool PrintInstantiation) const {
-  DeclPrinter Printer(Out, Policy, Indentation, PrintInstantiation);
+                 unsigned Indentation, bool PrintInstantiation,
+                 PrintingContext Context) const {
+  DeclPrinter Printer(Out, Policy, Indentation, PrintInstantiation, Context);
   Printer.Visit(const_cast<Decl*>(this));
 }
 
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -1404,12 +1404,13 @@
   return OS.str();
 }
 
-void NamedDecl::printQualifiedName(raw_ostream &OS) const {
-  printQualifiedName(OS, getASTContext().getPrintingPolicy());
+void NamedDecl::printQualifiedName(raw_ostream &OS,
+                                   PrintingContext Context) const {
+  printQualifiedName(OS, getASTContext().getPrintingPolicy(), Context);
 }
 
-void NamedDecl::printQualifiedName(raw_ostream &OS,
-                                   const PrintingPolicy &P) const {
+void NamedDecl::printQualifiedName(raw_ostream &OS, const PrintingPolicy &P,
+                                   PrintingContext Context) const {
   const DeclContext *Ctx = getDeclContext();
 
   // For ObjC methods, look through categories and use the interface as context.
@@ -1426,7 +1427,7 @@
   ContextsTy Contexts;
 
   if (P.Scope != ScopePrintingKind::SuppressScope &&
-      !P.TemporarySuppressScope) {
+      !Context.TemporarySuppressScope) {
     // Collect contexts.
     while (Ctx && isa<NamedDecl>(Ctx)) {
       Contexts.push_back(Ctx);
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -18,6 +18,7 @@
 #define LLVM_CLANG_AST_TYPE_H
 
 #include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/TemplateName.h"
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/Diagnostic.h"
@@ -950,19 +951,21 @@
   std::string getAsString(const PrintingPolicy &Policy) const;
 
   void print(raw_ostream &OS, const PrintingPolicy &Policy,
-             const Twine &PlaceHolder = Twine(),
-             unsigned Indentation = 0) const {
-    print(split(), OS, Policy, PlaceHolder, Indentation);
+             const Twine &PlaceHolder = Twine(), unsigned Indentation = 0,
+             PrintingContext Context = PrintingContext()) const {
+    print(split(), OS, Policy, PlaceHolder, Indentation, Context);
   }
   static void print(SplitQualType split, raw_ostream &OS,
                     const PrintingPolicy &policy, const Twine &PlaceHolder,
-                    unsigned Indentation = 0) {
-    return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation);
+                    unsigned Indentation = 0,
+                    PrintingContext Context = PrintingContext()) {
+    return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation,
+                 Context);
   }
-  static void print(const Type *ty, Qualifiers qs,
-                    raw_ostream &OS, const PrintingPolicy &policy,
-                    const Twine &PlaceHolder,
-                    unsigned Indentation = 0);
+  static void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
+                    const PrintingPolicy &policy, const Twine &PlaceHolder,
+                    unsigned Indentation = 0,
+                    PrintingContext Context = PrintingContext());
 
   void getAsStringInternal(std::string &Str,
                            const PrintingPolicy &Policy) const {
@@ -979,25 +982,30 @@
   class StreamedQualTypeHelper {
     const QualType &T;
     const PrintingPolicy &Policy;
+    PrintingContext Context;
     const Twine &PlaceHolder;
     unsigned Indentation;
   public:
     StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy,
-                           const Twine &PlaceHolder, unsigned Indentation)
-      : T(T), Policy(Policy), PlaceHolder(PlaceHolder),
-        Indentation(Indentation) { }
+                           const Twine &PlaceHolder, unsigned Indentation,
+                           PrintingContext Context = PrintingContext())
+        : T(T), Policy(Policy), Context(Context), PlaceHolder(PlaceHolder),
+          Indentation(Indentation) {}
 
     friend raw_ostream &operator<<(raw_ostream &OS,
                                    const StreamedQualTypeHelper &SQT) {
-      SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder, SQT.Indentation);
+      SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder, SQT.Indentation,
+                  SQT.Context);
       return OS;
     }
   };
 
-  StreamedQualTypeHelper stream(const PrintingPolicy &Policy,
-                                const Twine &PlaceHolder = Twine(),
-                                unsigned Indentation = 0) const {
-    return StreamedQualTypeHelper(*this, Policy, PlaceHolder, Indentation);
+  StreamedQualTypeHelper
+  stream(const PrintingPolicy &Policy, const Twine &PlaceHolder = Twine(),
+         unsigned Indentation = 0,
+         PrintingContext Context = PrintingContext()) const {
+    return StreamedQualTypeHelper(*this, Policy, PlaceHolder, Indentation,
+                                  Context);
   }
 
   void dump(const char *s) const;
@@ -3527,8 +3535,9 @@
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 
-  void printExceptionSpecification(raw_ostream &OS,
-                                   const PrintingPolicy &Policy) const;
+  void printExceptionSpecification(
+      raw_ostream &OS, const PrintingPolicy &Policy,
+      PrintingContext Context = PrintingContext()) const;
 
   static bool classof(const Type *T) {
     return T->getTypeClass() == FunctionProto;
@@ -4328,18 +4337,21 @@
 
   /// \brief Print a template argument list, including the '<' and '>'
   /// enclosing the template arguments.
-  static void PrintTemplateArgumentList(raw_ostream &OS,
-                                        ArrayRef<TemplateArgument> Args,
-                                        const PrintingPolicy &Policy,
-                                        bool SkipBrackets = false);
-
-  static void PrintTemplateArgumentList(raw_ostream &OS,
-                                        ArrayRef<TemplateArgumentLoc> Args,
-                                        const PrintingPolicy &Policy);
-
-  static void PrintTemplateArgumentList(raw_ostream &OS,
-                                        const TemplateArgumentListInfo &,
-                                        const PrintingPolicy &Policy);
+  static void
+  PrintTemplateArgumentList(raw_ostream &OS, ArrayRef<TemplateArgument> Args,
+                            const PrintingPolicy &Policy,
+                            bool SkipBrackets = false,
+                            PrintingContext Context = PrintingContext());
+
+  static void
+  PrintTemplateArgumentList(raw_ostream &OS, ArrayRef<TemplateArgumentLoc> Args,
+                            const PrintingPolicy &Policy,
+                            PrintingContext Context = PrintingContext());
+
+  static void
+  PrintTemplateArgumentList(raw_ostream &OS, const TemplateArgumentListInfo &,
+                            const PrintingPolicy &Policy,
+                            PrintingContext Context = PrintingContext());
 
   /// True if this template specialization type matches a current
   /// instantiation in the context in which it is found.
Index: include/clang/AST/TemplateName.h
===================================================================
--- include/clang/AST/TemplateName.h
+++ include/clang/AST/TemplateName.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_AST_TEMPLATENAME_H
 
 #include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/PointerUnion.h"
@@ -277,7 +278,8 @@
   ///
   /// \param OS the output stream to which the template name will be
   /// printed.
-  void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
+  void print(raw_ostream &OS, const PrintingPolicy &Policy,
+             PrintingContext Context = PrintingContext()) const;
 
   /// \brief Debugging aid that dumps the template name.
   void dump(raw_ostream &OS) const;
Index: include/clang/AST/TemplateBase.h
===================================================================
--- include/clang/AST/TemplateBase.h
+++ include/clang/AST/TemplateBase.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
 #define LLVM_CLANG_AST_TEMPLATEBASE_H
 
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/TemplateName.h"
 #include "clang/AST/Type.h"
 #include "llvm/ADT/APSInt.h"
@@ -353,8 +354,9 @@
   TemplateArgument getPackExpansionPattern() const;
 
   /// \brief Print this template argument to the given output stream.
-  void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
-             
+  void print(const PrintingPolicy &Policy, raw_ostream &Out,
+             PrintingContext Context = PrintingContext()) const;
+
   /// \brief Debugging aid that dumps the template argument.
   void dump(raw_ostream &Out) const;
 
Index: include/clang/AST/PrettyPrinter.h
===================================================================
--- include/clang/AST/PrettyPrinter.h
+++ include/clang/AST/PrettyPrinter.h
@@ -75,8 +75,25 @@
 };
 }
 
-/// \brief Describes how types, statements, expressions, and
-/// declarations should be printed.
+/// \brief Provides a context for one printing process. This should be used for
+/// mutable information that need to be shared across the member functions
+/// involved in the printing process of types and declarations.
+struct PrintingContext {
+  /// \brief Creates a default printing context.
+  PrintingContext() : TemporarySuppressScope(false) {}
+
+  /// \brief When true, suppress printing of current outer scope. For example
+  /// with TemporarySuppressScope set to true "::A::B::C<D::E, ::F>" ist
+  /// printed as "C<D::E, ::F>". This is currently only supported in some cases
+  /// and is only used internally.
+  bool TemporarySuppressScope : 1;
+};
+
+/// \brief Describes how types, statements, expressions, and declarations should
+/// be printed.
+///
+/// This should not be mutated during the printing process. Use PrintingContext
+/// for mutable information instead.
 ///
 /// This type is intended to be small and suitable for passing by value.
 /// It is very frequently copied.
@@ -100,7 +117,7 @@
         UseVoidForZeroParams(!LO.CPlusPlus), TerseOutput(false),
         PolishForDeclaration(false), Half(LO.Half),
         MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
-        MSVCFormatting(false), TemporarySuppressScope(false) {}
+        MSVCFormatting(false) {}
 
   /// \brief Adjust this printing policy for cases where it's known that
   /// we're printing C++ code (for instance, if AST dumping reaches a
@@ -251,13 +268,6 @@
   /// prints anonymous namespaces as `anonymous namespace' and does not insert
   /// spaces after template arguments.
   bool MSVCFormatting : 1;
-
-private:
-  /// \brief When true, suppress printing of current outer scope. For example
-  /// with TemporarySuppressScope set to true "::A::B::C<D::E, ::F>" ist
-  /// printed as "C<D::E, ::F>". This is currently only supported in some cases
-  /// and is currently only used internally.
-  bool TemporarySuppressScope : 1;
 };
 
 } // end namespace clang
Index: include/clang/AST/NestedNameSpecifier.h
===================================================================
--- include/clang/AST/NestedNameSpecifier.h
+++ include/clang/AST/NestedNameSpecifier.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
 #define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
 
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/Basic/Diagnostic.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/PointerIntPair.h"
@@ -208,7 +209,8 @@
 
   /// \brief Print this nested name specifier to the given output
   /// stream.
-  void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
+  void print(raw_ostream &OS, const PrintingPolicy &Policy,
+             PrintingContext Context = PrintingContext()) const;
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
     ID.AddPointer(Prefix.getOpaqueValue());
Index: include/clang/AST/DeclBase.h
===================================================================
--- include/clang/AST/DeclBase.h
+++ include/clang/AST/DeclBase.h
@@ -16,6 +16,7 @@
 
 #include "clang/AST/AttrIterator.h"
 #include "clang/AST/DeclarationName.h"
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/VersionTuple.h"
 #include "llvm/ADT/PointerUnion.h"
@@ -1090,7 +1091,8 @@
   void print(raw_ostream &Out, unsigned Indentation = 0,
              bool PrintInstantiation = false) const;
   void print(raw_ostream &Out, const PrintingPolicy &Policy,
-             unsigned Indentation = 0, bool PrintInstantiation = false) const;
+             unsigned Indentation = 0, bool PrintInstantiation = false,
+             PrintingContext Context = PrintingContext()) const;
   static void printGroup(Decl** Begin, unsigned NumDecls,
                          raw_ostream &Out, const PrintingPolicy &Policy,
                          unsigned Indentation = 0);
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h
+++ include/clang/AST/Decl.h
@@ -18,6 +18,7 @@
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/Redeclarable.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/Linkage.h"
@@ -27,8 +28,8 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/TrailingObjects.h"
+#include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 struct ASTTemplateArgumentListInfo;
@@ -266,8 +267,10 @@
   /// namespace), it will return same result as printName().
   /// Creating this name is expensive, so it should be called only when
   /// performance doesn't matter.
-  void printQualifiedName(raw_ostream &OS) const;
-  void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
+  void printQualifiedName(raw_ostream &OS,
+                          PrintingContext Context = PrintingContext()) const;
+  void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy,
+                          PrintingContext Context = PrintingContext()) const;
 
   // FIXME: Remove string version.
   std::string getQualifiedNameAsString() const;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D30946: [... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D309... Simon Schroeder via Phabricator via cfe-commits
    • [PATCH] D309... Simon Schroeder via Phabricator via cfe-commits
    • [PATCH] D309... Simon Schroeder via Phabricator via cfe-commits
    • [PATCH] D309... Simon Schroeder via Phabricator via cfe-commits

Reply via email to