It's kindof silly that ExtQuals has an ASTContext&, and we can use that
space better.  Remove this reference.  To make that work, change some APIs
(most importantly, getDesugaredType()) to take an ASTContext& if they
need to return a QualType.  Simultaneously, diminish the need to return a
QualType by introducing some useful APIs on SplitQualType, which is
just a std::pair<const Type *, Qualifiers>.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121478 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 5dfad6c..0e37acb 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -30,12 +30,13 @@
   public:
     explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { }
 
-    void Print(QualType T, std::string &S);
+    void print(const Type *ty, Qualifiers qs, std::string &buffer);
+    void print(QualType T, std::string &S);
     void AppendScope(DeclContext *DC, std::string &S);
-    void PrintTag(TagDecl *T, std::string &S);
+    void printTag(TagDecl *T, std::string &S);
 #define ABSTRACT_TYPE(CLASS, PARENT)
 #define TYPE(CLASS, PARENT) \
-  void Print##CLASS(const CLASS##Type *T, std::string &S);
+  void print##CLASS(const CLASS##Type *T, std::string &S);
 #include "clang/AST/TypeNodes.def"
   };
 }
@@ -55,9 +56,14 @@
   }
 }
 
-void TypePrinter::Print(QualType T, std::string &S) {
-  if (T.isNull()) {
-    S += "NULL TYPE";
+void TypePrinter::print(QualType t, std::string &buffer) {
+  SplitQualType split = t.split();
+  print(split.first, split.second, buffer);
+}
+
+void TypePrinter::print(const Type *T, Qualifiers Quals, std::string &buffer) {
+  if (!T) {
+    buffer += "NULL TYPE";
     return;
   }
   
@@ -65,7 +71,6 @@
     return;
   
   // Print qualifiers as appropriate.
-  Qualifiers Quals = T.getLocalQualifiers();
   
   // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
   // so that we get "const int" instead of "int const", but we can't do this if
@@ -79,38 +84,38 @@
     T->isObjCIdType() || T->isObjCQualifiedIdType();
   
   if (!CanPrefixQualifiers && !Quals.empty()) {
-    std::string TQS;
-    Quals.getAsStringInternal(TQS, Policy);
+    std::string qualsBuffer;
+    Quals.getAsStringInternal(qualsBuffer, Policy);
     
-    if (!S.empty()) {
-      TQS += ' ';
-      TQS += S;
+    if (!buffer.empty()) {
+      qualsBuffer += ' ';
+      qualsBuffer += buffer;
     }
-    std::swap(S, TQS);
+    std::swap(buffer, qualsBuffer);
   }
   
   switch (T->getTypeClass()) {
 #define ABSTRACT_TYPE(CLASS, PARENT)
-#define TYPE(CLASS, PARENT) case Type::CLASS:                \
-    Print##CLASS(cast<CLASS##Type>(T.getTypePtr()), S);      \
+#define TYPE(CLASS, PARENT) case Type::CLASS: \
+    print##CLASS(cast<CLASS##Type>(T), buffer); \
     break;
 #include "clang/AST/TypeNodes.def"
   }
   
   // If we're adding the qualifiers as a prefix, do it now.
   if (CanPrefixQualifiers && !Quals.empty()) {
-    std::string TQS;
-    Quals.getAsStringInternal(TQS, Policy);
+    std::string qualsBuffer;
+    Quals.getAsStringInternal(qualsBuffer, Policy);
     
-    if (!S.empty()) {
-      TQS += ' ';
-      TQS += S;
+    if (!buffer.empty()) {
+      qualsBuffer += ' ';
+      qualsBuffer += buffer;
     }
-    std::swap(S, TQS);
+    std::swap(buffer, qualsBuffer);
   }
 }
 
-void TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) {
+void TypePrinter::printBuiltin(const BuiltinType *T, std::string &S) {
   if (S.empty()) {
     S = T->getName(Policy.LangOpts);
   } else {
@@ -120,12 +125,12 @@
   }
 }
 
-void TypePrinter::PrintComplex(const ComplexType *T, std::string &S) {
-  Print(T->getElementType(), S);
+void TypePrinter::printComplex(const ComplexType *T, std::string &S) {
+  print(T->getElementType(), S);
   S = "_Complex " + S;
 }
 
-void TypePrinter::PrintPointer(const PointerType *T, std::string &S) { 
+void TypePrinter::printPointer(const PointerType *T, std::string &S) { 
   S = '*' + S;
   
   // Handle things like 'int (*A)[4];' correctly.
@@ -133,15 +138,15 @@
   if (isa<ArrayType>(T->getPointeeType()))
     S = '(' + S + ')';
   
-  Print(T->getPointeeType(), S);
+  print(T->getPointeeType(), S);
 }
 
-void TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) {
+void TypePrinter::printBlockPointer(const BlockPointerType *T, std::string &S) {
   S = '^' + S;
-  Print(T->getPointeeType(), S);
+  print(T->getPointeeType(), S);
 }
 
-void TypePrinter::PrintLValueReference(const LValueReferenceType *T, 
+void TypePrinter::printLValueReference(const LValueReferenceType *T, 
                                        std::string &S) { 
   S = '&' + S;
   
@@ -150,10 +155,10 @@
   if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
     S = '(' + S + ')';
   
-  Print(T->getPointeeTypeAsWritten(), S);
+  print(T->getPointeeTypeAsWritten(), S);
 }
 
-void TypePrinter::PrintRValueReference(const RValueReferenceType *T, 
+void TypePrinter::printRValueReference(const RValueReferenceType *T, 
                                        std::string &S) { 
   S = "&&" + S;
   
@@ -162,13 +167,13 @@
   if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
     S = '(' + S + ')';
   
-  Print(T->getPointeeTypeAsWritten(), S);
+  print(T->getPointeeTypeAsWritten(), S);
 }
 
-void TypePrinter::PrintMemberPointer(const MemberPointerType *T, 
+void TypePrinter::printMemberPointer(const MemberPointerType *T, 
                                      std::string &S) { 
   std::string C;
-  Print(QualType(T->getClass(), 0), C);
+  print(QualType(T->getClass(), 0), C);
   C += "::*";
   S = C + S;
   
@@ -177,25 +182,25 @@
   if (isa<ArrayType>(T->getPointeeType()))
     S = '(' + S + ')';
   
-  Print(T->getPointeeType(), S);
+  print(T->getPointeeType(), S);
 }
 
-void TypePrinter::PrintConstantArray(const ConstantArrayType *T, 
+void TypePrinter::printConstantArray(const ConstantArrayType *T, 
                                      std::string &S) {
   S += '[';
   S += llvm::utostr(T->getSize().getZExtValue());
   S += ']';
   
-  Print(T->getElementType(), S);
+  print(T->getElementType(), S);
 }
 
-void TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T, 
+void TypePrinter::printIncompleteArray(const IncompleteArrayType *T, 
                                        std::string &S) {
   S += "[]";
-  Print(T->getElementType(), S);
+  print(T->getElementType(), S);
 }
 
-void TypePrinter::PrintVariableArray(const VariableArrayType *T, 
+void TypePrinter::printVariableArray(const VariableArrayType *T, 
                                      std::string &S) { 
   S += '[';
   
@@ -217,10 +222,10 @@
   }
   S += ']';
   
-  Print(T->getElementType(), S);
+  print(T->getElementType(), S);
 }
 
-void TypePrinter::PrintDependentSizedArray(const DependentSizedArrayType *T, 
+void TypePrinter::printDependentSizedArray(const DependentSizedArrayType *T, 
                                            std::string &S) {  
   S += '[';
   
@@ -232,13 +237,13 @@
   }
   S += ']';
   
-  Print(T->getElementType(), S);
+  print(T->getElementType(), S);
 }
 
-void TypePrinter::PrintDependentSizedExtVector(
+void TypePrinter::printDependentSizedExtVector(
                                           const DependentSizedExtVectorType *T, 
                                                std::string &S) { 
-  Print(T->getElementType(), S);
+  print(T->getElementType(), S);
   
   S += " __attribute__((ext_vector_type(";
   if (T->getSizeExpr()) {
@@ -250,37 +255,37 @@
   S += ")))";  
 }
 
-void TypePrinter::PrintVector(const VectorType *T, std::string &S) { 
+void TypePrinter::printVector(const VectorType *T, std::string &S) { 
   switch (T->getVectorKind()) {
   case VectorType::AltiVecPixel:
     S = "__vector __pixel " + S;
     break;
   case VectorType::AltiVecBool:
-    Print(T->getElementType(), S);
+    print(T->getElementType(), S);
     S = "__vector __bool " + S;
     break;
   case VectorType::AltiVecVector:
-    Print(T->getElementType(), S);
+    print(T->getElementType(), S);
     S = "__vector " + S;
     break;
   case VectorType::NeonVector:
-    Print(T->getElementType(), S);
+    print(T->getElementType(), S);
     S = ("__attribute__((neon_vector_type(" +
          llvm::utostr_32(T->getNumElements()) + "))) " + S);
     break;
   case VectorType::NeonPolyVector:
-    Print(T->getElementType(), S);
+    print(T->getElementType(), S);
     S = ("__attribute__((neon_polyvector_type(" +
          llvm::utostr_32(T->getNumElements()) + "))) " + S);
     break;
   case VectorType::GenericVector: {
     // FIXME: We prefer to print the size directly here, but have no way
     // to get the size of the type.
-    Print(T->getElementType(), S);
+    print(T->getElementType(), S);
     std::string V = "__attribute__((__vector_size__(";
     V += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
     std::string ET;
-    Print(T->getElementType(), ET);
+    print(T->getElementType(), ET);
     V += " * sizeof(" + ET + ")))) ";
     S = V + S;
     break;
@@ -288,14 +293,14 @@
   }
 }
 
-void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) { 
+void TypePrinter::printExtVector(const ExtVectorType *T, std::string &S) { 
   S += " __attribute__((ext_vector_type(";
   S += llvm::utostr_32(T->getNumElements());
   S += ")))";
-  Print(T->getElementType(), S);
+  print(T->getElementType(), S);
 }
 
-void TypePrinter::PrintFunctionProto(const FunctionProtoType *T, 
+void TypePrinter::printFunctionProto(const FunctionProtoType *T, 
                                      std::string &S) { 
   // If needed for precedence reasons, wrap the inner part in grouping parens.
   if (!S.empty())
@@ -307,7 +312,7 @@
   ParamPolicy.SuppressSpecifiers = false;
   for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
     if (i) S += ", ";
-    Print(T->getArgType(i), Tmp);
+    print(T->getArgType(i), Tmp);
     S += Tmp;
     Tmp.clear();
   }
@@ -359,7 +364,7 @@
           S += ", ";
 
         std::string ExceptionType;
-        Print(T->getExceptionType(I), ExceptionType);
+        print(T->getExceptionType(I), ExceptionType);
         S += ExceptionType;
       }
     S += ")";
@@ -367,10 +372,10 @@
 
   AppendTypeQualList(S, T->getTypeQuals());
   
-  Print(T->getResultType(), S);
+  print(T->getResultType(), S);
 }
 
-void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T, 
+void TypePrinter::printFunctionNoProto(const FunctionNoProtoType *T, 
                                        std::string &S) { 
   // If needed for precedence reasons, wrap the inner part in grouping parens.
   if (!S.empty())
@@ -379,10 +384,10 @@
   S += "()";
   if (T->getNoReturnAttr())
     S += " __attribute__((noreturn))";
-  Print(T->getResultType(), S);
+  print(T->getResultType(), S);
 }
 
-static void PrintTypeSpec(const NamedDecl *D, std::string &S) {
+static void printTypeSpec(const NamedDecl *D, std::string &S) {
   IdentifierInfo *II = D->getIdentifier();
   if (S.empty())
     S = II->getName().str();
@@ -390,16 +395,16 @@
     S = II->getName().str() + ' ' + S;
 }
 
-void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T,
+void TypePrinter::printUnresolvedUsing(const UnresolvedUsingType *T,
                                        std::string &S) {
-  PrintTypeSpec(T->getDecl(), S);
+  printTypeSpec(T->getDecl(), S);
 }
 
-void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) { 
-  PrintTypeSpec(T->getDecl(), S);
+void TypePrinter::printTypedef(const TypedefType *T, std::string &S) { 
+  printTypeSpec(T->getDecl(), S);
 }
 
-void TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) {
+void TypePrinter::printTypeOfExpr(const TypeOfExprType *T, std::string &S) {
   if (!S.empty())    // Prefix the basic type, e.g. 'typeof(e) X'.
     S = ' ' + S;
   std::string Str;
@@ -408,15 +413,15 @@
   S = "typeof " + s.str() + S;
 }
 
-void TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) { 
+void TypePrinter::printTypeOf(const TypeOfType *T, std::string &S) { 
   if (!S.empty())    // Prefix the basic type, e.g. 'typeof(t) X'.
     S = ' ' + S;
   std::string Tmp;
-  Print(T->getUnderlyingType(), Tmp);
+  print(T->getUnderlyingType(), Tmp);
   S = "typeof(" + Tmp + ")" + S;
 }
 
-void TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) { 
+void TypePrinter::printDecltype(const DecltypeType *T, std::string &S) { 
   if (!S.empty())    // Prefix the basic type, e.g. 'decltype(t) X'.
     S = ' ' + S;
   std::string Str;
@@ -458,7 +463,7 @@
     Buffer += "::";
 }
 
-void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) {
+void TypePrinter::printTag(TagDecl *D, std::string &InnerString) {
   if (Policy.SuppressTag)
     return;
 
@@ -538,15 +543,15 @@
   std::swap(Buffer, InnerString);
 }
 
-void TypePrinter::PrintRecord(const RecordType *T, std::string &S) {
-  PrintTag(T->getDecl(), S);
+void TypePrinter::printRecord(const RecordType *T, std::string &S) {
+  printTag(T->getDecl(), S);
 }
 
-void TypePrinter::PrintEnum(const EnumType *T, std::string &S) { 
-  PrintTag(T->getDecl(), S);
+void TypePrinter::printEnum(const EnumType *T, std::string &S) { 
+  printTag(T->getDecl(), S);
 }
 
-void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T, 
+void TypePrinter::printTemplateTypeParm(const TemplateTypeParmType *T, 
                                         std::string &S) { 
   if (!S.empty())    // Prefix the basic type, e.g. 'parmname X'.
     S = ' ' + S;
@@ -558,12 +563,12 @@
     S = T->getName()->getName().str() + S;  
 }
 
-void TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T, 
+void TypePrinter::printSubstTemplateTypeParm(const SubstTemplateTypeParmType *T, 
                                              std::string &S) { 
-  Print(T->getReplacementType(), S);
+  print(T->getReplacementType(), S);
 }
 
-void TypePrinter::PrintTemplateSpecialization(
+void TypePrinter::printTemplateSpecialization(
                                             const TemplateSpecializationType *T, 
                                               std::string &S) { 
   std::string SpecString;
@@ -583,12 +588,12 @@
     S = SpecString + ' ' + S;
 }
 
-void TypePrinter::PrintInjectedClassName(const InjectedClassNameType *T,
+void TypePrinter::printInjectedClassName(const InjectedClassNameType *T,
                                          std::string &S) {
-  PrintTemplateSpecialization(T->getInjectedTST(), S);
+  printTemplateSpecialization(T->getInjectedTST(), S);
 }
 
-void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) {
+void TypePrinter::printElaborated(const ElaboratedType *T, std::string &S) {
   std::string MyString;
   
   {
@@ -604,7 +609,7 @@
   std::string TypeStr;
   PrintingPolicy InnerPolicy(Policy);
   InnerPolicy.SuppressScope = true;
-  TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr);
+  TypePrinter(InnerPolicy).print(T->getNamedType(), TypeStr);
   
   MyString += TypeStr;
   if (S.empty())
@@ -613,7 +618,7 @@
     S = MyString + ' ' + S;  
 }
 
-void TypePrinter::PrintDependentName(const DependentNameType *T, std::string &S) { 
+void TypePrinter::printDependentName(const DependentNameType *T, std::string &S) { 
   std::string MyString;
   
   {
@@ -633,7 +638,7 @@
     S = MyString + ' ' + S;
 }
 
-void TypePrinter::PrintDependentTemplateSpecialization(
+void TypePrinter::printDependentTemplateSpecialization(
         const DependentTemplateSpecializationType *T, std::string &S) { 
   std::string MyString;
   {
@@ -657,7 +662,7 @@
     S = MyString + ' ' + S;
 }
 
-void TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T, 
+void TypePrinter::printObjCInterface(const ObjCInterfaceType *T, 
                                      std::string &S) { 
   if (!S.empty())    // Prefix the basic type, e.g. 'typedefname X'.
     S = ' ' + S;
@@ -666,13 +671,13 @@
   S = ObjCQIString + S;
 }
 
-void TypePrinter::PrintObjCObject(const ObjCObjectType *T,
+void TypePrinter::printObjCObject(const ObjCObjectType *T,
                                   std::string &S) {
   if (T->qual_empty())
-    return Print(T->getBaseType(), S);
+    return print(T->getBaseType(), S);
 
   std::string tmp;
-  Print(T->getBaseType(), tmp);
+  print(T->getBaseType(), tmp);
   tmp += '<';
   bool isFirst = true;
   for (ObjCObjectType::qual_iterator
@@ -692,7 +697,7 @@
   std::swap(tmp, S);
 }
 
-void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T, 
+void TypePrinter::printObjCObjectPointer(const ObjCObjectPointerType *T, 
                                          std::string &S) { 
   std::string ObjCQIString;
   
@@ -730,7 +735,7 @@
   S = ObjCQIString + S;  
 }
 
-static void PrintTemplateArgument(std::string &Buffer,
+static void printTemplateArgument(std::string &Buffer,
                                   const TemplateArgument &Arg,
                                   const PrintingPolicy &Policy) {
   switch (Arg.getKind()) {
@@ -789,7 +794,7 @@
     
     // Print the argument into a string.
     std::string ArgString;
-    PrintTemplateArgument(ArgString, Args[Arg], Policy);
+    printTemplateArgument(ArgString, Args[Arg], Policy);
     
     // If this is the first argument and its string representation
     // begins with the global scope specifier ('::foo'), add a space
@@ -823,7 +828,7 @@
     
     // Print the argument into a string.
     std::string ArgString;
-    PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
+    printTemplateArgument(ArgString, Args[Arg].getArgument(), Policy);
     
     // If this is the first argument and its string representation
     // begins with the global scope specifier ('::foo'), add a space
@@ -889,15 +894,15 @@
   }
 }
 
-std::string QualType::getAsString() const {
-  std::string S;
-  LangOptions LO;
-  getAsStringInternal(S, PrintingPolicy(LO));
-  return S;
+std::string QualType::getAsString(const Type *ty, Qualifiers qs) {
+  std::string buffer;
+  LangOptions options;
+  getAsStringInternal(ty, qs, buffer, PrintingPolicy(options));
+  return buffer;
 }
 
-void QualType::getAsStringInternal(std::string &S,
-                                   const PrintingPolicy &Policy) const {
-  TypePrinter Printer(Policy);
-  Printer.Print(*this, S);
+void QualType::getAsStringInternal(const Type *ty, Qualifiers qs,
+                                   std::string &buffer,
+                                   const PrintingPolicy &policy) {
+  TypePrinter(policy).print(ty, qs, buffer);
 }