//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code to print types from Clang's type system.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;

namespace {
  class TypePrinter {
    PrintingPolicy Policy;

  public:
    explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { }
    
    void Print(QualType T, std::string &S);
    void PrintTag(const TagType *T, std::string &S);
#define ABSTRACT_TYPE(CLASS, PARENT)
#define TYPE(CLASS, PARENT) \
  void Print##CLASS(const CLASS##Type *T, std::string &S);
#include "clang/AST/TypeNodes.def"
  };
}

static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
  if (TypeQuals & Qualifiers::Const) {
    if (!S.empty()) S += ' ';
    S += "const";
  }
  if (TypeQuals & Qualifiers::Volatile) {
    if (!S.empty()) S += ' ';
    S += "volatile";
  }
  if (TypeQuals & Qualifiers::Restrict) {
    if (!S.empty()) S += ' ';
    S += "restrict";
  }
}

void TypePrinter::Print(QualType T, std::string &S) {
  if (T.isNull()) {
    S += "NULL TYPE";
    return;
  }
  
  if (Policy.SuppressSpecifiers && T->isSpecifierType())
    return;
  
  // Print qualifiers as appropriate.
  Qualifiers Quals = T.getLocalQualifiers();
  if (!Quals.empty()) {
    std::string TQS;
    Quals.getAsStringInternal(TQS, Policy);
    
    if (!S.empty()) {
      TQS += ' ';
      TQS += S;
    }
    std::swap(S, TQS);
  }
  
  switch (T->getTypeClass()) {
#define ABSTRACT_TYPE(CLASS, PARENT)
#define TYPE(CLASS, PARENT) case Type::CLASS:                \
    Print##CLASS(cast<CLASS##Type>(T.getTypePtr()), S);      \
    break;
#include "clang/AST/TypeNodes.def"
  }
}

void TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) {
  if (S.empty()) {
    S = T->getName(Policy.LangOpts);
  } else {
    // Prefix the basic type, e.g. 'int X'.
    S = ' ' + S;
    S = T->getName(Policy.LangOpts) + 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) { 
  S = '*' + S;
  
  // Handle things like 'int (*A)[4];' correctly.
  // FIXME: this should include vectors, but vectors use attributes I guess.
  if (isa<ArrayType>(T->getPointeeType()))
    S = '(' + S + ')';
  
  Print(T->getPointeeType(), S);
}

void TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) {
  S = '^' + S;
  Print(T->getPointeeType(), S);
}

void TypePrinter::PrintLValueReference(const LValueReferenceType *T, 
                                       std::string &S) { 
  S = '&' + S;
  
  // Handle things like 'int (&A)[4];' correctly.
  // FIXME: this should include vectors, but vectors use attributes I guess.
  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
    S = '(' + S + ')';
  
  Print(T->getPointeeTypeAsWritten(), S);
}

void TypePrinter::PrintRValueReference(const RValueReferenceType *T, 
                                       std::string &S) { 
  S = "&&" + S;
  
  // Handle things like 'int (&&A)[4];' correctly.
  // FIXME: this should include vectors, but vectors use attributes I guess.
  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
    S = '(' + S + ')';
  
  Print(T->getPointeeTypeAsWritten(), S);
}

void TypePrinter::PrintMemberPointer(const MemberPointerType *T, 
                                     std::string &S) { 
  std::string C;
  Print(QualType(T->getClass(), 0), C);
  C += "::*";
  S = C + S;
  
  // Handle things like 'int (Cls::*A)[4];' correctly.
  // FIXME: this should include vectors, but vectors use attributes I guess.
  if (isa<ArrayType>(T->getPointeeType()))
    S = '(' + S + ')';
  
  Print(T->getPointeeType(), S);
}

void TypePrinter::PrintConstantArray(const ConstantArrayType *T, 
                                     std::string &S) {
  S += '[';
  S += llvm::utostr(T->getSize().getZExtValue());
  S += ']';
  
  Print(T->getElementType(), S);
}

void TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T, 
                                       std::string &S) {
  S += "[]";
  Print(T->getElementType(), S);
}

void TypePrinter::PrintVariableArray(const VariableArrayType *T, 
                                     std::string &S) { 
  S += '[';
  
  if (T->getIndexTypeQualifiers().hasQualifiers()) {
    AppendTypeQualList(S, T->getIndexTypeCVRQualifiers());
    S += ' ';
  }
  
  if (T->getSizeModifier() == VariableArrayType::Static)
    S += "static";
  else if (T->getSizeModifier() == VariableArrayType::Star)
    S += '*';
  
  if (T->getSizeExpr()) {
    std::string SStr;
    llvm::raw_string_ostream s(SStr);
    T->getSizeExpr()->printPretty(s, 0, Policy);
    S += s.str();
  }
  S += ']';
  
  Print(T->getElementType(), S);
}

void TypePrinter::PrintDependentSizedArray(const DependentSizedArrayType *T, 
                                           std::string &S) {  
  S += '[';
  
  if (T->getSizeExpr()) {
    std::string SStr;
    llvm::raw_string_ostream s(SStr);
    T->getSizeExpr()->printPretty(s, 0, Policy);
    S += s.str();
  }
  S += ']';
  
  Print(T->getElementType(), S);
}

void TypePrinter::PrintDependentSizedExtVector(
                                          const DependentSizedExtVectorType *T, 
                                               std::string &S) { 
  Print(T->getElementType(), S);
  
  S += " __attribute__((ext_vector_type(";
  if (T->getSizeExpr()) {
    std::string SStr;
    llvm::raw_string_ostream s(SStr);
    T->getSizeExpr()->printPretty(s, 0, Policy);
    S += s.str();
  }
  S += ")))";  
}

void TypePrinter::PrintVector(const VectorType *T, std::string &S) { 
  if (T->isAltiVec()) {
    if (T->isPixel())
      S = "__vector __pixel " + S;
    else {
      Print(T->getElementType(), S);
      S = "__vector " + S;
    }
  } else {
    // FIXME: We prefer to print the size directly here, but have no way
    // to get the size of the type.
    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);
    V += " * sizeof(" + ET + ")))) ";
    S = V + 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);
}

void TypePrinter::PrintFunctionProto(const FunctionProtoType *T, 
                                     std::string &S) { 
  // If needed for precedence reasons, wrap the inner part in grouping parens.
  if (!S.empty())
    S = "(" + S + ")";
  
  S += "(";
  std::string Tmp;
  PrintingPolicy ParamPolicy(Policy);
  ParamPolicy.SuppressSpecifiers = false;
  for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
    if (i) S += ", ";
    Print(T->getArgType(i), Tmp);
    S += Tmp;
    Tmp.clear();
  }
  
  if (T->isVariadic()) {
    if (T->getNumArgs())
      S += ", ";
    S += "...";
  } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
    // Do not emit int() if we have a proto, emit 'int(void)'.
    S += "void";
  }
  
  S += ")";

  switch(T->getCallConv()) {
  case CC_Default:
  default: break;
  case CC_C:
    S += " __attribute__((cdecl))";
    break;
  case CC_X86StdCall:
    S += " __attribute__((stdcall))";
    break;
  case CC_X86FastCall:
    S += " __attribute__((fastcall))";
    break;
  }
  if (T->getNoReturnAttr())
    S += " __attribute__((noreturn))";

  
  if (T->hasExceptionSpec()) {
    S += " throw(";
    if (T->hasAnyExceptionSpec())
      S += "...";
    else 
      for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) {
        if (I)
          S += ", ";

        std::string ExceptionType;
        Print(T->getExceptionType(I), ExceptionType);
        S += ExceptionType;
      }
    S += ")";
  }

  AppendTypeQualList(S, T->getTypeQuals());
  
  Print(T->getResultType(), S);
}

void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T, 
                                       std::string &S) { 
  // If needed for precedence reasons, wrap the inner part in grouping parens.
  if (!S.empty())
    S = "(" + S + ")";
  
  S += "()";
  if (T->getNoReturnAttr())
    S += " __attribute__((noreturn))";
  Print(T->getResultType(), S);
}

void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T,
                                       std::string &S) {
  IdentifierInfo *II = T->getDecl()->getIdentifier();
  if (S.empty())
    S = II->getName().str();
  else
    S = II->getName().str() + ' ' + S;
}

void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) { 
  if (!S.empty())    // Prefix the basic type, e.g. 'typedefname X'.
    S = ' ' + S;
  S = T->getDecl()->getIdentifier()->getName().str() + 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;
  llvm::raw_string_ostream s(Str);
  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
  S = "typeof " + s.str() + 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);
  S = "typeof(" + Tmp + ")" + 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;
  llvm::raw_string_ostream s(Str);
  T->getUnderlyingExpr()->printPretty(s, 0, Policy);
  S = "decltype(" + s.str() + ")" + S;
}

void TypePrinter::PrintTag(const TagType *T, std::string &InnerString) {
  if (Policy.SuppressTag)
    return;
  
  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
    InnerString = ' ' + InnerString;
  
  const char *Kind = Policy.SuppressTagKind? 0 : T->getDecl()->getKindName();
  const char *ID;
  if (const IdentifierInfo *II = T->getDecl()->getIdentifier())
    ID = II->getNameStart();
  else if (TypedefDecl *Typedef = T->getDecl()->getTypedefForAnonDecl()) {
    Kind = 0;
    assert(Typedef->getIdentifier() && "Typedef without identifier?");
    ID = Typedef->getIdentifier()->getNameStart();
  } else
    ID = "<anonymous>";
  
  // If this is a class template specialization, print the template
  // arguments.
  if (ClassTemplateSpecializationDecl *Spec
      = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
    std::string TemplateArgsStr
      = TemplateSpecializationType::PrintTemplateArgumentList(
                                            TemplateArgs.getFlatArgumentList(),
                                            TemplateArgs.flat_size(),
                                            Policy);
    InnerString = TemplateArgsStr + InnerString;
  }
  
  if (!Policy.SuppressScope) {
    // Compute the full nested-name-specifier for this type. In C,
    // this will always be empty.
    std::string ContextStr;
    for (DeclContext *DC = T->getDecl()->getDeclContext();
         !DC->isTranslationUnit(); DC = DC->getParent()) {
      std::string MyPart;
      if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
        if (NS->getIdentifier())
          MyPart = NS->getNameAsString();
      } else if (ClassTemplateSpecializationDecl *Spec
                  = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
        const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
        std::string TemplateArgsStr
          = TemplateSpecializationType::PrintTemplateArgumentList(
                                            TemplateArgs.getFlatArgumentList(),
                                            TemplateArgs.flat_size(),
                                            Policy);
        MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr;
      } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
        if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
          MyPart = Typedef->getIdentifier()->getName();
        else if (Tag->getIdentifier())
          MyPart = Tag->getIdentifier()->getName();
      }
      
      if (!MyPart.empty())
        ContextStr = MyPart + "::" + ContextStr;
    }
    
    if (Kind)
      InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString;
    else
      InnerString = ContextStr + ID + InnerString;
  } else
    InnerString = ID + InnerString;  
}

void TypePrinter::PrintRecord(const RecordType *T, std::string &S) {
  PrintTag(T, S);
}

void TypePrinter::PrintEnum(const EnumType *T, std::string &S) { 
  PrintTag(T, S);
}

void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) { 
  std::string TypeStr;
  PrintingPolicy InnerPolicy(Policy);
  InnerPolicy.SuppressTagKind = true;
  TypePrinter(InnerPolicy).Print(T->getUnderlyingType(), S);
  
  S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S;  
}

void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T, 
                                        std::string &S) { 
  if (!S.empty())    // Prefix the basic type, e.g. 'parmname X'.
    S = ' ' + S;
  
  if (!T->getName())
    S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' +
        llvm::utostr_32(T->getIndex()) + S;
  else
    S = T->getName()->getName().str() + S;  
}

void TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T, 
                                             std::string &S) { 
  Print(T->getReplacementType(), S);
}

void TypePrinter::PrintTemplateSpecialization(
                                            const TemplateSpecializationType *T, 
                                              std::string &S) { 
  std::string SpecString;
  
  {
    llvm::raw_string_ostream OS(SpecString);
    T->getTemplateName().print(OS, Policy);
  }
  
  SpecString += TemplateSpecializationType::PrintTemplateArgumentList(
                                                                  T->getArgs(), 
                                                                T->getNumArgs(), 
                                                                      Policy);
  if (S.empty())
    S.swap(SpecString);
  else
    S = SpecString + ' ' + S;
}

void TypePrinter::PrintQualifiedName(const QualifiedNameType *T, 
                                     std::string &S) { 
  std::string MyString;
  
  {
    llvm::raw_string_ostream OS(MyString);
    T->getQualifier()->print(OS, Policy);
  }
  
  std::string TypeStr;
  PrintingPolicy InnerPolicy(Policy);
  InnerPolicy.SuppressTagKind = true;
  InnerPolicy.SuppressScope = true;
  TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr);
  
  MyString += TypeStr;
  if (S.empty())
    S.swap(MyString);
  else
    S = MyString + ' ' + S;  
}

void TypePrinter::PrintTypename(const TypenameType *T, std::string &S) { 
  std::string MyString;
  
  {
    llvm::raw_string_ostream OS(MyString);
    OS << "typename ";
    T->getQualifier()->print(OS, Policy);
    
    if (const IdentifierInfo *Ident = T->getIdentifier())
      OS << Ident->getName();
    else if (const TemplateSpecializationType *Spec = T->getTemplateId()) {
      Spec->getTemplateName().print(OS, Policy, true);
      OS << TemplateSpecializationType::PrintTemplateArgumentList(
                                                            Spec->getArgs(),
                                                            Spec->getNumArgs(),
                                                            Policy);
    }
  }
  
  if (S.empty())
    S.swap(MyString);
  else
    S = MyString + ' ' + S;
}

void TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T, 
                                     std::string &S) { 
  if (!S.empty())    // Prefix the basic type, e.g. 'typedefname X'.
    S = ' ' + S;
  
  std::string ObjCQIString = T->getDecl()->getNameAsString();
  if (T->getNumProtocols()) {
    ObjCQIString += '<';
    bool isFirst = true;
    for (ObjCInterfaceType::qual_iterator I = T->qual_begin(), 
                                          E = T->qual_end(); 
         I != E; ++I) {
      if (isFirst)
        isFirst = false;
      else
        ObjCQIString += ',';
      ObjCQIString += (*I)->getNameAsString();
    }
    ObjCQIString += '>';
  }
  S = ObjCQIString + S;
}

void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T, 
                                         std::string &S) { 
  std::string ObjCQIString;
  
  if (T->isObjCIdType() || T->isObjCQualifiedIdType())
    ObjCQIString = "id";
  else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
    ObjCQIString = "Class";
  else if (T->isObjCSelType())
    ObjCQIString = "SEL";
  else
    ObjCQIString = T->getInterfaceDecl()->getNameAsString();
  
  if (!T->qual_empty()) {
    ObjCQIString += '<';
    for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(), 
                                              E = T->qual_end();
         I != E; ++I) {
      ObjCQIString += (*I)->getNameAsString();
      if (I+1 != E)
        ObjCQIString += ',';
    }
    ObjCQIString += '>';
  }
  
  T->getPointeeType().getLocalQualifiers().getAsStringInternal(ObjCQIString, 
                                                               Policy);
  
  if (!T->isObjCIdType() && !T->isObjCQualifiedIdType())
    ObjCQIString += " *"; // Don't forget the implicit pointer.
  else if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
    S = ' ' + S;
  
  S = ObjCQIString + S;  
}

static void PrintTemplateArgument(std::string &Buffer,
                                  const TemplateArgument &Arg,
                                  const PrintingPolicy &Policy) {
  switch (Arg.getKind()) {
    case TemplateArgument::Null:
      assert(false && "Null template argument");
      break;
      
    case TemplateArgument::Type:
      Arg.getAsType().getAsStringInternal(Buffer, Policy);
      break;
      
    case TemplateArgument::Declaration:
      Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString();
      break;
      
    case TemplateArgument::Template: {
      llvm::raw_string_ostream s(Buffer);
      Arg.getAsTemplate().print(s, Policy);
      break;
    }
      
    case TemplateArgument::Integral:
      Buffer = Arg.getAsIntegral()->toString(10, true);
      break;
      
    case TemplateArgument::Expression: {
      llvm::raw_string_ostream s(Buffer);
      Arg.getAsExpr()->printPretty(s, 0, Policy);
      break;
    }
      
    case TemplateArgument::Pack:
      assert(0 && "FIXME: Implement!");
      break;
  }
}

std::string TemplateSpecializationType::
  PrintTemplateArgumentList(const TemplateArgumentListInfo &Args,
                            const PrintingPolicy &Policy) {
  return PrintTemplateArgumentList(Args.getArgumentArray(),
                                   Args.size(),
                                   Policy);
}

std::string
TemplateSpecializationType::PrintTemplateArgumentList(
                                                const TemplateArgument *Args,
                                                unsigned NumArgs,
                                                const PrintingPolicy &Policy) {
  std::string SpecString;
  SpecString += '<';
  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
    if (Arg)
      SpecString += ", ";
    
    // Print the argument into a string.
    std::string ArgString;
    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
    // to avoid printing the diagraph '<:'.
    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
      SpecString += ' ';
    
    SpecString += ArgString;
  }
  
  // If the last character of our string is '>', add another space to
  // keep the two '>''s separate tokens. We don't *have* to do this in
  // C++0x, but it's still good hygiene.
  if (SpecString[SpecString.size() - 1] == '>')
    SpecString += ' ';
  
  SpecString += '>';
  
  return SpecString;
}

// Sadly, repeat all that with TemplateArgLoc.
std::string TemplateSpecializationType::
PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
                          const PrintingPolicy &Policy) {
  std::string SpecString;
  SpecString += '<';
  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
    if (Arg)
      SpecString += ", ";
    
    // Print the argument into a string.
    std::string ArgString;
    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
    // to avoid printing the diagraph '<:'.
    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
      SpecString += ' ';
    
    SpecString += ArgString;
  }
  
  // If the last character of our string is '>', add another space to
  // keep the two '>''s separate tokens. We don't *have* to do this in
  // C++0x, but it's still good hygiene.
  if (SpecString[SpecString.size() - 1] == '>')
    SpecString += ' ';
  
  SpecString += '>';
  
  return SpecString;
}

void QualType::dump(const char *msg) const {
  std::string R = "identifier";
  LangOptions LO;
  getAsStringInternal(R, PrintingPolicy(LO));
  if (msg)
    llvm::errs() << msg << ": ";
  llvm::errs() << R << "\n";
}
void QualType::dump() const {
  dump("");
}

void Type::dump() const {
  QualType(this, 0).dump();
}

std::string Qualifiers::getAsString() const {
  LangOptions LO;
  return getAsString(PrintingPolicy(LO));
}

// Appends qualifiers to the given string, separated by spaces.  Will
// prefix a space if the string is non-empty.  Will not append a final
// space.
void Qualifiers::getAsStringInternal(std::string &S,
                                     const PrintingPolicy&) const {
  AppendTypeQualList(S, getCVRQualifiers());
  if (unsigned AddressSpace = getAddressSpace()) {
    if (!S.empty()) S += ' ';
    S += "__attribute__((address_space(";
    S += llvm::utostr_32(AddressSpace);
    S += ")))";
  }
  if (Qualifiers::GC GCAttrType = getObjCGCAttr()) {
    if (!S.empty()) S += ' ';
    S += "__attribute__((objc_gc(";
    if (GCAttrType == Qualifiers::Weak)
      S += "weak";
    else
      S += "strong";
    S += ")))";
  }
}

std::string QualType::getAsString() const {
  std::string S;
  LangOptions LO;
  getAsStringInternal(S, PrintingPolicy(LO));
  return S;
}

void QualType::getAsStringInternal(std::string &S,
                                   const PrintingPolicy &Policy) const {
  TypePrinter Printer(Policy);
  Printer.Print(*this, S);
}

