1fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===//
2fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//
3fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//                     The LLVM Compiler Infrastructure
4fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//
5fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// This file is distributed under the University of Illinois Open Source
6fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// License. See LICENSE.TXT for details.
7fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//
8fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//===----------------------------------------------------------------------===//
9fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//
10fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// This contains code to print types from Clang's type system.
11fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//
12fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor//===----------------------------------------------------------------------===//
13fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
14471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer#include "clang/AST/ASTContext.h"
15fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/Decl.h"
16fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/DeclObjC.h"
17fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/DeclTemplate.h"
18fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/Expr.h"
19fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/Type.h"
20fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/PrettyPrinter.h"
21fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/Basic/LangOptions.h"
2273061d054128e486e70e0f2874b23d6eca067e5bJohn McCall#include "clang/Basic/SourceManager.h"
237ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis#include "llvm/ADT/SmallString.h"
24fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "llvm/ADT/StringExtras.h"
25fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "llvm/Support/raw_ostream.h"
267ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis#include "llvm/Support/SaveAndRestore.h"
27fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorusing namespace clang;
28fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
29fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregornamespace {
30f85e193739c953358c865005855253af4f68a497John McCall  /// \brief RAII object that enables printing of the ARC __strong lifetime
31f85e193739c953358c865005855253af4f68a497John McCall  /// qualifier.
32f85e193739c953358c865005855253af4f68a497John McCall  class IncludeStrongLifetimeRAII {
33f85e193739c953358c865005855253af4f68a497John McCall    PrintingPolicy &Policy;
34f85e193739c953358c865005855253af4f68a497John McCall    bool Old;
35f85e193739c953358c865005855253af4f68a497John McCall
36f85e193739c953358c865005855253af4f68a497John McCall  public:
37f85e193739c953358c865005855253af4f68a497John McCall    explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)
38f85e193739c953358c865005855253af4f68a497John McCall      : Policy(Policy), Old(Policy.SuppressStrongLifetime) {
39f85e193739c953358c865005855253af4f68a497John McCall      Policy.SuppressStrongLifetime = false;
40f85e193739c953358c865005855253af4f68a497John McCall    }
41f85e193739c953358c865005855253af4f68a497John McCall
42f85e193739c953358c865005855253af4f68a497John McCall    ~IncludeStrongLifetimeRAII() {
43f85e193739c953358c865005855253af4f68a497John McCall      Policy.SuppressStrongLifetime = Old;
44f85e193739c953358c865005855253af4f68a497John McCall    }
45f85e193739c953358c865005855253af4f68a497John McCall  };
467ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
477ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  class ParamPolicyRAII {
487ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    PrintingPolicy &Policy;
497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    bool Old;
507ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
517ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  public:
527ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    explicit ParamPolicyRAII(PrintingPolicy &Policy)
537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      : Policy(Policy), Old(Policy.SuppressSpecifiers) {
547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Policy.SuppressSpecifiers = false;
557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    }
567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
577ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    ~ParamPolicyRAII() {
587ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Policy.SuppressSpecifiers = Old;
597ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    }
607ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  };
617ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
627ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  class ElaboratedTypePolicyRAII {
637ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    PrintingPolicy &Policy;
647ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    bool SuppressTagKeyword;
657ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    bool SuppressScope;
667ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
677ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  public:
687ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {
697ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      SuppressTagKeyword = Policy.SuppressTagKeyword;
707ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      SuppressScope = Policy.SuppressScope;
717ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Policy.SuppressTagKeyword = true;
727ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Policy.SuppressScope = true;
737ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    }
747ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
757ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    ~ElaboratedTypePolicyRAII() {
767ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Policy.SuppressTagKeyword = SuppressTagKeyword;
777ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Policy.SuppressScope = SuppressScope;
787ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    }
797ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  };
80f85e193739c953358c865005855253af4f68a497John McCall
81fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  class TypePrinter {
82fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    PrintingPolicy Policy;
837ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    bool HasEmptyPlaceHolder;
84fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
85fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  public:
867ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    explicit TypePrinter(const PrintingPolicy &Policy)
877ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      : Policy(Policy), HasEmptyPlaceHolder(false) { }
887ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
897ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
907ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis               StringRef PlaceHolder);
917ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void print(QualType T, raw_ostream &OS, StringRef PlaceHolder);
927ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
937ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier);
947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void spaceBeforePlaceHolder(raw_ostream &OS);
957ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void printTypeSpec(const NamedDecl *D, raw_ostream &OS);
967ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
977ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);
987ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void printBefore(QualType T, raw_ostream &OS);
997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);
1007ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void printAfter(QualType T, raw_ostream &OS);
1017ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void AppendScope(DeclContext *DC, raw_ostream &OS);
1027ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void printTag(TagDecl *T, raw_ostream &OS);
103fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#define ABSTRACT_TYPE(CLASS, PARENT)
104fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#define TYPE(CLASS, PARENT) \
1057ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
1067ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);
107fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/TypeNodes.def"
108fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  };
109fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
110fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1117ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisstatic void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals) {
1127ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  bool appendSpace = false;
113fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (TypeQuals & Qualifiers::Const) {
1147ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "const";
1157ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    appendSpace = true;
116fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
117fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (TypeQuals & Qualifiers::Volatile) {
1187ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (appendSpace) OS << ' ';
1197ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "volatile";
1207ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    appendSpace = true;
121fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
122fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (TypeQuals & Qualifiers::Restrict) {
1237ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (appendSpace) OS << ' ';
1247ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "restrict";
125fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
126fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
127fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1287ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {
1297ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (!HasEmptyPlaceHolder)
1307ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ' ';
1317ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
1327ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
1337ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {
13449f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall  SplitQualType split = t.split();
1357ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  print(split.Ty, split.Quals, OS, PlaceHolder);
13649f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall}
13749f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall
1387ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
1397ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                        StringRef PlaceHolder) {
14049f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall  if (!T) {
1417ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "NULL TYPE";
142fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    return;
143fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
144fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
145fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (Policy.SuppressSpecifiers && T->isSpecifierType())
146fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    return;
1477ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
1487ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());
1497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
1507ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T, Quals, OS);
1517ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << PlaceHolder;
1527ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T, Quals, OS);
1537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
1547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
1557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisbool TypePrinter::canPrefixQualifiers(const Type *T,
1567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                      bool &NeedARCStrongQualifier) {
15758f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner  // CanPrefixQualifiers - We prefer to print type qualifiers before the type,
15858f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner  // so that we get "const int" instead of "int const", but we can't do this if
15958f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner  // the type is complex.  For example if the type is "int*", we *must* print
16058f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner  // "int * const", printing "const int *" is different.  Only do this when the
16158f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner  // type expands to a simple string.
162c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor  bool CanPrefixQualifiers = false;
1637ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  NeedARCStrongQualifier = false;
164c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor  Type::TypeClass TC = T->getTypeClass();
16534b41d939a1328f484511c6002ba2456db879a29Richard Smith  if (const AutoType *AT = dyn_cast<AutoType>(T))
16634b41d939a1328f484511c6002ba2456db879a29Richard Smith    TC = AT->desugar()->getTypeClass();
167c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor  if (const SubstTemplateTypeParmType *Subst
168c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor                                      = dyn_cast<SubstTemplateTypeParmType>(T))
169c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    TC = Subst->getReplacementType()->getTypeClass();
170c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor
171c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor  switch (TC) {
172c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::Builtin:
173c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::Complex:
174c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::UnresolvedUsing:
175c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::Typedef:
176c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::TypeOfExpr:
177c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::TypeOf:
178c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::Decltype:
179ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt    case Type::UnaryTransform:
180c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::Record:
181c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::Enum:
182c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::Elaborated:
183c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::TemplateTypeParm:
184c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::SubstTemplateTypeParmPack:
185c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::TemplateSpecialization:
186c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::InjectedClassName:
187c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::DependentName:
188c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::DependentTemplateSpecialization:
189c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::ObjCObject:
190c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::ObjCInterface:
191b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman    case Type::Atomic:
192c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor      CanPrefixQualifiers = true;
193c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor      break;
194c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor
195c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::ObjCObjectPointer:
196c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor      CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||
197c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor        T->isObjCQualifiedIdType() || T->isObjCQualifiedClassType();
198c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor      break;
199c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor
200f85e193739c953358c865005855253af4f68a497John McCall    case Type::ConstantArray:
201f85e193739c953358c865005855253af4f68a497John McCall    case Type::IncompleteArray:
202f85e193739c953358c865005855253af4f68a497John McCall    case Type::VariableArray:
203f85e193739c953358c865005855253af4f68a497John McCall    case Type::DependentSizedArray:
204f85e193739c953358c865005855253af4f68a497John McCall      NeedARCStrongQualifier = true;
205f85e193739c953358c865005855253af4f68a497John McCall      // Fall through
206f85e193739c953358c865005855253af4f68a497John McCall
207c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::Pointer:
208c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::BlockPointer:
209c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::LValueReference:
210c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::RValueReference:
211c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::MemberPointer:
212c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::DependentSizedExtVector:
213c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::Vector:
214c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::ExtVector:
215c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::FunctionProto:
216c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::FunctionNoProto:
217c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::Paren:
218c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::Attributed:
219c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::PackExpansion:
220c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor    case Type::SubstTemplateTypeParm:
22134b41d939a1328f484511c6002ba2456db879a29Richard Smith    case Type::Auto:
222c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor      CanPrefixQualifiers = false;
223c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor      break;
224c6daf0b29d6c48a99cb1ad707973a7e6dfcafd58Douglas Gregor  }
2257ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
2267ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  return CanPrefixQualifiers;
2277ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
2287ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
229838925dc841f0968ac5daf941aed5d2331775a59Richard Smithvoid TypePrinter::printBefore(QualType T, raw_ostream &OS) {
230838925dc841f0968ac5daf941aed5d2331775a59Richard Smith  SplitQualType Split = T.split();
231838925dc841f0968ac5daf941aed5d2331775a59Richard Smith
232838925dc841f0968ac5daf941aed5d2331775a59Richard Smith  // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2
233838925dc841f0968ac5daf941aed5d2331775a59Richard Smith  // at this level.
234838925dc841f0968ac5daf941aed5d2331775a59Richard Smith  Qualifiers Quals = Split.Quals;
235838925dc841f0968ac5daf941aed5d2331775a59Richard Smith  if (const SubstTemplateTypeParmType *Subst =
236838925dc841f0968ac5daf941aed5d2331775a59Richard Smith        dyn_cast<SubstTemplateTypeParmType>(Split.Ty))
237838925dc841f0968ac5daf941aed5d2331775a59Richard Smith    Quals -= QualType(Subst, 0).getQualifiers();
238838925dc841f0968ac5daf941aed5d2331775a59Richard Smith
239838925dc841f0968ac5daf941aed5d2331775a59Richard Smith  printBefore(Split.Ty, Quals, OS);
2407ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
2417ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
2427ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis/// \brief Prints the part of the type string before an identifier, e.g. for
2437ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis/// "int foo[10]" it prints "int ".
2447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {
2457ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (Policy.SuppressSpecifiers && T->isSpecifierType())
2467ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    return;
2477ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
2487ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder);
2497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
2507ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // Print qualifiers as appropriate.
2517ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
2527ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  bool CanPrefixQualifiers = false;
2537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  bool NeedARCStrongQualifier = false;
2547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);
2557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
2567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (CanPrefixQualifiers && !Quals.empty()) {
257f85e193739c953358c865005855253af4f68a497John McCall    if (NeedARCStrongQualifier) {
258f85e193739c953358c865005855253af4f68a497John McCall      IncludeStrongLifetimeRAII Strong(Policy);
2597ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
260f85e193739c953358c865005855253af4f68a497John McCall    } else {
2617ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
262fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    }
263fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
2647ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
2657ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  bool hasAfterQuals = false;
2667ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (!CanPrefixQualifiers && !Quals.empty()) {
2677ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);
2687ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (hasAfterQuals)
2697ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      HasEmptyPlaceHolder = false;
2707ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  }
2717ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
272fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  switch (T->getTypeClass()) {
273fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#define ABSTRACT_TYPE(CLASS, PARENT)
27449f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall#define TYPE(CLASS, PARENT) case Type::CLASS: \
2757ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    print##CLASS##Before(cast<CLASS##Type>(T), OS); \
276fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    break;
277fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor#include "clang/AST/TypeNodes.def"
278fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
2797ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
2807ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (hasAfterQuals) {
281f85e193739c953358c865005855253af4f68a497John McCall    if (NeedARCStrongQualifier) {
282f85e193739c953358c865005855253af4f68a497John McCall      IncludeStrongLifetimeRAII Strong(Policy);
2837ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
284f85e193739c953358c865005855253af4f68a497John McCall    } else {
2857ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());
28658f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner    }
28758f9e13e87e57236fee4b914eea9be6f92a1c345Chris Lattner  }
288fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
289fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
2907ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printAfter(QualType t, raw_ostream &OS) {
2917ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SplitQualType split = t.split();
2927ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(split.Ty, split.Quals, OS);
2937ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
2947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
2957ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis/// \brief Prints the part of the type string after an identifier, e.g. for
2967ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis/// "int foo[10]" it prints "[10]".
2977ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {
2987ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  switch (T->getTypeClass()) {
2997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis#define ABSTRACT_TYPE(CLASS, PARENT)
3007ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis#define TYPE(CLASS, PARENT) case Type::CLASS: \
3017ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    print##CLASS##After(cast<CLASS##Type>(T), OS); \
3027ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    break;
3037ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis#include "clang/AST/TypeNodes.def"
304fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
305fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
306fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
3077ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {
3087ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << T->getName(Policy);
3097ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
310fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
3117ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) { }
312fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
3137ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {
3147ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << "_Complex ";
3157ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getElementType(), OS);
3167ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
3177ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {
3187ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getElementType(), OS);
3197ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
3207ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
3217ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {
3227ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  IncludeStrongLifetimeRAII Strong(Policy);
3237ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
3247ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getPointeeType(), OS);
325fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // Handle things like 'int (*A)[4];' correctly.
326fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // FIXME: this should include vectors, but vectors use attributes I guess.
327fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (isa<ArrayType>(T->getPointeeType()))
3287ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << '(';
3297ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << '*';
3307ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
3317ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {
332f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
3337ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
3347ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // Handle things like 'int (*A)[4];' correctly.
3357ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // FIXME: this should include vectors, but vectors use attributes I guess.
3367ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (isa<ArrayType>(T->getPointeeType()))
3377ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
3387ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getPointeeType(), OS);
339fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
340fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
3417ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printBlockPointerBefore(const BlockPointerType *T,
3427ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          raw_ostream &OS) {
3437ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
3447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getPointeeType(), OS);
3457ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << '^';
3467ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
3477ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printBlockPointerAfter(const BlockPointerType *T,
3487ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          raw_ostream &OS) {
3497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
3507ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getPointeeType(), OS);
351fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
352fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
3537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,
3547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                             raw_ostream &OS) {
3557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  IncludeStrongLifetimeRAII Strong(Policy);
3567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
3577ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getPointeeTypeAsWritten(), OS);
358fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // Handle things like 'int (&A)[4];' correctly.
359fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // FIXME: this should include vectors, but vectors use attributes I guess.
360fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
3617ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << '(';
3627ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << '&';
3637ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
3647ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,
3657ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                            raw_ostream &OS) {
366f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
3677ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
3687ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // Handle things like 'int (&A)[4];' correctly.
3697ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // FIXME: this should include vectors, but vectors use attributes I guess.
3707ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
3717ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
3727ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getPointeeTypeAsWritten(), OS);
373fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
374fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
3757ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,
3767ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                             raw_ostream &OS) {
3777ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  IncludeStrongLifetimeRAII Strong(Policy);
3787ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
3797ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getPointeeTypeAsWritten(), OS);
380fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // Handle things like 'int (&&A)[4];' correctly.
381fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // FIXME: this should include vectors, but vectors use attributes I guess.
382fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
3837ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << '(';
3847ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << "&&";
3857ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
3867ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,
3877ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                            raw_ostream &OS) {
388f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
3897ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
3907ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // Handle things like 'int (&&A)[4];' correctly.
3917ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // FIXME: this should include vectors, but vectors use attributes I guess.
3927ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (isa<ArrayType>(T->getPointeeTypeAsWritten()))
3937ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
3947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getPointeeTypeAsWritten(), OS);
395fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
396fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
3977ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
3987ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                           raw_ostream &OS) {
3997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  IncludeStrongLifetimeRAII Strong(Policy);
4007ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
4017ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getPointeeType(), OS);
402fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // Handle things like 'int (Cls::*A)[4];' correctly.
403fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // FIXME: this should include vectors, but vectors use attributes I guess.
404fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (isa<ArrayType>(T->getPointeeType()))
4057ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << '(';
4067ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
4077ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  PrintingPolicy InnerPolicy(Policy);
4087ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  InnerPolicy.SuppressTag = false;
4097ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());
4107ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
4117ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << "::*";
4127ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
4137ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printMemberPointerAfter(const MemberPointerType *T,
4147ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          raw_ostream &OS) {
415f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
4167ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
4177ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // Handle things like 'int (Cls::*A)[4];' correctly.
4187ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // FIXME: this should include vectors, but vectors use attributes I guess.
4197ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (isa<ArrayType>(T->getPointeeType()))
4207ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
4217ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getPointeeType(), OS);
422fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
423fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
4247ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,
4257ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                           raw_ostream &OS) {
426f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
4277ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
4287ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getElementType(), OS);
4297ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
4307ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,
4317ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          raw_ostream &OS) {
4327ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << '[' << T->getSize().getZExtValue() << ']';
4337ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getElementType(), OS);
434fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
435fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
4367ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,
4377ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                             raw_ostream &OS) {
438f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
4397ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
4407ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getElementType(), OS);
4417ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
4427ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,
4437ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                            raw_ostream &OS) {
4447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << "[]";
4457ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getElementType(), OS);
446fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
447fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
4487ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printVariableArrayBefore(const VariableArrayType *T,
4497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                           raw_ostream &OS) {
4507ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  IncludeStrongLifetimeRAII Strong(Policy);
4517ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
4527ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getElementType(), OS);
4537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
4547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printVariableArrayAfter(const VariableArrayType *T,
4557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          raw_ostream &OS) {
4567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << '[';
457fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->getIndexTypeQualifiers().hasQualifiers()) {
4587ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers());
4597ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ' ';
460fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
46116d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann
462fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->getSizeModifier() == VariableArrayType::Static)
4637ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "static";
464fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else if (T->getSizeModifier() == VariableArrayType::Star)
4657ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << '*';
46616d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann
4677ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (T->getSizeExpr())
4687ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    T->getSizeExpr()->printPretty(OS, 0, Policy);
4697ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << ']';
4707ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
4717ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getElementType(), OS);
472fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
473fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
4747ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printDependentSizedArrayBefore(
4757ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                               const DependentSizedArrayType *T,
4767ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                               raw_ostream &OS) {
477f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
4787ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
4797ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getElementType(), OS);
4807ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
4817ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printDependentSizedArrayAfter(
4827ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                               const DependentSizedArrayType *T,
4837ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                               raw_ostream &OS) {
4847ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << '[';
4857ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (T->getSizeExpr())
4867ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    T->getSizeExpr()->printPretty(OS, 0, Policy);
4877ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << ']';
4887ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getElementType(), OS);
489fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
490fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
4917ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printDependentSizedExtVectorBefore(
492fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                          const DependentSizedExtVectorType *T,
4937ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          raw_ostream &OS) {
4947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getElementType(), OS);
4957ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
4967ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printDependentSizedExtVectorAfter(
4977ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          const DependentSizedExtVectorType *T,
4987ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          raw_ostream &OS) {
4997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << " __attribute__((ext_vector_type(";
5007ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (T->getSizeExpr())
5017ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    T->getSizeExpr()->printPretty(OS, 0, Policy);
5027ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << ")))";
5037ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getElementType(), OS);
504fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
505fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
5067ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
507ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson  switch (T->getVectorKind()) {
508ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson  case VectorType::AltiVecPixel:
5097ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "__vector __pixel ";
510ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson    break;
511ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson  case VectorType::AltiVecBool:
5127ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "__vector __bool ";
5137ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printBefore(T->getElementType(), OS);
514ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson    break;
515ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson  case VectorType::AltiVecVector:
5167ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "__vector ";
5177ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printBefore(T->getElementType(), OS);
518ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson    break;
519ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson  case VectorType::NeonVector:
5207ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "__attribute__((neon_vector_type("
5217ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis       << T->getNumElements() << "))) ";
5227ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printBefore(T->getElementType(), OS);
523ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson    break;
524ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson  case VectorType::NeonPolyVector:
5257ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "__attribute__((neon_polyvector_type(" <<
5267ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis          T->getNumElements() << "))) ";
5277ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printBefore(T->getElementType(), OS);
528ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson    break;
529ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson  case VectorType::GenericVector: {
53082287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson    // FIXME: We prefer to print the size directly here, but have no way
53182287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson    // to get the size of the type.
5327ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "__attribute__((__vector_size__("
5337ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis       << T->getNumElements()
5347ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis       << " * sizeof(";
5357ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    print(T->getElementType(), OS, StringRef());
5367ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ")))) ";
5377ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printBefore(T->getElementType(), OS);
538ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson    break;
539ec33cbeab96f33007ac19a57bab454519cd94fe9Bob Wilson  }
54082287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson  }
541fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
5427ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {
5437ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getElementType(), OS);
5447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
545fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
5467ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printExtVectorBefore(const ExtVectorType *T,
5477ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                       raw_ostream &OS) {
5487ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getElementType(), OS);
5497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
5507ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {
5517ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getElementType(), OS);
5527ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << " __attribute__((ext_vector_type(";
5537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << T->getNumElements();
5547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << ")))";
555fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
556fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
55701d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregorvoid
5587ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios KyrtzidisFunctionProtoType::printExceptionSpecification(raw_ostream &OS,
55901d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor                                               PrintingPolicy Policy) const {
56001d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
56101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  if (hasDynamicExceptionSpec()) {
5627ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " throw(";
56301d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor    if (getExceptionSpecType() == EST_MSAny)
5647ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << "...";
56501d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor    else
56601d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor      for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
56701d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor        if (I)
5687ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis          OS << ", ";
56901d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
5707ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        OS << getExceptionType(I).stream(Policy);
57101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor      }
5727ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
57301d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
5747ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " noexcept";
57501d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor    if (getExceptionSpecType() == EST_ComputedNoexcept) {
5767ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << '(';
5777ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      getNoexceptExpr()->printPretty(OS, 0, Policy);
5787ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << ')';
57901d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor    }
58001d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor  }
58101d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor}
58201d08018b7cf5ce1601707cfd7a84d22015fc04eDouglas Gregor
5837ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,
5847ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                           raw_ostream &OS) {
5857ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (T->hasTrailingReturn()) {
5867ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "auto ";
5877ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (!HasEmptyPlaceHolder)
5887ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << '(';
5897ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  } else {
5907ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    // If needed for precedence reasons, wrap the inner part in grouping parens.
5917ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
5927ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printBefore(T->getResultType(), OS);
5937ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (!PrevPHIsEmpty.get())
5947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << '(';
5957ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  }
5967ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
5977ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
5987ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
5997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          raw_ostream &OS) {
600fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // If needed for precedence reasons, wrap the inner part in grouping parens.
6017ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (!HasEmptyPlaceHolder)
6027ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
6037ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
6047ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
6057ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << '(';
6067ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  {
6077ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    ParamPolicyRAII ParamPolicy(Policy);
6087ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
6097ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      if (i) OS << ", ";
6107ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      print(T->getArgType(i), OS, StringRef());
6117ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    }
612fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
613fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
614fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->isVariadic()) {
615fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (T->getNumArgs())
6167ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << ", ";
6177ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "...";
618fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
619fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // Do not emit int() if we have a proto, emit 'int(void)'.
6207ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "void";
621fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
622fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
6237ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << ')';
6240ae7b3f1d5403265f693ed75384603ca8fbba74dDouglas Gregor
625264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  FunctionType::ExtInfo Info = T->getExtInfo();
626264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  switch(Info.getCC()) {
627561d3abc881033776ece385a01a510e1cbc1fa92David Blaikie  case CC_Default: break;
628f82b4e85b1219295cad4b5851b035575bc293010John McCall  case CC_C:
6297ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " __attribute__((cdecl))";
630f82b4e85b1219295cad4b5851b035575bc293010John McCall    break;
631f82b4e85b1219295cad4b5851b035575bc293010John McCall  case CC_X86StdCall:
6327ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " __attribute__((stdcall))";
633f82b4e85b1219295cad4b5851b035575bc293010John McCall    break;
634f82b4e85b1219295cad4b5851b035575bc293010John McCall  case CC_X86FastCall:
6357ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " __attribute__((fastcall))";
636f82b4e85b1219295cad4b5851b035575bc293010John McCall    break;
637f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor  case CC_X86ThisCall:
6387ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " __attribute__((thiscall))";
639f813a2c03fcb05381b3252010435f557eb6b3cdeDouglas Gregor    break;
64052fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik  case CC_X86Pascal:
6417ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " __attribute__((pascal))";
64252fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik    break;
643414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case CC_AAPCS:
6447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " __attribute__((pcs(\"aapcs\")))";
645414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    break;
646414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case CC_AAPCS_VFP:
6477ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " __attribute__((pcs(\"aapcs-vfp\")))";
648414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov    break;
649f82b4e85b1219295cad4b5851b035575bc293010John McCall  }
650264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola  if (Info.getNoReturn())
6517ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " __attribute__((noreturn))";
652425ef72306d4ff6b3698b744353e5f0e56b4b884Rafael Espindola  if (Info.getRegParm())
6537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " __attribute__((regparm ("
6547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis       << Info.getRegParm() << ")))";
6557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
6567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (unsigned quals = T->getTypeQuals()) {
6577ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ' ';
6587ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    AppendTypeQualList(OS, quals);
6597ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  }
660c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor
661c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor  switch (T->getRefQualifier()) {
662c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor  case RQ_None:
663c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor    break;
664c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor
665c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor  case RQ_LValue:
6667ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " &";
667c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor    break;
668c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor
669c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor  case RQ_RValue:
6707ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " &&";
671c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor    break;
672c938c1668b4fd12af154e965dd935a89e4801a70Douglas Gregor  }
6737ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  T->printExceptionSpecification(OS, Policy);
6747ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
675eefb3d5b49c844347f212073a7e975b8118fe8e9Richard Smith  if (T->hasTrailingReturn()) {
6767ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " -> ";
6777ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    print(T->getResultType(), OS, StringRef());
678eefb3d5b49c844347f212073a7e975b8118fe8e9Richard Smith  } else
6797ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printAfter(T->getResultType(), OS);
680fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
681fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
6827ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
6837ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                             raw_ostream &OS) {
684fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // If needed for precedence reasons, wrap the inner part in grouping parens.
6857ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
6867ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getResultType(), OS);
6877ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (!PrevPHIsEmpty.get())
6887ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << '(';
6897ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
6907ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
6917ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                            raw_ostream &OS) {
6927ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // If needed for precedence reasons, wrap the inner part in grouping parens.
6937ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (!HasEmptyPlaceHolder)
6947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
6957ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
696fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
6977ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << "()";
698fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->getNoReturnAttr())
6997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " __attribute__((noreturn))";
7007ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getResultType(), OS);
701fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
702fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
7037ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) {
7043cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  IdentifierInfo *II = D->getIdentifier();
7057ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << II->getName();
7067ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
707ed97649e9574b9d854fa4d6109c9333ae0993554John McCall}
708ed97649e9574b9d854fa4d6109c9333ae0993554John McCall
7097ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
7107ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                             raw_ostream &OS) {
7117ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printTypeSpec(T->getDecl(), OS);
7123cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall}
7137ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
7147ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                             raw_ostream &OS) { }
7153cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall
7167ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
7177ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printTypeSpec(T->getDecl(), OS);
718fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
7197ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) { }
720fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
7217ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
7227ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                        raw_ostream &OS) {
7237ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << "typeof ";
7247ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  T->getUnderlyingExpr()->printPretty(OS, 0, Policy);
7257ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
726fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
7277ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
7287ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                       raw_ostream &OS) { }
7297ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
7307ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {
7317ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << "typeof(";
7327ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  print(T->getUnderlyingType(), OS, StringRef());
7337ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << ')';
7347ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
735fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
7367ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) { }
737fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
7387ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {
7397ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << "decltype(";
7407ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  T->getUnderlyingExpr()->printPretty(OS, 0, Policy);
7417ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << ')';
7427ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
743fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
7447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) { }
745fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
7467ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
7477ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                            raw_ostream &OS) {
748f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
749ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt
750ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  switch (T->getUTTKind()) {
751ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt    case UnaryTransformType::EnumUnderlyingType:
7527ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << "__underlying_type(";
7537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      print(T->getBaseType(), OS, StringRef());
7547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << ')';
7557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      spaceBeforePlaceHolder(OS);
7567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      return;
7577ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  }
7587ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
7597ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getBaseType(), OS);
7607ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
7617ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
7627ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                           raw_ostream &OS) {
7637ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  IncludeStrongLifetimeRAII Strong(Policy);
7647ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
7657ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  switch (T->getUTTKind()) {
7667ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    case UnaryTransformType::EnumUnderlyingType:
7677ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      return;
768ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt  }
7697ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
7707ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getBaseType(), OS);
771ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt}
772ca63c200346c0ca9e00194ec6e34a5a7b0ed9321Sean Hunt
7737ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
77434b41d939a1328f484511c6002ba2456db879a29Richard Smith  // If the type has been deduced, do not print 'auto'.
77534b41d939a1328f484511c6002ba2456db879a29Richard Smith  if (T->isDeduced()) {
7767ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printBefore(T->getDeducedType(), OS);
77734b41d939a1328f484511c6002ba2456db879a29Richard Smith  } else {
7787ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "auto";
7797ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    spaceBeforePlaceHolder(OS);
78034b41d939a1328f484511c6002ba2456db879a29Richard Smith  }
78134b41d939a1328f484511c6002ba2456db879a29Richard Smith}
7827ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
7837ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // If the type has been deduced, do not print 'auto'.
7847ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (T->isDeduced())
7857ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printAfter(T->getDeducedType(), OS);
7867ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
78734b41d939a1328f484511c6002ba2456db879a29Richard Smith
7887ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {
789b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman  IncludeStrongLifetimeRAII Strong(Policy);
790b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman
7917ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << "_Atomic(";
7927ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  print(T->getValueType(), OS, StringRef());
7937ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << ')';
7947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
795b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman}
7967ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { }
797b001de7458d17c17e6d8b8034c7cfcefd3b70c00Eli Friedman
7987c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall/// Appends the given scope to the end of a string.
7997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) {
8007c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  if (DC->isTranslationUnit()) return;
8017ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  AppendScope(DC->getParent(), OS);
8027c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall
8037c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
80425270b6e6a8416b7532cfe552b41794418ea19b1Douglas Gregor    if (Policy.SuppressUnwrittenScope &&
80525270b6e6a8416b7532cfe552b41794418ea19b1Douglas Gregor        (NS->isAnonymousNamespace() || NS->isInline()))
80625270b6e6a8416b7532cfe552b41794418ea19b1Douglas Gregor      return;
8077c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall    if (NS->getIdentifier())
8087ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << NS->getName() << "::";
8097c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall    else
8107ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << "<anonymous>::";
8117c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  } else if (ClassTemplateSpecializationDecl *Spec
8127c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall               = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
813f85e193739c953358c865005855253af4f68a497John McCall    IncludeStrongLifetimeRAII Strong(Policy);
8147ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << Spec->getIdentifier()->getName();
8157c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
8167ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    TemplateSpecializationType::PrintTemplateArgumentList(OS,
817910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                            TemplateArgs.data(),
818910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor                                            TemplateArgs.size(),
8197c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall                                            Policy);
8207ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "::";
8217c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
822162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
8237ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << Typedef->getIdentifier()->getName() << "::";
8247c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall    else if (Tag->getIdentifier())
8257ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << Tag->getIdentifier()->getName() << "::";
82625270b6e6a8416b7532cfe552b41794418ea19b1Douglas Gregor    else
82725270b6e6a8416b7532cfe552b41794418ea19b1Douglas Gregor      return;
8287c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  }
8297c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall}
8307c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall
8317ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
832fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (Policy.SuppressTag)
833fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    return;
8347c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall
83573061d054128e486e70e0f2874b23d6eca067e5bJohn McCall  bool HasKindDecoration = false;
8367c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall
8370daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara  // bool SuppressTagKeyword
8380daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara  //   = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword;
8390daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara
8407c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  // We don't print tags unless this is an elaborated type.
8417c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  // In C, we just assume every RecordType is an elaborated type.
8420daaf32723ac78549c507c2a68a5300502703673Abramo Bagnara  if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword ||
843162e1c1b487352434552147967c3dd296ebee2f7Richard Smith        D->getTypedefNameForAnonDecl())) {
84473061d054128e486e70e0f2874b23d6eca067e5bJohn McCall    HasKindDecoration = true;
8457ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << D->getKindName();
8467ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ' ';
8477c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  }
8487c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall
849c7acc66050a96571739eeb017a867df27e6bcfc3Chris Lattner  // Compute the full nested-name-specifier for this type.
850c7acc66050a96571739eeb017a867df27e6bcfc3Chris Lattner  // In C, this will always be empty except when the type
851c7acc66050a96571739eeb017a867df27e6bcfc3Chris Lattner  // being printed is anonymous within other Record.
8527c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  if (!Policy.SuppressScope)
8537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    AppendScope(D->getDeclContext(), OS);
8547c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall
8553cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall  if (const IdentifierInfo *II = D->getIdentifier())
8567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << II->getName();
857162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
858fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    assert(Typedef->getIdentifier() && "Typedef without identifier?");
8597ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << Typedef->getIdentifier()->getName();
86073061d054128e486e70e0f2874b23d6eca067e5bJohn McCall  } else {
86173061d054128e486e70e0f2874b23d6eca067e5bJohn McCall    // Make an unambiguous representation for anonymous types, e.g.
86273061d054128e486e70e0f2874b23d6eca067e5bJohn McCall    //   <anonymous enum at /usr/include/string.h:120:9>
863e4e68d45f89ff4899d30cbd196603d09b7fbc150Douglas Gregor
864e4e68d45f89ff4899d30cbd196603d09b7fbc150Douglas Gregor    if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
865e4e68d45f89ff4899d30cbd196603d09b7fbc150Douglas Gregor      OS << "<lambda";
866e4e68d45f89ff4899d30cbd196603d09b7fbc150Douglas Gregor      HasKindDecoration = true;
867e4e68d45f89ff4899d30cbd196603d09b7fbc150Douglas Gregor    } else {
868e4e68d45f89ff4899d30cbd196603d09b7fbc150Douglas Gregor      OS << "<anonymous";
869e4e68d45f89ff4899d30cbd196603d09b7fbc150Douglas Gregor    }
870e4e68d45f89ff4899d30cbd196603d09b7fbc150Douglas Gregor
87184139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor    if (Policy.AnonymousTagLocations) {
87284139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor      // Suppress the redundant tag keyword if we just printed one.
87384139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor      // We don't have to worry about ElaboratedTypes here because you can't
87484139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor      // refer to an anonymous type with one.
87584139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor      if (!HasKindDecoration)
87684139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor        OS << " " << D->getKindName();
87784139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor
878cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(
87916834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor          D->getLocation());
880cb7b1e17b63967317ab5cc55682168cf0380519aDouglas Gregor      if (PLoc.isValid()) {
88116834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor        OS << " at " << PLoc.getFilename()
88216834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor           << ':' << PLoc.getLine()
88316834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor           << ':' << PLoc.getColumn();
88416834e88b9102b7c6562a6bb8a8931a58ebda900Douglas Gregor      }
88584139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor    }
88684139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor
88784139d6ef8967cfdb70d37378a7a65cc4827d44dDouglas Gregor    OS << '>';
88873061d054128e486e70e0f2874b23d6eca067e5bJohn McCall  }
8897c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall
890fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // If this is a class template specialization, print the template
891fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // arguments.
892fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (ClassTemplateSpecializationDecl *Spec
8937c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall        = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
8943cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall    const TemplateArgument *Args;
8953cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall    unsigned NumArgs;
8963cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall    if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
8973cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall      const TemplateSpecializationType *TST =
8983cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall        cast<TemplateSpecializationType>(TAW->getType());
8993cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall      Args = TST->getArgs();
9003cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall      NumArgs = TST->getNumArgs();
9013cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall    } else {
9023cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall      const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
903910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor      Args = TemplateArgs.data();
904910f8008fea79120489a53593fe971b0b8a4a740Douglas Gregor      NumArgs = TemplateArgs.size();
9053cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall    }
906f85e193739c953358c865005855253af4f68a497John McCall    IncludeStrongLifetimeRAII Strong(Policy);
9077ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    TemplateSpecializationType::PrintTemplateArgumentList(OS,
9087ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                          Args, NumArgs,
9097ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                          Policy);
910fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
9117c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall
9127ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
913fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
914fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
9157ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
9167ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printTag(T->getDecl(), OS);
917fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
9187ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) { }
919fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
9207ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
9217ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printTag(T->getDecl(), OS);
922fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
9237ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) { }
924fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
9257ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
9267ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                              raw_ostream &OS) {
927b7efff4bae117604f442bb6859c844f90b15f3ffChandler Carruth  if (IdentifierInfo *Id = T->getIdentifier())
9287ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << Id->getName();
9294fb86f8c4585e53c21c847ad3de9e3b2de123cd9Chandler Carruth  else
9307ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();
9317ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
932fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
9337ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,
9347ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                             raw_ostream &OS) { }
935fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
9367ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printSubstTemplateTypeParmBefore(
9377ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                             const SubstTemplateTypeParmType *T,
9387ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                             raw_ostream &OS) {
9397ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  IncludeStrongLifetimeRAII Strong(Policy);
9407ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getReplacementType(), OS);
9417ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
9427ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printSubstTemplateTypeParmAfter(
9437ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                             const SubstTemplateTypeParmType *T,
9447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                             raw_ostream &OS) {
945f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
9467ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getReplacementType(), OS);
947fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
948fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
9497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printSubstTemplateTypeParmPackBefore(
950c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor                                        const SubstTemplateTypeParmPackType *T,
9517ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                        raw_ostream &OS) {
952f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
9537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printTemplateTypeParmBefore(T->getReplacedParameter(), OS);
9547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
9557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printSubstTemplateTypeParmPackAfter(
9567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                        const SubstTemplateTypeParmPackType *T,
9577ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                        raw_ostream &OS) {
9587ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  IncludeStrongLifetimeRAII Strong(Policy);
9597ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printTemplateTypeParmAfter(T->getReplacedParameter(), OS);
960c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor}
961c3069d618f4661d923cb1b5c4525b082fce73b04Douglas Gregor
9627ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTemplateSpecializationBefore(
963fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                            const TemplateSpecializationType *T,
9647ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                            raw_ostream &OS) {
965f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
9667ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  T->getTemplateName().print(OS, Policy);
967fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
9687ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  TemplateSpecializationType::PrintTemplateArgumentList(OS,
9697ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                        T->getArgs(),
9707ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                        T->getNumArgs(),
9717ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                        Policy);
9727ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
973fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
9747ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printTemplateSpecializationAfter(
9757ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                            const TemplateSpecializationType *T,
9767ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                            raw_ostream &OS) { }
977fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
9787ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
9797ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                               raw_ostream &OS) {
9807ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printTemplateSpecializationBefore(T->getInjectedTST(), OS);
9813cb0ebd5f76abcb776f7cb4062bd79e3268c0dc4John McCall}
9827ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
9837ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                               raw_ostream &OS) { }
9847ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
9857ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printElaboratedBefore(const ElaboratedType *T,
9867ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                        raw_ostream &OS) {
9877ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << TypeWithKeyword::getKeywordName(T->getKeyword());
9887ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (T->getKeyword() != ETK_None)
9897ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " ";
9907ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  NestedNameSpecifier* Qualifier = T->getQualifier();
9917ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (Qualifier)
9927ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    Qualifier->print(OS, Policy);
993fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
9947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  ElaboratedTypePolicyRAII PolicyRAII(Policy);
9957ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getNamedType(), OS);
9967ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
9977ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printElaboratedAfter(const ElaboratedType *T,
9987ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                        raw_ostream &OS) {
9997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  ElaboratedTypePolicyRAII PolicyRAII(Policy);
10007ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getNamedType(), OS);
1001fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
1002fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
10037ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
10047ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
10057ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printBefore(T->getInnerType(), OS);
10067ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << '(';
10077ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  } else
10087ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printBefore(T->getInnerType(), OS);
10097ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
10107ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {
10117ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
10127ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
10137ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printAfter(T->getInnerType(), OS);
10147ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  } else
10157ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    printAfter(T->getInnerType(), OS);
1016075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara}
1017075f8f1b6bed4d1b224c74f87508534cc6392ce6Abramo Bagnara
10187ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printDependentNameBefore(const DependentNameType *T,
10197ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                           raw_ostream &OS) {
10207ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << TypeWithKeyword::getKeywordName(T->getKeyword());
10217ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (T->getKeyword() != ETK_None)
10227ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " ";
1023fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
10247ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  T->getQualifier()->print(OS, Policy);
102533500955d731c73717af52088b7fc0e7a85681e7John McCall
10267ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << T->getIdentifier()->getName();
10277ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
102833500955d731c73717af52088b7fc0e7a85681e7John McCall}
10297ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printDependentNameAfter(const DependentNameType *T,
10307ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          raw_ostream &OS) { }
103133500955d731c73717af52088b7fc0e7a85681e7John McCall
10327ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printDependentTemplateSpecializationBefore(
10337ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        const DependentTemplateSpecializationType *T, raw_ostream &OS) {
1034f85e193739c953358c865005855253af4f68a497John McCall  IncludeStrongLifetimeRAII Strong(Policy);
103533500955d731c73717af52088b7fc0e7a85681e7John McCall
10367ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << TypeWithKeyword::getKeywordName(T->getKeyword());
10377ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (T->getKeyword() != ETK_None)
10387ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " ";
1039fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
10407ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (T->getQualifier())
10417ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    T->getQualifier()->print(OS, Policy);
10427ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << T->getIdentifier()->getName();
10437ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  TemplateSpecializationType::PrintTemplateArgumentList(OS,
10447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                        T->getArgs(),
10457ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                        T->getNumArgs(),
10467ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                        Policy);
10477ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
1048fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
10497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printDependentTemplateSpecializationAfter(
10507ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        const DependentTemplateSpecializationType *T, raw_ostream &OS) { }
1051fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
10527ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
10537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                           raw_ostream &OS) {
10547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getPattern(), OS);
10557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
10567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
10577ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          raw_ostream &OS) {
10587ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printAfter(T->getPattern(), OS);
10597ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << "...";
10607536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor}
10617536dd5e6c99584481b7dab68b7e7d8df9c54054Douglas Gregor
10627ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printAttributedBefore(const AttributedType *T,
10637ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                        raw_ostream &OS) {
1064b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  // Prefer the macro forms of the GC and ownership qualifiers.
1065f85e193739c953358c865005855253af4f68a497John McCall  if (T->getAttrKind() == AttributedType::attr_objc_gc ||
1066b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis      T->getAttrKind() == AttributedType::attr_objc_ownership)
10677ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    return printBefore(T->getEquivalentType(), OS);
106814aa2175416f79ef17811282afbf425f87d54ebfJohn McCall
10697ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  printBefore(T->getModifiedType(), OS);
10707ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
10717ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
10727ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printAttributedAfter(const AttributedType *T,
10737ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                       raw_ostream &OS) {
10747ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  // Prefer the macro forms of the GC and ownership qualifiers.
10757ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (T->getAttrKind() == AttributedType::attr_objc_gc ||
10767ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      T->getAttrKind() == AttributedType::attr_objc_ownership)
10777ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    return printAfter(T->getEquivalentType(), OS);
10789d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall
10799d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall  // TODO: not all attributes are GCC-style attributes.
10807ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << " __attribute__((";
10819d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall  switch (T->getAttrKind()) {
1082170464b7c0a2c0c86f2821f14a46f0d540cb5e94Francois Pichet  case AttributedType::attr_address_space:
10837ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "address_space(";
10847ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << T->getEquivalentType().getAddressSpace();
10857ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
10869d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    break;
10879d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall
1088170464b7c0a2c0c86f2821f14a46f0d540cb5e94Francois Pichet  case AttributedType::attr_vector_size: {
10897ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "__vector_size__(";
10909d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    if (const VectorType *vector =T->getEquivalentType()->getAs<VectorType>()) {
10917ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << vector->getNumElements();
10927ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << " * sizeof(";
10937ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      print(vector->getElementType(), OS, StringRef());
10947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << ')';
10959d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    }
10967ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
10979d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    break;
10989d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall  }
10999d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall
1100170464b7c0a2c0c86f2821f14a46f0d540cb5e94Francois Pichet  case AttributedType::attr_neon_vector_type:
1101170464b7c0a2c0c86f2821f14a46f0d540cb5e94Francois Pichet  case AttributedType::attr_neon_polyvector_type: {
1102170464b7c0a2c0c86f2821f14a46f0d540cb5e94Francois Pichet    if (T->getAttrKind() == AttributedType::attr_neon_vector_type)
11037ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << "neon_vector_type(";
11049d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    else
11057ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << "neon_polyvector_type(";
11069d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    const VectorType *vector = T->getEquivalentType()->getAs<VectorType>();
11077ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << vector->getNumElements();
11087ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
11099d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    break;
11109d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall  }
11119d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall
1112170464b7c0a2c0c86f2821f14a46f0d540cb5e94Francois Pichet  case AttributedType::attr_regparm: {
11137ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "regparm(";
11149d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    QualType t = T->getEquivalentType();
11159d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    while (!t->isFunctionType())
11169d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall      t = t->getPointeeType();
11177ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << t->getAs<FunctionType>()->getRegParmType();
11187ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
11199d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    break;
11209d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall  }
11219d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall
1122170464b7c0a2c0c86f2821f14a46f0d540cb5e94Francois Pichet  case AttributedType::attr_objc_gc: {
11237ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "objc_gc(";
11249d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall
11259d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    QualType tmp = T->getEquivalentType();
11269d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    while (tmp.getObjCGCAttr() == Qualifiers::GCNone) {
11279d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall      QualType next = tmp->getPointeeType();
11289d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall      if (next == tmp) break;
11299d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall      tmp = next;
11309d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    }
11319d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall
11329d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    if (tmp.isObjCGCWeak())
11337ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << "weak";
11349d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    else
11357ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << "strong";
11367ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
11379d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall    break;
11389d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall  }
11399d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall
1140b8b0313e84700b5c6d597b3be4de41c97b7550f1Argyrios Kyrtzidis  case AttributedType::attr_objc_ownership:
11417ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "objc_ownership(";
1142f85e193739c953358c865005855253af4f68a497John McCall    switch (T->getEquivalentType().getObjCLifetime()) {
11433026348bd4c13a0f83b59839f64065e0fcbea253David Blaikie    case Qualifiers::OCL_None: llvm_unreachable("no ownership!");
11447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    case Qualifiers::OCL_ExplicitNone: OS << "none"; break;
11457ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    case Qualifiers::OCL_Strong: OS << "strong"; break;
11467ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    case Qualifiers::OCL_Weak: OS << "weak"; break;
11477ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    case Qualifiers::OCL_Autoreleasing: OS << "autoreleasing"; break;
1148f85e193739c953358c865005855253af4f68a497John McCall    }
11497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ')';
1150f85e193739c953358c865005855253af4f68a497John McCall    break;
1151f85e193739c953358c865005855253af4f68a497John McCall
11527ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  case AttributedType::attr_noreturn: OS << "noreturn"; break;
11537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  case AttributedType::attr_cdecl: OS << "cdecl"; break;
11547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  case AttributedType::attr_fastcall: OS << "fastcall"; break;
11557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  case AttributedType::attr_stdcall: OS << "stdcall"; break;
11567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  case AttributedType::attr_thiscall: OS << "thiscall"; break;
11577ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  case AttributedType::attr_pascal: OS << "pascal"; break;
1158414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  case AttributedType::attr_pcs: {
11597ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "pcs(";
1160414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov   QualType t = T->getEquivalentType();
1161414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov   while (!t->isFunctionType())
1162414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov     t = t->getPointeeType();
11637ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis   OS << (t->getAs<FunctionType>()->getCallConv() == CC_AAPCS ?
1164414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov         "\"aapcs\"" : "\"aapcs-vfp\"");
11657ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis   OS << ')';
1166414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov   break;
1167414d8967e1d760ea1e19a4aca96b13777a8cf8c5Anton Korobeynikov  }
11689d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall  }
11697ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << "))";
11709d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall}
11719d156a7b1b2771e191f2f5a45a7b7a694129463bJohn McCall
11727ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
11737ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                           raw_ostream &OS) {
11747ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << T->getDecl()->getName();
11757ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
1176fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
11777ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
11787ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                          raw_ostream &OS) { }
1179fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
11807ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
11817ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                        raw_ostream &OS) {
1182c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  if (T->qual_empty())
11837ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    return printBefore(T->getBaseType(), OS);
1184c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
11857ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  print(T->getBaseType(), OS, StringRef());
11867ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << '<';
1187c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  bool isFirst = true;
1188c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  for (ObjCObjectType::qual_iterator
1189c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall         I = T->qual_begin(), E = T->qual_end(); I != E; ++I) {
1190c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall    if (isFirst)
1191c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall      isFirst = false;
1192c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall    else
11937ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << ',';
11947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << (*I)->getName();
1195c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall  }
11967ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << '>';
11977ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  spaceBeforePlaceHolder(OS);
11987ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
11997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,
12007ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                        raw_ostream &OS) {
12017ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (T->qual_empty())
12027ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    return printAfter(T->getBaseType(), OS);
1203c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall}
1204c12c5bba6ceb6acd4e51e7a0fc03257da9cfd44eJohn McCall
12057ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
12067ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                               raw_ostream &OS) {
12077ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  T->getPointeeType().getLocalQualifiers().print(OS, Policy,
12087ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                /*appendSpaceIfNonEmpty=*/true);
12097ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
1210fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (T->isObjCIdType() || T->isObjCQualifiedIdType())
12117ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "id";
1212fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
12137ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "Class";
121413dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian  else if (T->isObjCSelType())
12157ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << "SEL";
1216fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  else
12177ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << T->getInterfaceDecl()->getName();
1218fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1219fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (!T->qual_empty()) {
12207ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << '<';
1221fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(),
1222fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                              E = T->qual_end();
1223fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor         I != E; ++I) {
12247ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << (*I)->getName();
1225fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      if (I+1 != E)
12267ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        OS << ',';
1227fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    }
12287ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << '>';
1229fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
1230fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
12317ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (!T->isObjCIdType() && !T->isObjCQualifiedIdType()) {
12327ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << " *"; // Don't forget the implicit pointer.
12337ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  } else {
12347ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    spaceBeforePlaceHolder(OS);
12357ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  }
12367ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
12377ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
12387ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                              raw_ostream &OS) { }
12397ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
12407ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TemplateSpecializationType::
12417ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  PrintTemplateArgumentList(raw_ostream &OS,
12427ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                            const TemplateArgumentListInfo &Args,
12437ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                            const PrintingPolicy &Policy) {
12447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  return PrintTemplateArgumentList(OS,
12457ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                   Args.getArgumentArray(),
12467ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                   Args.size(),
12477ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                   Policy);
12487ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
12497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
12507ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid
12517ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios KyrtzidisTemplateSpecializationType::PrintTemplateArgumentList(
12527ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                raw_ostream &OS,
12537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                const TemplateArgument *Args,
12547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                unsigned NumArgs,
12557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                  const PrintingPolicy &Policy,
12567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                                      bool SkipBrackets) {
12577ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (!SkipBrackets)
12587ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << '<';
1259fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
126016d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann  bool needSpace = false;
12617ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
12627ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (Arg > 0)
12637ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << ", ";
12647ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
12657ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    // Print the argument into a string.
12667ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    SmallString<128> Buf;
12677ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    llvm::raw_svector_ostream ArgOS(Buf);
12687ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (Args[Arg].getKind() == TemplateArgument::Pack) {
12697ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      PrintTemplateArgumentList(ArgOS,
12707ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                Args[Arg].pack_begin(),
12717ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                Args[Arg].pack_size(),
12727ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                Policy, true);
12737ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    } else {
12747ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Args[Arg].print(Policy, ArgOS);
12757ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    }
12767ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    StringRef ArgString = ArgOS.str();
12777ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
12787ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    // If this is the first argument and its string representation
12797ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    // begins with the global scope specifier ('::foo'), add a space
12807ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    // to avoid printing the diagraph '<:'.
12817ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
12827ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << ' ';
128316d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann
12847ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ArgString;
128516d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann
128616d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann    needSpace = (!ArgString.empty() && ArgString.back() == '>');
12877ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  }
12887ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
128916d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann  // If the last character of our string is '>', add another space to
129016d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann  // keep the two '>''s separate tokens. We don't *have* to do this in
129116d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann  // C++0x, but it's still good hygiene.
129216d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann  if (needSpace)
129316d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann    OS << ' ';
129416d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann
12957ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (!SkipBrackets)
12967ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << '>';
12977ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
12987ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
12997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis// Sadly, repeat all that with TemplateArgLoc.
13007ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid TemplateSpecializationType::
13017ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios KyrtzidisPrintTemplateArgumentList(raw_ostream &OS,
13027ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                          const TemplateArgumentLoc *Args, unsigned NumArgs,
13037ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                          const PrintingPolicy &Policy) {
13047ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << '<';
130516d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann
130616d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann  bool needSpace = false;
13077ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
13087ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (Arg > 0)
13097ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << ", ";
13107ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
13117ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    // Print the argument into a string.
13127ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    SmallString<128> Buf;
13137ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    llvm::raw_svector_ostream ArgOS(Buf);
13147ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) {
13157ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      PrintTemplateArgumentList(ArgOS,
13167ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                Args[Arg].getArgument().pack_begin(),
13177ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                Args[Arg].getArgument().pack_size(),
13187ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                Policy, true);
13197ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    } else {
13207ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      Args[Arg].getArgument().print(Policy, ArgOS);
13217ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    }
13227ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    StringRef ArgString = ArgOS.str();
13237ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
13247ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    // If this is the first argument and its string representation
13257ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    // begins with the global scope specifier ('::foo'), add a space
13267ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    // to avoid printing the diagraph '<:'.
13277ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
13287ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << ' ';
132916d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann
13307ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ArgString;
133116d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann
133216d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann    needSpace = (!ArgString.empty() && ArgString.back() == '>');
13337ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  }
13347ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
133516d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann  // If the last character of our string is '>', add another space to
133616d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann  // keep the two '>''s separate tokens. We don't *have* to do this in
133716d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann  // C++0x, but it's still good hygiene.
133816d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann  if (needSpace)
133916d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann    OS << ' ';
134016d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann
13417ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  OS << '>';
13427ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
13437ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
13447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid
13457ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios KyrtzidisFunctionProtoType::printExceptionSpecification(std::string &S,
13467ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                                               PrintingPolicy Policy) const {
13477ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
13487ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (hasDynamicExceptionSpec()) {
13497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    S += " throw(";
13507ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (getExceptionSpecType() == EST_MSAny)
13517ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      S += "...";
13527ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    else
13537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {
13547ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        if (I)
13557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis          S += ", ";
13567ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
13577ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        S += getExceptionType(I).getAsString(Policy);
13587ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      }
13597ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    S += ")";
13607ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {
13617ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    S += " noexcept";
13627ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (getExceptionSpecType() == EST_ComputedNoexcept) {
13637ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      S += "(";
13647ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      llvm::raw_string_ostream EOut(S);
13657ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      getNoexceptExpr()->printPretty(EOut, 0, Policy);
13667ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      EOut.flush();
13677ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      S += EOut.str();
13687ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      S += ")";
13697ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    }
13707ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  }
1371fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
1372fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1373d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCallstd::string TemplateSpecializationType::
1374d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  PrintTemplateArgumentList(const TemplateArgumentListInfo &Args,
1375d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                            const PrintingPolicy &Policy) {
1376d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall  return PrintTemplateArgumentList(Args.getArgumentArray(),
1377d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                   Args.size(),
1378d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall                                   Policy);
1379d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall}
1380d5532b6cfff2977e0c59fa6ead7f7973984a620dJohn McCall
1381fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string
1382fee8a3c003a8894002810a6373bd5b895290974eDouglas GregorTemplateSpecializationType::PrintTemplateArgumentList(
1383fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                                const TemplateArgument *Args,
1384fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                                                unsigned NumArgs,
1385dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor                                                  const PrintingPolicy &Policy,
1386dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor                                                      bool SkipBrackets) {
1387fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string SpecString;
1388dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor  if (!SkipBrackets)
1389dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor    SpecString += '<';
1390dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor
1391fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1392319b4a609156faabf0bb86e368026afcd30893eeFrancois Pichet    if (SpecString.size() > unsigned(!SkipBrackets))
1393fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      SpecString += ", ";
1394fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1395fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // Print the argument into a string.
1396fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    std::string ArgString;
1397dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor    if (Args[Arg].getKind() == TemplateArgument::Pack) {
1398dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor      ArgString = PrintTemplateArgumentList(Args[Arg].pack_begin(),
1399dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor                                            Args[Arg].pack_size(),
1400dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor                                            Policy, true);
1401dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor    } else {
140287dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor      llvm::raw_string_ostream ArgOut(ArgString);
140387dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor      Args[Arg].print(Policy, ArgOut);
140487dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor    }
140587dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor
1406fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // If this is the first argument and its string representation
1407fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // begins with the global scope specifier ('::foo'), add a space
1408fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // to avoid printing the diagraph '<:'.
1409fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
1410fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      SpecString += ' ';
1411fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1412fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    SpecString += ArgString;
1413fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
1414fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1415fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // If the last character of our string is '>', add another space to
1416fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // keep the two '>''s separate tokens. We don't *have* to do this in
1417fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // C++0x, but it's still good hygiene.
1418b5bc7d04447026252b5181537ab4edcfdbeb3587Francois Pichet  if (!SpecString.empty() && SpecString[SpecString.size() - 1] == '>')
1419fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    SpecString += ' ';
1420fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1421dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor  if (!SkipBrackets)
1422dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor    SpecString += '>';
1423fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1424fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  return SpecString;
1425fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
1426fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1427fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// Sadly, repeat all that with TemplateArgLoc.
1428fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string TemplateSpecializationType::
1429fee8a3c003a8894002810a6373bd5b895290974eDouglas GregorPrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs,
1430fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor                          const PrintingPolicy &Policy) {
1431fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  std::string SpecString;
1432fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  SpecString += '<';
1433fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
1434dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor    if (SpecString.size() > 1)
1435fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      SpecString += ", ";
1436fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1437fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // Print the argument into a string.
1438fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    std::string ArgString;
1439dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor    if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) {
1440dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor      ArgString = PrintTemplateArgumentList(
1441dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor                                           Args[Arg].getArgument().pack_begin(),
1442dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor                                            Args[Arg].getArgument().pack_size(),
1443dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor                                            Policy, true);
1444dace95b13e2ceb0c3ec8de6babd926dc5114e1e5Douglas Gregor    } else {
144587dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor      llvm::raw_string_ostream ArgOut(ArgString);
144687dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor      Args[Arg].getArgument().print(Policy, ArgOut);
144787dd697dcc8ecb64df73ae64d61b8c80ff0c157cDouglas Gregor    }
1448fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1449fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // If this is the first argument and its string representation
1450fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // begins with the global scope specifier ('::foo'), add a space
1451fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    // to avoid printing the diagraph '<:'.
1452fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    if (!Arg && !ArgString.empty() && ArgString[0] == ':')
1453fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor      SpecString += ' ';
1454fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1455fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    SpecString += ArgString;
1456fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
1457fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1458fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // If the last character of our string is '>', add another space to
1459fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // keep the two '>''s separate tokens. We don't *have* to do this in
1460fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  // C++0x, but it's still good hygiene.
1461fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (SpecString[SpecString.size() - 1] == '>')
1462fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    SpecString += ' ';
1463fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1464fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  SpecString += '>';
1465fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1466fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  return SpecString;
1467fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
1468fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1469fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid QualType::dump(const char *msg) const {
1470fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  if (msg)
1471e7cb7e4570842297f698bd7fd8d85520fc008acdDaniel Dunbar    llvm::errs() << msg << ": ";
14727ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  LangOptions LO;
14737ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  print(llvm::errs(), PrintingPolicy(LO), "identifier");
14747ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  llvm::errs() << '\n';
1475fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
1476fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid QualType::dump() const {
14777ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  dump(0);
1478fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
1479fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1480fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorvoid Type::dump() const {
1481fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  QualType(this, 0).dump();
1482fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
1483fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1484fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregorstd::string Qualifiers::getAsString() const {
1485fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  LangOptions LO;
1486fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  return getAsString(PrintingPolicy(LO));
1487fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
1488fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
1489fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// Appends qualifiers to the given string, separated by spaces.  Will
1490fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// prefix a space if the string is non-empty.  Will not append a final
1491fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor// space.
14927ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisstd::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {
14937ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SmallString<64> Buf;
14947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  llvm::raw_svector_ostream StrOS(Buf);
14957ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  print(StrOS, Policy);
14967ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  return StrOS.str();
14977ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
14987ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
14997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisbool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const {
15007ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (getCVRQualifiers())
15017ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    return false;
15027ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
15037ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (getAddressSpace())
15047ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    return false;
15057ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
15067ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (getObjCGCAttr())
15077ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    return false;
15087ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
15097ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime())
15107ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))
15117ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      return false;
15127ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
15137ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  return true;
15147ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
15157ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
15167ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis// Appends qualifiers to the given string, separated by spaces.  Will
15177ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis// prefix a space if the string is non-empty.  Will not append a final
15187ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis// space.
15197ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
15207ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                       bool appendSpaceIfNonEmpty) const {
15217ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  bool addSpace = false;
15227ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
15237ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  unsigned quals = getCVRQualifiers();
15247ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (quals) {
15257ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    AppendTypeQualList(OS, quals);
15267ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    addSpace = true;
15277ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  }
152814aa2175416f79ef17811282afbf425f87d54ebfJohn McCall  if (unsigned addrspace = getAddressSpace()) {
15297ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (addSpace)
15307ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << ' ';
15317ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    addSpace = true;
153263cf68a4fcb93b502934d0d9c4e2ea407180ceb9Peter Collingbourne    switch (addrspace) {
153363cf68a4fcb93b502934d0d9c4e2ea407180ceb9Peter Collingbourne      case LangAS::opencl_global:
15347ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        OS << "__global";
153563cf68a4fcb93b502934d0d9c4e2ea407180ceb9Peter Collingbourne        break;
153663cf68a4fcb93b502934d0d9c4e2ea407180ceb9Peter Collingbourne      case LangAS::opencl_local:
15377ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        OS << "__local";
153863cf68a4fcb93b502934d0d9c4e2ea407180ceb9Peter Collingbourne        break;
153963cf68a4fcb93b502934d0d9c4e2ea407180ceb9Peter Collingbourne      case LangAS::opencl_constant:
15407ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        OS << "__constant";
154163cf68a4fcb93b502934d0d9c4e2ea407180ceb9Peter Collingbourne        break;
154263cf68a4fcb93b502934d0d9c4e2ea407180ceb9Peter Collingbourne      default:
15437ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        OS << "__attribute__((address_space(";
15447ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        OS << addrspace;
15457ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        OS << ")))";
154663cf68a4fcb93b502934d0d9c4e2ea407180ceb9Peter Collingbourne    }
1547fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
154814aa2175416f79ef17811282afbf425f87d54ebfJohn McCall  if (Qualifiers::GC gc = getObjCGCAttr()) {
15497ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (addSpace)
15507ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << ' ';
15517ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    addSpace = true;
155214aa2175416f79ef17811282afbf425f87d54ebfJohn McCall    if (gc == Qualifiers::Weak)
15537ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << "__weak";
1554fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor    else
15557ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      OS << "__strong";
1556fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor  }
1557f85e193739c953358c865005855253af4f68a497John McCall  if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {
15587ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){
15597ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      if (addSpace)
15607ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        OS << ' ';
15617ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis      addSpace = true;
15627ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    }
156316d0078d2a4b1024cbeca8e1ebe7c0ed45554f11Axel Naumann
1564f85e193739c953358c865005855253af4f68a497John McCall    switch (lifetime) {
1565f85e193739c953358c865005855253af4f68a497John McCall    case Qualifiers::OCL_None: llvm_unreachable("none but true");
15667ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;
1567f85e193739c953358c865005855253af4f68a497John McCall    case Qualifiers::OCL_Strong:
1568f85e193739c953358c865005855253af4f68a497John McCall      if (!Policy.SuppressStrongLifetime)
15697ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis        OS << "__strong";
1570f85e193739c953358c865005855253af4f68a497John McCall      break;
1571f85e193739c953358c865005855253af4f68a497John McCall
15727ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    case Qualifiers::OCL_Weak: OS << "__weak"; break;
15737ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;
1574f85e193739c953358c865005855253af4f68a497John McCall    }
1575f85e193739c953358c865005855253af4f68a497John McCall  }
15767ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
15777ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (appendSpaceIfNonEmpty && addSpace)
15787ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    OS << ' ';
15797ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
15807ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
15817ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisstd::string QualType::getAsString(const PrintingPolicy &Policy) const {
15827ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  std::string S;
15837ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  getAsStringInternal(S, Policy);
15847ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  return S;
1585fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
1586fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
158749f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCallstd::string QualType::getAsString(const Type *ty, Qualifiers qs) {
158849f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall  std::string buffer;
158949f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall  LangOptions options;
159049f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall  getAsStringInternal(ty, qs, buffer, PrintingPolicy(options));
159149f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall  return buffer;
1592fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
1593fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor
15947ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidisvoid QualType::print(const Type *ty, Qualifiers qs,
15957ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                     raw_ostream &OS, const PrintingPolicy &policy,
15967ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis                     const Twine &PlaceHolder) {
15977ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SmallString<128> PHBuf;
15987ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  StringRef PH;
15997ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  if (PlaceHolder.isSingleStringRef())
16007ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    PH = PlaceHolder.getSingleStringRef();
16017ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  else
16027ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis    PH = PlaceHolder.toStringRef(PHBuf);
16037ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
16047ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  TypePrinter(policy).print(ty, qs, OS, PH);
16057ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis}
16067ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis
160749f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCallvoid QualType::getAsStringInternal(const Type *ty, Qualifiers qs,
160849f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall                                   std::string &buffer,
160949f4e1cbd839da27ff4814b4ea6d85a79f786cbdJohn McCall                                   const PrintingPolicy &policy) {
16107ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  SmallString<256> Buf;
16117ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  llvm::raw_svector_ostream StrOS(Buf);
16127ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  TypePrinter(policy).print(ty, qs, StrOS, buffer);
16137ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  std::string str = StrOS.str();
16147ad5c996e9519ed4e9afd1f0166be1cd2be8415aArgyrios Kyrtzidis  buffer.swap(str);
1615fee8a3c003a8894002810a6373bd5b895290974eDouglas Gregor}
1616