brintos

brintos / llvm-project-archived public Read only

0
0
Text · 92.6 KiB · d2881d5 Raw
2828 lines · cpp
1//===- TypePrinter.cpp - Pretty-Print Clang Types -------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This contains code to print types from Clang's type system.10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/ASTContext.h"14#include "clang/AST/Attr.h"15#include "clang/AST/Decl.h"16#include "clang/AST/DeclBase.h"17#include "clang/AST/DeclCXX.h"18#include "clang/AST/DeclObjC.h"19#include "clang/AST/DeclTemplate.h"20#include "clang/AST/Expr.h"21#include "clang/AST/NestedNameSpecifier.h"22#include "clang/AST/PrettyPrinter.h"23#include "clang/AST/TemplateBase.h"24#include "clang/AST/TemplateName.h"25#include "clang/AST/Type.h"26#include "clang/Basic/AddressSpaces.h"27#include "clang/Basic/AttrKinds.h"28#include "clang/Basic/ExceptionSpecificationType.h"29#include "clang/Basic/IdentifierTable.h"30#include "clang/Basic/LLVM.h"31#include "clang/Basic/LangOptions.h"32#include "clang/Basic/SourceLocation.h"33#include "clang/Basic/SourceManager.h"34#include "clang/Basic/Specifiers.h"35#include "llvm/ADT/ArrayRef.h"36#include "llvm/ADT/DenseMap.h"37#include "llvm/ADT/SmallString.h"38#include "llvm/ADT/StringRef.h"39#include "llvm/ADT/Twine.h"40#include "llvm/Support/Compiler.h"41#include "llvm/Support/ErrorHandling.h"42#include "llvm/Support/SaveAndRestore.h"43#include "llvm/Support/raw_ostream.h"44#include <cassert>45#include <string>46 47using namespace clang;48 49namespace {50 51/// RAII object that enables printing of the ARC __strong lifetime52/// qualifier.53class IncludeStrongLifetimeRAII {54  PrintingPolicy &Policy;55  bool Old;56 57public:58  explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)59      : Policy(Policy), Old(Policy.SuppressStrongLifetime) {60    if (!Policy.SuppressLifetimeQualifiers)61      Policy.SuppressStrongLifetime = false;62  }63 64  ~IncludeStrongLifetimeRAII() { Policy.SuppressStrongLifetime = Old; }65};66 67class ParamPolicyRAII {68  PrintingPolicy &Policy;69  bool Old;70 71public:72  explicit ParamPolicyRAII(PrintingPolicy &Policy)73      : Policy(Policy), Old(Policy.SuppressSpecifiers) {74    Policy.SuppressSpecifiers = false;75  }76 77  ~ParamPolicyRAII() { Policy.SuppressSpecifiers = Old; }78};79 80class DefaultTemplateArgsPolicyRAII {81  PrintingPolicy &Policy;82  bool Old;83 84public:85  explicit DefaultTemplateArgsPolicyRAII(PrintingPolicy &Policy)86      : Policy(Policy), Old(Policy.SuppressDefaultTemplateArgs) {87    Policy.SuppressDefaultTemplateArgs = false;88  }89 90  ~DefaultTemplateArgsPolicyRAII() { Policy.SuppressDefaultTemplateArgs = Old; }91};92 93class ElaboratedTypePolicyRAII {94  PrintingPolicy &Policy;95  bool SuppressTagKeyword;96  bool SuppressScope;97 98public:99  explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {100    SuppressTagKeyword = Policy.SuppressTagKeyword;101    SuppressScope = Policy.SuppressScope;102    Policy.SuppressTagKeyword = true;103    Policy.SuppressScope = true;104  }105 106  ~ElaboratedTypePolicyRAII() {107    Policy.SuppressTagKeyword = SuppressTagKeyword;108    Policy.SuppressScope = SuppressScope;109  }110};111 112class TypePrinter {113  PrintingPolicy Policy;114  unsigned Indentation;115  bool HasEmptyPlaceHolder = false;116  bool InsideCCAttribute = false;117 118public:119  explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0)120      : Policy(Policy), Indentation(Indentation) {}121 122  void print(const Type *ty, Qualifiers qs, raw_ostream &OS,123             StringRef PlaceHolder);124  void print(QualType T, raw_ostream &OS, StringRef PlaceHolder);125 126  static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier);127  void spaceBeforePlaceHolder(raw_ostream &OS);128  void printTypeSpec(NamedDecl *D, raw_ostream &OS);129  void printTemplateId(const TemplateSpecializationType *T, raw_ostream &OS,130                       bool FullyQualify);131 132  void printBefore(QualType T, raw_ostream &OS);133  void printAfter(QualType T, raw_ostream &OS);134  void printTagType(const TagType *T, raw_ostream &OS);135  void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);136#define ABSTRACT_TYPE(CLASS, PARENT)137#define TYPE(CLASS, PARENT)                                                    \138  void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS);            \139  void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);140#include "clang/AST/TypeNodes.inc"141 142private:143  void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);144  void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);145};146 147} // namespace148 149static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals,150                               bool HasRestrictKeyword) {151  bool appendSpace = false;152  if (TypeQuals & Qualifiers::Const) {153    OS << "const";154    appendSpace = true;155  }156  if (TypeQuals & Qualifiers::Volatile) {157    if (appendSpace) OS << ' ';158    OS << "volatile";159    appendSpace = true;160  }161  if (TypeQuals & Qualifiers::Restrict) {162    if (appendSpace) OS << ' ';163    if (HasRestrictKeyword) {164      OS << "restrict";165    } else {166      OS << "__restrict";167    }168  }169}170 171void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {172  if (!HasEmptyPlaceHolder)173    OS << ' ';174}175 176static SplitQualType splitAccordingToPolicy(QualType QT,177                                            const PrintingPolicy &Policy) {178  if (Policy.PrintAsCanonical)179    QT = QT.getCanonicalType();180  return QT.split();181}182 183void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {184  SplitQualType split = splitAccordingToPolicy(t, Policy);185  print(split.Ty, split.Quals, OS, PlaceHolder);186}187 188void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,189                        StringRef PlaceHolder) {190  if (!T) {191    OS << "NULL TYPE";192    return;193  }194 195  SaveAndRestore PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());196 197  printBefore(T, Quals, OS);198  OS << PlaceHolder;199  printAfter(T, Quals, OS);200}201 202bool TypePrinter::canPrefixQualifiers(const Type *T,203                                      bool &NeedARCStrongQualifier) {204  // CanPrefixQualifiers - We prefer to print type qualifiers before the type,205  // so that we get "const int" instead of "int const", but we can't do this if206  // the type is complex.  For example if the type is "int*", we *must* print207  // "int * const", printing "const int *" is different.  Only do this when the208  // type expands to a simple string.209  bool CanPrefixQualifiers = false;210  NeedARCStrongQualifier = false;211  const Type *UnderlyingType = T;212  if (const auto *AT = dyn_cast<AutoType>(T))213    UnderlyingType = AT->desugar().getTypePtr();214  if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(T))215    UnderlyingType = Subst->getReplacementType().getTypePtr();216  Type::TypeClass TC = UnderlyingType->getTypeClass();217 218  switch (TC) {219    case Type::Auto:220    case Type::Builtin:221    case Type::Complex:222    case Type::UnresolvedUsing:223    case Type::Using:224    case Type::Typedef:225    case Type::TypeOfExpr:226    case Type::TypeOf:227    case Type::Decltype:228    case Type::UnaryTransform:229    case Type::Record:230    case Type::Enum:231    case Type::TemplateTypeParm:232    case Type::SubstTemplateTypeParmPack:233    case Type::SubstBuiltinTemplatePack:234    case Type::DeducedTemplateSpecialization:235    case Type::TemplateSpecialization:236    case Type::InjectedClassName:237    case Type::DependentName:238    case Type::ObjCObject:239    case Type::ObjCTypeParam:240    case Type::ObjCInterface:241    case Type::Atomic:242    case Type::Pipe:243    case Type::BitInt:244    case Type::DependentBitInt:245    case Type::BTFTagAttributed:246    case Type::HLSLAttributedResource:247    case Type::HLSLInlineSpirv:248    case Type::PredefinedSugar:249      CanPrefixQualifiers = true;250      break;251 252    case Type::ObjCObjectPointer:253      CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() ||254        T->isObjCQualifiedIdType() || T->isObjCQualifiedClassType();255      break;256 257    case Type::VariableArray:258    case Type::DependentSizedArray:259      NeedARCStrongQualifier = true;260      [[fallthrough]];261 262    case Type::ConstantArray:263    case Type::IncompleteArray:264      return canPrefixQualifiers(265          cast<ArrayType>(UnderlyingType)->getElementType().getTypePtr(),266          NeedARCStrongQualifier);267 268    case Type::Adjusted:269    case Type::Decayed:270    case Type::ArrayParameter:271    case Type::Pointer:272    case Type::BlockPointer:273    case Type::LValueReference:274    case Type::RValueReference:275    case Type::MemberPointer:276    case Type::DependentAddressSpace:277    case Type::DependentVector:278    case Type::DependentSizedExtVector:279    case Type::Vector:280    case Type::ExtVector:281    case Type::ConstantMatrix:282    case Type::DependentSizedMatrix:283    case Type::FunctionProto:284    case Type::FunctionNoProto:285    case Type::Paren:286    case Type::PackExpansion:287    case Type::SubstTemplateTypeParm:288    case Type::MacroQualified:289    case Type::CountAttributed:290      CanPrefixQualifiers = false;291      break;292 293    case Type::Attributed: {294      // We still want to print the address_space before the type if it is an295      // address_space attribute.296      const auto *AttrTy = cast<AttributedType>(UnderlyingType);297      CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;298      break;299    }300    case Type::PackIndexing: {301      return canPrefixQualifiers(302          cast<PackIndexingType>(UnderlyingType)->getPattern().getTypePtr(),303          NeedARCStrongQualifier);304    }305  }306 307  return CanPrefixQualifiers;308}309 310void TypePrinter::printBefore(QualType T, raw_ostream &OS) {311  SplitQualType Split = splitAccordingToPolicy(T, Policy);312 313  // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2314  // at this level.315  Qualifiers Quals = Split.Quals;316  if (const auto *Subst = dyn_cast<SubstTemplateTypeParmType>(Split.Ty))317    Quals -= QualType(Subst, 0).getQualifiers();318 319  printBefore(Split.Ty, Quals, OS);320}321 322/// Prints the part of the type string before an identifier, e.g. for323/// "int foo[10]" it prints "int ".324void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {325  if (Policy.SuppressSpecifiers && T->isSpecifierType())326    return;327 328  SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder);329 330  // Print qualifiers as appropriate.331 332  bool CanPrefixQualifiers = false;333  bool NeedARCStrongQualifier = false;334  CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);335 336  if (CanPrefixQualifiers && !Quals.empty()) {337    if (NeedARCStrongQualifier) {338      IncludeStrongLifetimeRAII Strong(Policy);339      Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);340    } else {341      Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);342    }343  }344 345  bool hasAfterQuals = false;346  if (!CanPrefixQualifiers && !Quals.empty()) {347    hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy);348    if (hasAfterQuals)349      HasEmptyPlaceHolder = false;350  }351 352  switch (T->getTypeClass()) {353#define ABSTRACT_TYPE(CLASS, PARENT)354#define TYPE(CLASS, PARENT) case Type::CLASS: \355    print##CLASS##Before(cast<CLASS##Type>(T), OS); \356    break;357#include "clang/AST/TypeNodes.inc"358  }359 360  if (hasAfterQuals) {361    if (NeedARCStrongQualifier) {362      IncludeStrongLifetimeRAII Strong(Policy);363      Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());364    } else {365      Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get());366    }367  }368}369 370void TypePrinter::printAfter(QualType t, raw_ostream &OS) {371  SplitQualType split = splitAccordingToPolicy(t, Policy);372  printAfter(split.Ty, split.Quals, OS);373}374 375/// Prints the part of the type string after an identifier, e.g. for376/// "int foo[10]" it prints "[10]".377void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {378  switch (T->getTypeClass()) {379#define ABSTRACT_TYPE(CLASS, PARENT)380#define TYPE(CLASS, PARENT) case Type::CLASS: \381    print##CLASS##After(cast<CLASS##Type>(T), OS); \382    break;383#include "clang/AST/TypeNodes.inc"384  }385}386 387void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {388  OS << T->getName(Policy);389  spaceBeforePlaceHolder(OS);390}391 392void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}393 394void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {395  OS << "_Complex ";396  printBefore(T->getElementType(), OS);397}398 399void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {400  printAfter(T->getElementType(), OS);401}402 403void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {404  IncludeStrongLifetimeRAII Strong(Policy);405  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);406  printBefore(T->getPointeeType(), OS);407  // Handle things like 'int (*A)[4];' correctly.408  // FIXME: this should include vectors, but vectors use attributes I guess.409  if (isa<ArrayType>(T->getPointeeType()))410    OS << '(';411  OS << '*';412}413 414void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {415  IncludeStrongLifetimeRAII Strong(Policy);416  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);417  // Handle things like 'int (*A)[4];' correctly.418  // FIXME: this should include vectors, but vectors use attributes I guess.419  if (isa<ArrayType>(T->getPointeeType()))420    OS << ')';421  printAfter(T->getPointeeType(), OS);422}423 424void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,425                                          raw_ostream &OS) {426  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);427  printBefore(T->getPointeeType(), OS);428  OS << '^';429}430 431void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,432                                          raw_ostream &OS) {433  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);434  printAfter(T->getPointeeType(), OS);435}436 437// When printing a reference, the referenced type might also be a reference.438// If so, we want to skip that before printing the inner type.439static QualType skipTopLevelReferences(QualType T) {440  if (auto *Ref = T->getAs<ReferenceType>())441    return skipTopLevelReferences(Ref->getPointeeTypeAsWritten());442  return T;443}444 445void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,446                                             raw_ostream &OS) {447  IncludeStrongLifetimeRAII Strong(Policy);448  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);449  QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());450  printBefore(Inner, OS);451  // Handle things like 'int (&A)[4];' correctly.452  // FIXME: this should include vectors, but vectors use attributes I guess.453  if (isa<ArrayType>(Inner))454    OS << '(';455  OS << '&';456}457 458void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,459                                            raw_ostream &OS) {460  IncludeStrongLifetimeRAII Strong(Policy);461  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);462  QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());463  // Handle things like 'int (&A)[4];' correctly.464  // FIXME: this should include vectors, but vectors use attributes I guess.465  if (isa<ArrayType>(Inner))466    OS << ')';467  printAfter(Inner, OS);468}469 470void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,471                                             raw_ostream &OS) {472  IncludeStrongLifetimeRAII Strong(Policy);473  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);474  QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());475  printBefore(Inner, OS);476  // Handle things like 'int (&&A)[4];' correctly.477  // FIXME: this should include vectors, but vectors use attributes I guess.478  if (isa<ArrayType>(Inner))479    OS << '(';480  OS << "&&";481}482 483void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,484                                            raw_ostream &OS) {485  IncludeStrongLifetimeRAII Strong(Policy);486  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);487  QualType Inner = skipTopLevelReferences(T->getPointeeTypeAsWritten());488  // Handle things like 'int (&&A)[4];' correctly.489  // FIXME: this should include vectors, but vectors use attributes I guess.490  if (isa<ArrayType>(Inner))491    OS << ')';492  printAfter(Inner, OS);493}494 495void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,496                                           raw_ostream &OS) {497  IncludeStrongLifetimeRAII Strong(Policy);498  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);499  printBefore(T->getPointeeType(), OS);500  // Handle things like 'int (Cls::*A)[4];' correctly.501  // FIXME: this should include vectors, but vectors use attributes I guess.502  if (isa<ArrayType>(T->getPointeeType()))503    OS << '(';504  T->getQualifier().print(OS, Policy);505  OS << "*";506}507 508void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,509                                          raw_ostream &OS) {510  IncludeStrongLifetimeRAII Strong(Policy);511  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);512  // Handle things like 'int (Cls::*A)[4];' correctly.513  // FIXME: this should include vectors, but vectors use attributes I guess.514  if (isa<ArrayType>(T->getPointeeType()))515    OS << ')';516  printAfter(T->getPointeeType(), OS);517}518 519void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,520                                           raw_ostream &OS) {521  IncludeStrongLifetimeRAII Strong(Policy);522  printBefore(T->getElementType(), OS);523}524 525void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,526                                          raw_ostream &OS) {527  OS << '[';528  if (T->getIndexTypeQualifiers().hasQualifiers()) {529    AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(),530                       Policy.Restrict);531    OS << ' ';532  }533 534  if (T->getSizeModifier() == ArraySizeModifier::Static)535    OS << "static ";536 537  OS << T->getZExtSize() << ']';538  printAfter(T->getElementType(), OS);539}540 541void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,542                                             raw_ostream &OS) {543  IncludeStrongLifetimeRAII Strong(Policy);544  printBefore(T->getElementType(), OS);545}546 547void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,548                                            raw_ostream &OS) {549  OS << "[]";550  printAfter(T->getElementType(), OS);551}552 553void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,554                                           raw_ostream &OS) {555  IncludeStrongLifetimeRAII Strong(Policy);556  printBefore(T->getElementType(), OS);557}558 559void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,560                                          raw_ostream &OS) {561  OS << '[';562  if (T->getIndexTypeQualifiers().hasQualifiers()) {563    AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);564    OS << ' ';565  }566 567  if (T->getSizeModifier() == ArraySizeModifier::Static)568    OS << "static ";569  else if (T->getSizeModifier() == ArraySizeModifier::Star)570    OS << '*';571 572  if (T->getSizeExpr())573    T->getSizeExpr()->printPretty(OS, nullptr, Policy);574  OS << ']';575 576  printAfter(T->getElementType(), OS);577}578 579void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {580  // Print the adjusted representation, otherwise the adjustment will be581  // invisible.582  printBefore(T->getAdjustedType(), OS);583}584 585void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {586  printAfter(T->getAdjustedType(), OS);587}588 589void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {590  // Print as though it's a pointer.591  printAdjustedBefore(T, OS);592}593 594void TypePrinter::printArrayParameterAfter(const ArrayParameterType *T,595                                           raw_ostream &OS) {596  printConstantArrayAfter(T, OS);597}598 599void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T,600                                            raw_ostream &OS) {601  printConstantArrayBefore(T, OS);602}603 604void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {605  printAdjustedAfter(T, OS);606}607 608void TypePrinter::printDependentSizedArrayBefore(609                                               const DependentSizedArrayType *T,610                                               raw_ostream &OS) {611  IncludeStrongLifetimeRAII Strong(Policy);612  printBefore(T->getElementType(), OS);613}614 615void TypePrinter::printDependentSizedArrayAfter(616                                               const DependentSizedArrayType *T,617                                               raw_ostream &OS) {618  OS << '[';619  if (T->getSizeExpr())620    T->getSizeExpr()->printPretty(OS, nullptr, Policy);621  OS << ']';622  printAfter(T->getElementType(), OS);623}624 625void TypePrinter::printDependentAddressSpaceBefore(626    const DependentAddressSpaceType *T, raw_ostream &OS) {627  printBefore(T->getPointeeType(), OS);628}629 630void TypePrinter::printDependentAddressSpaceAfter(631    const DependentAddressSpaceType *T, raw_ostream &OS) {632  OS << " __attribute__((address_space(";633  if (T->getAddrSpaceExpr())634    T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);635  OS << ")))";636  printAfter(T->getPointeeType(), OS);637}638 639void TypePrinter::printDependentSizedExtVectorBefore(640                                          const DependentSizedExtVectorType *T,641                                          raw_ostream &OS) {642  if (Policy.UseHLSLTypes)643    OS << "vector<";644  printBefore(T->getElementType(), OS);645}646 647void TypePrinter::printDependentSizedExtVectorAfter(648                                          const DependentSizedExtVectorType *T,649                                          raw_ostream &OS) {650  if (Policy.UseHLSLTypes) {651    OS << ", ";652    if (T->getSizeExpr())653      T->getSizeExpr()->printPretty(OS, nullptr, Policy);654    OS << ">";655  } else {656    OS << " __attribute__((ext_vector_type(";657    if (T->getSizeExpr())658      T->getSizeExpr()->printPretty(OS, nullptr, Policy);659    OS << ")))";660  }661  printAfter(T->getElementType(), OS);662}663 664void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {665  switch (T->getVectorKind()) {666  case VectorKind::AltiVecPixel:667    OS << "__vector __pixel ";668    break;669  case VectorKind::AltiVecBool:670    OS << "__vector __bool ";671    printBefore(T->getElementType(), OS);672    break;673  case VectorKind::AltiVecVector:674    OS << "__vector ";675    printBefore(T->getElementType(), OS);676    break;677  case VectorKind::Neon:678    OS << "__attribute__((neon_vector_type("679       << T->getNumElements() << "))) ";680    printBefore(T->getElementType(), OS);681    break;682  case VectorKind::NeonPoly:683    OS << "__attribute__((neon_polyvector_type(" <<684          T->getNumElements() << "))) ";685    printBefore(T->getElementType(), OS);686    break;687  case VectorKind::Generic: {688    // FIXME: We prefer to print the size directly here, but have no way689    // to get the size of the type.690    OS << "__attribute__((__vector_size__("691       << T->getNumElements()692       << " * sizeof(";693    print(T->getElementType(), OS, StringRef());694    OS << ")))) ";695    printBefore(T->getElementType(), OS);696    break;697  }698  case VectorKind::SveFixedLengthData:699  case VectorKind::SveFixedLengthPredicate:700    // FIXME: We prefer to print the size directly here, but have no way701    // to get the size of the type.702    OS << "__attribute__((__arm_sve_vector_bits__(";703 704    if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)705      // Predicates take a bit per byte of the vector size, multiply by 8 to706      // get the number of bits passed to the attribute.707      OS << T->getNumElements() * 8;708    else709      OS << T->getNumElements();710 711    OS << " * sizeof(";712    print(T->getElementType(), OS, StringRef());713    // Multiply by 8 for the number of bits.714    OS << ") * 8))) ";715    printBefore(T->getElementType(), OS);716    break;717  case VectorKind::RVVFixedLengthData:718  case VectorKind::RVVFixedLengthMask:719  case VectorKind::RVVFixedLengthMask_1:720  case VectorKind::RVVFixedLengthMask_2:721  case VectorKind::RVVFixedLengthMask_4:722    // FIXME: We prefer to print the size directly here, but have no way723    // to get the size of the type.724    OS << "__attribute__((__riscv_rvv_vector_bits__(";725 726    OS << T->getNumElements();727 728    OS << " * sizeof(";729    print(T->getElementType(), OS, StringRef());730    // Multiply by 8 for the number of bits.731    OS << ") * 8))) ";732    printBefore(T->getElementType(), OS);733    break;734  }735}736 737void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {738  printAfter(T->getElementType(), OS);739}740 741void TypePrinter::printDependentVectorBefore(742    const DependentVectorType *T, raw_ostream &OS) {743  switch (T->getVectorKind()) {744  case VectorKind::AltiVecPixel:745    OS << "__vector __pixel ";746    break;747  case VectorKind::AltiVecBool:748    OS << "__vector __bool ";749    printBefore(T->getElementType(), OS);750    break;751  case VectorKind::AltiVecVector:752    OS << "__vector ";753    printBefore(T->getElementType(), OS);754    break;755  case VectorKind::Neon:756    OS << "__attribute__((neon_vector_type(";757    if (T->getSizeExpr())758      T->getSizeExpr()->printPretty(OS, nullptr, Policy);759    OS << "))) ";760    printBefore(T->getElementType(), OS);761    break;762  case VectorKind::NeonPoly:763    OS << "__attribute__((neon_polyvector_type(";764    if (T->getSizeExpr())765      T->getSizeExpr()->printPretty(OS, nullptr, Policy);766    OS << "))) ";767    printBefore(T->getElementType(), OS);768    break;769  case VectorKind::Generic: {770    // FIXME: We prefer to print the size directly here, but have no way771    // to get the size of the type.772    OS << "__attribute__((__vector_size__(";773    if (T->getSizeExpr())774      T->getSizeExpr()->printPretty(OS, nullptr, Policy);775    OS << " * sizeof(";776    print(T->getElementType(), OS, StringRef());777    OS << ")))) ";778    printBefore(T->getElementType(), OS);779    break;780  }781  case VectorKind::SveFixedLengthData:782  case VectorKind::SveFixedLengthPredicate:783    // FIXME: We prefer to print the size directly here, but have no way784    // to get the size of the type.785    OS << "__attribute__((__arm_sve_vector_bits__(";786    if (T->getSizeExpr()) {787      T->getSizeExpr()->printPretty(OS, nullptr, Policy);788      if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)789        // Predicates take a bit per byte of the vector size, multiply by 8 to790        // get the number of bits passed to the attribute.791        OS << " * 8";792      OS << " * sizeof(";793      print(T->getElementType(), OS, StringRef());794      // Multiply by 8 for the number of bits.795      OS << ") * 8";796    }797    OS << "))) ";798    printBefore(T->getElementType(), OS);799    break;800  case VectorKind::RVVFixedLengthData:801  case VectorKind::RVVFixedLengthMask:802  case VectorKind::RVVFixedLengthMask_1:803  case VectorKind::RVVFixedLengthMask_2:804  case VectorKind::RVVFixedLengthMask_4:805    // FIXME: We prefer to print the size directly here, but have no way806    // to get the size of the type.807    OS << "__attribute__((__riscv_rvv_vector_bits__(";808    if (T->getSizeExpr()) {809      T->getSizeExpr()->printPretty(OS, nullptr, Policy);810      OS << " * sizeof(";811      print(T->getElementType(), OS, StringRef());812      // Multiply by 8 for the number of bits.813      OS << ") * 8";814    }815    OS << "))) ";816    printBefore(T->getElementType(), OS);817    break;818  }819}820 821void TypePrinter::printDependentVectorAfter(822    const DependentVectorType *T, raw_ostream &OS) {823  printAfter(T->getElementType(), OS);824}825 826void TypePrinter::printExtVectorBefore(const ExtVectorType *T,827                                       raw_ostream &OS) {828  if (Policy.UseHLSLTypes)829    OS << "vector<";830  printBefore(T->getElementType(), OS);831}832 833void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {834  printAfter(T->getElementType(), OS);835 836  if (Policy.UseHLSLTypes) {837    OS << ", ";838    OS << T->getNumElements();839    OS << ">";840  } else {841    OS << " __attribute__((ext_vector_type(";842    OS << T->getNumElements();843    OS << ")))";844  }845}846 847static void printDims(const ConstantMatrixType *T, raw_ostream &OS) {848  OS << T->getNumRows() << ", " << T->getNumColumns();849}850 851static void printHLSLMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T,852                                  raw_ostream &OS) {853  OS << "matrix<";854  TP.printBefore(T->getElementType(), OS);855}856 857static void printHLSLMatrixAfter(const ConstantMatrixType *T, raw_ostream &OS) {858  OS << ", ";859  printDims(T, OS);860  OS << ">";861}862 863static void printClangMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T,864                                   raw_ostream &OS) {865  TP.printBefore(T->getElementType(), OS);866  OS << " __attribute__((matrix_type(";867  printDims(T, OS);868  OS << ")))";869}870 871void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,872                                            raw_ostream &OS) {873  if (Policy.UseHLSLTypes) {874    printHLSLMatrixBefore(*this, T, OS);875    return;876  }877  printClangMatrixBefore(*this, T, OS);878}879 880void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,881                                           raw_ostream &OS) {882  if (Policy.UseHLSLTypes) {883    printHLSLMatrixAfter(T, OS);884    return;885  }886  printAfter(T->getElementType(), OS);887}888 889void TypePrinter::printDependentSizedMatrixBefore(890    const DependentSizedMatrixType *T, raw_ostream &OS) {891  printBefore(T->getElementType(), OS);892  OS << " __attribute__((matrix_type(";893  if (T->getRowExpr()) {894    T->getRowExpr()->printPretty(OS, nullptr, Policy);895  }896  OS << ", ";897  if (T->getColumnExpr()) {898    T->getColumnExpr()->printPretty(OS, nullptr, Policy);899  }900  OS << ")))";901}902 903void TypePrinter::printDependentSizedMatrixAfter(904    const DependentSizedMatrixType *T, raw_ostream &OS) {905  printAfter(T->getElementType(), OS);906}907 908void909FunctionProtoType::printExceptionSpecification(raw_ostream &OS,910                                               const PrintingPolicy &Policy)911                                                                         const {912  if (hasDynamicExceptionSpec()) {913    OS << " throw(";914    if (getExceptionSpecType() == EST_MSAny)915      OS << "...";916    else917      for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) {918        if (I)919          OS << ", ";920 921        OS << getExceptionType(I).stream(Policy);922      }923    OS << ')';924  } else if (EST_NoThrow == getExceptionSpecType()) {925    OS << " __attribute__((nothrow))";926  } else if (isNoexceptExceptionSpec(getExceptionSpecType())) {927    OS << " noexcept";928    // FIXME:Is it useful to print out the expression for a non-dependent929    // noexcept specification?930    if (isComputedNoexcept(getExceptionSpecType())) {931      OS << '(';932      if (getNoexceptExpr())933        getNoexceptExpr()->printPretty(OS, nullptr, Policy);934      OS << ')';935    }936  }937}938 939void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,940                                           raw_ostream &OS) {941  if (T->hasTrailingReturn()) {942    OS << "auto ";943    if (!HasEmptyPlaceHolder)944      OS << '(';945  } else {946    // If needed for precedence reasons, wrap the inner part in grouping parens.947    SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);948    printBefore(T->getReturnType(), OS);949    if (!PrevPHIsEmpty.get())950      OS << '(';951  }952}953 954StringRef clang::getParameterABISpelling(ParameterABI ABI) {955  switch (ABI) {956  case ParameterABI::Ordinary:957    llvm_unreachable("asking for spelling of ordinary parameter ABI");958  case ParameterABI::SwiftContext:959    return "swift_context";960  case ParameterABI::SwiftAsyncContext:961    return "swift_async_context";962  case ParameterABI::SwiftErrorResult:963    return "swift_error_result";964  case ParameterABI::SwiftIndirectResult:965    return "swift_indirect_result";966  case ParameterABI::HLSLOut:967    return "out";968  case ParameterABI::HLSLInOut:969    return "inout";970  }971  llvm_unreachable("bad parameter ABI kind");972}973 974void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,975                                          raw_ostream &OS) {976  // If needed for precedence reasons, wrap the inner part in grouping parens.977  if (!HasEmptyPlaceHolder)978    OS << ')';979  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);980 981  OS << '(';982  {983    ParamPolicyRAII ParamPolicy(Policy);984    for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {985      if (i) OS << ", ";986 987      auto EPI = T->getExtParameterInfo(i);988      if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";989      if (EPI.isNoEscape())990        OS << "__attribute__((noescape)) ";991      auto ABI = EPI.getABI();992      if (ABI == ParameterABI::HLSLInOut || ABI == ParameterABI::HLSLOut) {993        OS << getParameterABISpelling(ABI) << " ";994        if (Policy.UseHLSLTypes) {995          // This is a bit of a hack because we _do_ use reference types in the996          // AST for representing inout and out parameters so that code997          // generation is sane, but when re-printing these for HLSL we need to998          // skip the reference.999          print(T->getParamType(i).getNonReferenceType(), OS, StringRef());1000          continue;1001        }1002      } else if (ABI != ParameterABI::Ordinary)1003        OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";1004 1005      print(T->getParamType(i), OS, StringRef());1006    }1007  }1008 1009  if (T->isVariadic()) {1010    if (T->getNumParams())1011      OS << ", ";1012    OS << "...";1013  } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {1014    // Do not emit int() if we have a proto, emit 'int(void)'.1015    OS << "void";1016  }1017 1018  OS << ')';1019 1020  FunctionType::ExtInfo Info = T->getExtInfo();1021  unsigned SMEBits = T->getAArch64SMEAttributes();1022 1023  if (SMEBits & FunctionType::SME_PStateSMCompatibleMask)1024    OS << " __arm_streaming_compatible";1025  if (SMEBits & FunctionType::SME_PStateSMEnabledMask)1026    OS << " __arm_streaming";1027  if (SMEBits & FunctionType::SME_AgnosticZAStateMask)1028    OS << "__arm_agnostic(\"sme_za_state\")";1029  if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Preserves)1030    OS << " __arm_preserves(\"za\")";1031  if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_In)1032    OS << " __arm_in(\"za\")";1033  if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Out)1034    OS << " __arm_out(\"za\")";1035  if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_InOut)1036    OS << " __arm_inout(\"za\")";1037  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Preserves)1038    OS << " __arm_preserves(\"zt0\")";1039  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_In)1040    OS << " __arm_in(\"zt0\")";1041  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Out)1042    OS << " __arm_out(\"zt0\")";1043  if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_InOut)1044    OS << " __arm_inout(\"zt0\")";1045 1046  printFunctionAfter(Info, OS);1047 1048  if (!T->getMethodQuals().empty())1049    OS << " " << T->getMethodQuals().getAsString();1050 1051  switch (T->getRefQualifier()) {1052  case RQ_None:1053    break;1054 1055  case RQ_LValue:1056    OS << " &";1057    break;1058 1059  case RQ_RValue:1060    OS << " &&";1061    break;1062  }1063  T->printExceptionSpecification(OS, Policy);1064 1065  const FunctionEffectsRef FX = T->getFunctionEffects();1066  for (const auto &CFE : FX) {1067    OS << " __attribute__((" << CFE.Effect.name();1068    if (const Expr *E = CFE.Cond.getCondition()) {1069      OS << '(';1070      E->printPretty(OS, nullptr, Policy);1071      OS << ')';1072    }1073    OS << "))";1074  }1075 1076  if (T->hasCFIUncheckedCallee())1077    OS << " __attribute__((cfi_unchecked_callee))";1078 1079  if (T->hasTrailingReturn()) {1080    OS << " -> ";1081    print(T->getReturnType(), OS, StringRef());1082  } else1083    printAfter(T->getReturnType(), OS);1084}1085 1086void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,1087                                     raw_ostream &OS) {1088  if (!InsideCCAttribute) {1089    switch (Info.getCC()) {1090    case CC_C:1091      // The C calling convention is the default on the vast majority of platforms1092      // we support.  If the user wrote it explicitly, it will usually be printed1093      // while traversing the AttributedType.  If the type has been desugared, let1094      // the canonical spelling be the implicit calling convention.1095      // FIXME: It would be better to be explicit in certain contexts, such as a1096      // cdecl function typedef used to declare a member function with the1097      // Microsoft C++ ABI.1098      break;1099    case CC_X86StdCall:1100      OS << " __attribute__((stdcall))";1101      break;1102    case CC_X86FastCall:1103      OS << " __attribute__((fastcall))";1104      break;1105    case CC_X86ThisCall:1106      OS << " __attribute__((thiscall))";1107      break;1108    case CC_X86VectorCall:1109      OS << " __attribute__((vectorcall))";1110      break;1111    case CC_X86Pascal:1112      OS << " __attribute__((pascal))";1113      break;1114    case CC_AAPCS:1115      OS << " __attribute__((pcs(\"aapcs\")))";1116      break;1117    case CC_AAPCS_VFP:1118      OS << " __attribute__((pcs(\"aapcs-vfp\")))";1119      break;1120    case CC_AArch64VectorCall:1121      OS << " __attribute__((aarch64_vector_pcs))";1122      break;1123    case CC_AArch64SVEPCS:1124      OS << " __attribute__((aarch64_sve_pcs))";1125      break;1126    case CC_DeviceKernel:1127      OS << " __attribute__((device_kernel))";1128      break;1129    case CC_IntelOclBicc:1130      OS << " __attribute__((intel_ocl_bicc))";1131      break;1132    case CC_Win64:1133      OS << " __attribute__((ms_abi))";1134      break;1135    case CC_X86_64SysV:1136      OS << " __attribute__((sysv_abi))";1137      break;1138    case CC_X86RegCall:1139      OS << " __attribute__((regcall))";1140      break;1141    case CC_SpirFunction:1142      // Do nothing. These CCs are not available as attributes.1143      break;1144    case CC_Swift:1145      OS << " __attribute__((swiftcall))";1146      break;1147    case CC_SwiftAsync:1148      OS << "__attribute__((swiftasynccall))";1149      break;1150    case CC_PreserveMost:1151      OS << " __attribute__((preserve_most))";1152      break;1153    case CC_PreserveAll:1154      OS << " __attribute__((preserve_all))";1155      break;1156    case CC_M68kRTD:1157      OS << " __attribute__((m68k_rtd))";1158      break;1159    case CC_PreserveNone:1160      OS << " __attribute__((preserve_none))";1161      break;1162    case CC_RISCVVectorCall:1163      OS << "__attribute__((riscv_vector_cc))";1164      break;1165#define CC_VLS_CASE(ABI_VLEN)                                                  \1166  case CC_RISCVVLSCall_##ABI_VLEN:                                             \1167    OS << "__attribute__((riscv_vls_cc" #ABI_VLEN "))";                        \1168    break;1169      CC_VLS_CASE(32)1170      CC_VLS_CASE(64)1171      CC_VLS_CASE(128)1172      CC_VLS_CASE(256)1173      CC_VLS_CASE(512)1174      CC_VLS_CASE(1024)1175      CC_VLS_CASE(2048)1176      CC_VLS_CASE(4096)1177      CC_VLS_CASE(8192)1178      CC_VLS_CASE(16384)1179      CC_VLS_CASE(32768)1180      CC_VLS_CASE(65536)1181#undef CC_VLS_CASE1182    }1183  }1184 1185  if (Info.getNoReturn())1186    OS << " __attribute__((noreturn))";1187  if (Info.getCmseNSCall())1188    OS << " __attribute__((cmse_nonsecure_call))";1189  if (Info.getProducesResult())1190    OS << " __attribute__((ns_returns_retained))";1191  if (Info.getRegParm())1192    OS << " __attribute__((regparm ("1193       << Info.getRegParm() << ")))";1194  if (Info.getNoCallerSavedRegs())1195    OS << " __attribute__((no_caller_saved_registers))";1196  if (Info.getNoCfCheck())1197    OS << " __attribute__((nocf_check))";1198}1199 1200void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,1201                                             raw_ostream &OS) {1202  // If needed for precedence reasons, wrap the inner part in grouping parens.1203  SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);1204  printBefore(T->getReturnType(), OS);1205  if (!PrevPHIsEmpty.get())1206    OS << '(';1207}1208 1209void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,1210                                            raw_ostream &OS) {1211  // If needed for precedence reasons, wrap the inner part in grouping parens.1212  if (!HasEmptyPlaceHolder)1213    OS << ')';1214  SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);1215 1216  OS << "()";1217  printFunctionAfter(T->getExtInfo(), OS);1218  printAfter(T->getReturnType(), OS);1219}1220 1221void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {1222 1223  // Compute the full nested-name-specifier for this type.1224  // In C, this will always be empty except when the type1225  // being printed is anonymous within other Record.1226  if (!Policy.SuppressScope)1227    D->printNestedNameSpecifier(OS, Policy);1228 1229  IdentifierInfo *II = D->getIdentifier();1230  OS << II->getName();1231  spaceBeforePlaceHolder(OS);1232}1233 1234void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,1235                                             raw_ostream &OS) {1236  OS << TypeWithKeyword::getKeywordName(T->getKeyword());1237  if (T->getKeyword() != ElaboratedTypeKeyword::None)1238    OS << ' ';1239  auto *D = T->getDecl();1240  if (Policy.FullyQualifiedName || T->isCanonicalUnqualified()) {1241    D->printNestedNameSpecifier(OS, Policy);1242  } else {1243    T->getQualifier().print(OS, Policy);1244  }1245  OS << D->getIdentifier()->getName();1246  spaceBeforePlaceHolder(OS);1247}1248 1249void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,1250                                            raw_ostream &OS) {}1251 1252void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {1253  OS << TypeWithKeyword::getKeywordName(T->getKeyword());1254  if (T->getKeyword() != ElaboratedTypeKeyword::None)1255    OS << ' ';1256  auto *D = T->getDecl();1257  if (Policy.FullyQualifiedName) {1258    D->printNestedNameSpecifier(OS, Policy);1259  } else {1260    T->getQualifier().print(OS, Policy);1261  }1262  OS << D->getIdentifier()->getName();1263  spaceBeforePlaceHolder(OS);1264}1265 1266void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}1267 1268void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {1269  OS << TypeWithKeyword::getKeywordName(T->getKeyword());1270  if (T->getKeyword() != ElaboratedTypeKeyword::None)1271    OS << ' ';1272  auto *D = T->getDecl();1273  if (Policy.FullyQualifiedName) {1274    D->printNestedNameSpecifier(OS, Policy);1275  } else {1276    T->getQualifier().print(OS, Policy);1277  }1278  OS << D->getIdentifier()->getName();1279  spaceBeforePlaceHolder(OS);1280}1281 1282void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,1283                                            raw_ostream &OS) {1284  StringRef MacroName = T->getMacroIdentifier()->getName();1285  OS << MacroName << " ";1286 1287  // Since this type is meant to print the macro instead of the whole attribute,1288  // we trim any attributes and go directly to the original modified type.1289  printBefore(T->getModifiedType(), OS);1290}1291 1292void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,1293                                           raw_ostream &OS) {1294  printAfter(T->getModifiedType(), OS);1295}1296 1297void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}1298 1299void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,1300                                        raw_ostream &OS) {1301  OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "1302                                                 : "typeof ");1303  if (T->getUnderlyingExpr())1304    T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);1305  spaceBeforePlaceHolder(OS);1306}1307 1308void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,1309                                       raw_ostream &OS) {}1310 1311void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {1312  OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("1313                                                 : "typeof(");1314  print(T->getUnmodifiedType(), OS, StringRef());1315  OS << ')';1316  spaceBeforePlaceHolder(OS);1317}1318 1319void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}1320 1321void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {1322  OS << "decltype(";1323  if (const Expr *E = T->getUnderlyingExpr()) {1324    PrintingPolicy ExprPolicy = Policy;1325    ExprPolicy.PrintAsCanonical = T->isCanonicalUnqualified();1326    E->printPretty(OS, nullptr, ExprPolicy);1327  }1328  OS << ')';1329  spaceBeforePlaceHolder(OS);1330}1331 1332void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,1333                                          raw_ostream &OS) {1334  if (T->hasSelectedType()) {1335    OS << T->getSelectedType();1336  } else {1337    OS << T->getPattern() << "...[";1338    T->getIndexExpr()->printPretty(OS, nullptr, Policy);1339    OS << "]";1340  }1341  spaceBeforePlaceHolder(OS);1342}1343 1344void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,1345                                         raw_ostream &OS) {}1346 1347void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}1348 1349void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,1350                                            raw_ostream &OS) {1351  IncludeStrongLifetimeRAII Strong(Policy);1352 1353  static llvm::DenseMap<int, const char *> Transformation = {{1354#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait)                                  \1355  {UnaryTransformType::Enum, "__" #Trait},1356#include "clang/Basic/TransformTypeTraits.def"1357  }};1358  OS << Transformation[T->getUTTKind()] << '(';1359  print(T->getBaseType(), OS, StringRef());1360  OS << ')';1361  spaceBeforePlaceHolder(OS);1362}1363 1364void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,1365                                           raw_ostream &OS) {}1366 1367void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {1368  // If the type has been deduced, do not print 'auto'.1369  if (!T->getDeducedType().isNull()) {1370    printBefore(T->getDeducedType(), OS);1371  } else {1372    if (T->isConstrained()) {1373      // FIXME: Track a TypeConstraint as type sugar, so that we can print the1374      // type as it was written.1375      T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);1376      auto Args = T->getTypeConstraintArguments();1377      if (!Args.empty())1378        printTemplateArgumentList(1379            OS, Args, Policy,1380            T->getTypeConstraintConcept()->getTemplateParameters());1381      OS << ' ';1382    }1383    switch (T->getKeyword()) {1384    case AutoTypeKeyword::Auto: OS << "auto"; break;1385    case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;1386    case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;1387    }1388    spaceBeforePlaceHolder(OS);1389  }1390}1391 1392void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {1393  // If the type has been deduced, do not print 'auto'.1394  if (!T->getDeducedType().isNull())1395    printAfter(T->getDeducedType(), OS);1396}1397 1398void TypePrinter::printDeducedTemplateSpecializationBefore(1399    const DeducedTemplateSpecializationType *T, raw_ostream &OS) {1400  if (ElaboratedTypeKeyword Keyword = T->getKeyword();1401      T->getKeyword() != ElaboratedTypeKeyword::None)1402    OS << KeywordHelpers::getKeywordName(Keyword) << ' ';1403 1404  TemplateName Name = T->getTemplateName();1405 1406  // If the type has been deduced, print the template arguments, as if this was1407  // printing the deduced type, but including elaboration and template name1408  // qualification.1409  // FIXME: There should probably be a policy which controls this.1410  // We would probably want to do this on diagnostics, but not on -ast-print.1411  ArrayRef<TemplateArgument> Args;1412  TemplateDecl *DeducedTD = nullptr;1413  if (!T->getDeducedType().isNull()) {1414    if (const auto *TST =1415            dyn_cast<TemplateSpecializationType>(T->getDeducedType())) {1416      DeducedTD = TST->getTemplateName().getAsTemplateDecl(1417          /*IgnoreDeduced=*/true);1418      Args = TST->template_arguments();1419    } else {1420      // Should only get here for canonical types.1421      const auto *CD = cast<ClassTemplateSpecializationDecl>(1422          cast<RecordType>(T->getDeducedType())->getDecl());1423      DeducedTD = CD->getSpecializedTemplate();1424      Args = CD->getTemplateArgs().asArray();1425    }1426 1427    // FIXME: Workaround for alias template CTAD not producing guides which1428    // include the alias template specialization type.1429    // Purposefully disregard qualification when building this TemplateName;1430    // any qualification we might have, might not make sense in the1431    // context this was deduced.1432    if (!declaresSameEntity(DeducedTD, Name.getAsTemplateDecl(1433                                           /*IgnoreDeduced=*/true)))1434      Name = TemplateName(DeducedTD);1435  }1436 1437  {1438    IncludeStrongLifetimeRAII Strong(Policy);1439    Name.print(OS, Policy);1440  }1441  if (DeducedTD) {1442    printTemplateArgumentList(OS, Args, Policy,1443                              DeducedTD->getTemplateParameters());1444  }1445 1446  spaceBeforePlaceHolder(OS);1447}1448 1449void TypePrinter::printDeducedTemplateSpecializationAfter(1450    const DeducedTemplateSpecializationType *T, raw_ostream &OS) {1451  // If the type has been deduced, print the deduced type.1452  if (!T->getDeducedType().isNull())1453    printAfter(T->getDeducedType(), OS);1454}1455 1456void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {1457  IncludeStrongLifetimeRAII Strong(Policy);1458 1459  OS << "_Atomic(";1460  print(T->getValueType(), OS, StringRef());1461  OS << ')';1462  spaceBeforePlaceHolder(OS);1463}1464 1465void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}1466 1467void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {1468  IncludeStrongLifetimeRAII Strong(Policy);1469 1470  if (T->isReadOnly())1471    OS << "read_only ";1472  else1473    OS << "write_only ";1474  OS << "pipe ";1475  print(T->getElementType(), OS, StringRef());1476  spaceBeforePlaceHolder(OS);1477}1478 1479void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}1480 1481void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {1482  if (T->isUnsigned())1483    OS << "unsigned ";1484  OS << "_BitInt(" << T->getNumBits() << ")";1485  spaceBeforePlaceHolder(OS);1486}1487 1488void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}1489 1490void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,1491                                             raw_ostream &OS) {1492  if (T->isUnsigned())1493    OS << "unsigned ";1494  OS << "_BitInt(";1495  T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);1496  OS << ")";1497  spaceBeforePlaceHolder(OS);1498}1499 1500void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,1501                                            raw_ostream &OS) {}1502 1503void TypePrinter::printPredefinedSugarBefore(const PredefinedSugarType *T,1504                                             raw_ostream &OS) {1505  OS << T->getIdentifier()->getName();1506  spaceBeforePlaceHolder(OS);1507}1508 1509void TypePrinter::printPredefinedSugarAfter(const PredefinedSugarType *T,1510                                            raw_ostream &OS) {}1511 1512void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {1513  TagDecl *D = T->getDecl();1514 1515  if (Policy.IncludeTagDefinition && T->isTagOwned()) {1516    D->print(OS, Policy, Indentation);1517    spaceBeforePlaceHolder(OS);1518    return;1519  }1520 1521  bool HasKindDecoration = false;1522 1523  if (T->isCanonicalUnqualified()) {1524    if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {1525      HasKindDecoration = true;1526      OS << D->getKindName();1527      OS << ' ';1528    }1529  } else {1530    OS << TypeWithKeyword::getKeywordName(T->getKeyword());1531    if (T->getKeyword() != ElaboratedTypeKeyword::None)1532      OS << ' ';1533  }1534 1535  if (!Policy.FullyQualifiedName && !T->isCanonicalUnqualified()) {1536    T->getQualifier().print(OS, Policy);1537  } else if (!Policy.SuppressScope) {1538    // Compute the full nested-name-specifier for this type.1539    // In C, this will always be empty except when the type1540    // being printed is anonymous within other Record.1541    D->printNestedNameSpecifier(OS, Policy);1542  }1543 1544  if (const IdentifierInfo *II = D->getIdentifier())1545    OS << II->getName();1546  else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {1547    assert(Typedef->getIdentifier() && "Typedef without identifier?");1548    OS << Typedef->getIdentifier()->getName();1549  } else {1550    // Make an unambiguous representation for anonymous types, e.g.1551    //   (anonymous enum at /usr/include/string.h:120:9)1552    OS << (Policy.MSVCFormatting ? '`' : '(');1553 1554    if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {1555      OS << "lambda";1556      HasKindDecoration = true;1557    } else if ((isa<RecordDecl>(D) && cast<RecordDecl>(D)->isAnonymousStructOrUnion())) {1558      OS << "anonymous";1559    } else {1560      OS << "unnamed";1561    }1562 1563    if (Policy.AnonymousTagLocations) {1564      // Suppress the redundant tag keyword if we just printed one.1565      // We don't have to worry about ElaboratedTypes here because you can't1566      // refer to an anonymous type with one.1567      if (!HasKindDecoration)1568        OS << " " << D->getKindName();1569 1570      PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc(1571          D->getLocation());1572      if (PLoc.isValid()) {1573        OS << " at ";1574        StringRef File = PLoc.getFilename();1575        llvm::SmallString<1024> WrittenFile(File);1576        if (auto *Callbacks = Policy.Callbacks)1577          WrittenFile = Callbacks->remapPath(File);1578        // Fix inconsistent path separator created by1579        // clang::DirectoryLookup::LookupFile when the file path is relative1580        // path.1581        llvm::sys::path::Style Style =1582            llvm::sys::path::is_absolute(WrittenFile)1583                ? llvm::sys::path::Style::native1584                : (Policy.MSVCFormatting1585                       ? llvm::sys::path::Style::windows_backslash1586                       : llvm::sys::path::Style::posix);1587        llvm::sys::path::native(WrittenFile, Style);1588        OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();1589      }1590    }1591 1592    OS << (Policy.MSVCFormatting ? '\'' : ')');1593  }1594 1595  // If this is a class template specialization, print the template1596  // arguments.1597  if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {1598    const TemplateParameterList *TParams =1599        S->getSpecializedTemplate()->getTemplateParameters();1600    const ASTTemplateArgumentListInfo *TArgAsWritten =1601        S->getTemplateArgsAsWritten();1602    IncludeStrongLifetimeRAII Strong(Policy);1603    if (TArgAsWritten && !Policy.PrintAsCanonical)1604      printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,1605                                TParams);1606    else1607      printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,1608                                TParams);1609  }1610 1611  spaceBeforePlaceHolder(OS);1612}1613 1614void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {1615  // Print the preferred name if we have one for this type.1616  if (Policy.UsePreferredNames) {1617    for (const auto *PNA : T->getDecl()1618                               ->getMostRecentDecl()1619                               ->specific_attrs<PreferredNameAttr>()) {1620      if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),1621                              T->getDecl()))1622        continue;1623      // Find the outermost typedef or alias template.1624      QualType T = PNA->getTypedefType();1625      while (true) {1626        if (auto *TT = dyn_cast<TypedefType>(T))1627          return printTypeSpec(TT->getDecl(), OS);1628        if (auto *TST = dyn_cast<TemplateSpecializationType>(T))1629          return printTemplateId(TST, OS, /*FullyQualify=*/true);1630        T = T->getLocallyUnqualifiedSingleStepDesugaredType();1631      }1632    }1633  }1634 1635  printTagType(T, OS);1636}1637 1638void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}1639 1640void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {1641  printTagType(T, OS);1642}1643 1644void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}1645 1646void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,1647                                               raw_ostream &OS) {1648  const ASTContext &Ctx = T->getDecl()->getASTContext();1649  IncludeStrongLifetimeRAII Strong(Policy);1650  T->getTemplateName(Ctx).print(OS, Policy);1651  if (Policy.PrintInjectedClassNameWithArguments) {1652    auto *Decl = T->getDecl();1653    // FIXME: Use T->getTemplateArgs(Ctx) when that supports as-written1654    // arguments.1655    if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Decl)) {1656      printTemplateArgumentList(OS, RD->getTemplateArgsAsWritten()->arguments(),1657                                Policy,1658                                T->getTemplateDecl()->getTemplateParameters());1659    } else {1660      ClassTemplateDecl *TD = Decl->getDescribedClassTemplate();1661      assert(TD);1662      printTemplateArgumentList(1663          OS, TD->getTemplateParameters()->getInjectedTemplateArgs(Ctx), Policy,1664          T->getTemplateDecl()->getTemplateParameters());1665    }1666  }1667  spaceBeforePlaceHolder(OS);1668}1669 1670void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,1671                                              raw_ostream &OS) {}1672 1673void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,1674                                              raw_ostream &OS) {1675  TemplateTypeParmDecl *D = T->getDecl();1676  if (D && D->isImplicit()) {1677    if (auto *TC = D->getTypeConstraint()) {1678      TC->print(OS, Policy);1679      OS << ' ';1680    }1681    OS << "auto";1682  } else if (IdentifierInfo *Id = T->getIdentifier())1683    OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()1684                                          : Id->getName());1685  else1686    OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();1687 1688  spaceBeforePlaceHolder(OS);1689}1690 1691void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,1692                                             raw_ostream &OS) {}1693 1694void TypePrinter::printSubstTemplateTypeParmBefore(1695                                             const SubstTemplateTypeParmType *T,1696                                             raw_ostream &OS) {1697  IncludeStrongLifetimeRAII Strong(Policy);1698  printBefore(T->getReplacementType(), OS);1699}1700 1701void TypePrinter::printSubstTemplateTypeParmAfter(1702                                             const SubstTemplateTypeParmType *T,1703                                             raw_ostream &OS) {1704  IncludeStrongLifetimeRAII Strong(Policy);1705  printAfter(T->getReplacementType(), OS);1706}1707 1708void TypePrinter::printSubstBuiltinTemplatePackBefore(1709    const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {1710  IncludeStrongLifetimeRAII Strong(Policy);1711  OS << "type-pack";1712}1713 1714void TypePrinter::printSubstBuiltinTemplatePackAfter(1715    const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {}1716 1717void TypePrinter::printSubstTemplateTypeParmPackBefore(1718                                        const SubstTemplateTypeParmPackType *T,1719                                        raw_ostream &OS) {1720  IncludeStrongLifetimeRAII Strong(Policy);1721  if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {1722    if (D && D->isImplicit()) {1723      if (auto *TC = D->getTypeConstraint()) {1724        TC->print(OS, Policy);1725        OS << ' ';1726      }1727      OS << "auto";1728    } else if (IdentifierInfo *Id = D->getIdentifier())1729      OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()1730                                            : Id->getName());1731    else1732      OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();1733 1734    spaceBeforePlaceHolder(OS);1735  }1736}1737 1738void TypePrinter::printSubstTemplateTypeParmPackAfter(1739                                        const SubstTemplateTypeParmPackType *T,1740                                        raw_ostream &OS) {1741  IncludeStrongLifetimeRAII Strong(Policy);1742}1743 1744void TypePrinter::printTemplateId(const TemplateSpecializationType *T,1745                                  raw_ostream &OS, bool FullyQualify) {1746  IncludeStrongLifetimeRAII Strong(Policy);1747 1748  if (ElaboratedTypeKeyword K = T->getKeyword();1749      K != ElaboratedTypeKeyword::None)1750    OS << TypeWithKeyword::getKeywordName(K) << ' ';1751 1752  TemplateDecl *TD =1753      T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true);1754  // FIXME: Null TD never exercised in test suite.1755  if (FullyQualify && TD) {1756    if (!Policy.SuppressScope)1757      TD->printNestedNameSpecifier(OS, Policy);1758 1759    OS << TD->getName();1760  } else {1761    T->getTemplateName().print(OS, Policy,1762                               !Policy.SuppressScope1763                                   ? TemplateName::Qualified::AsWritten1764                                   : TemplateName::Qualified::None);1765  }1766 1767  DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);1768  const TemplateParameterList *TPL = TD ? TD->getTemplateParameters() : nullptr;1769  printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);1770  spaceBeforePlaceHolder(OS);1771}1772 1773void TypePrinter::printTemplateSpecializationBefore(1774                                            const TemplateSpecializationType *T,1775                                            raw_ostream &OS) {1776  printTemplateId(T, OS, Policy.FullyQualifiedName);1777}1778 1779void TypePrinter::printTemplateSpecializationAfter(1780                                            const TemplateSpecializationType *T,1781                                            raw_ostream &OS) {}1782 1783void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {1784  if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {1785    printBefore(T->getInnerType(), OS);1786    OS << '(';1787  } else1788    printBefore(T->getInnerType(), OS);1789}1790 1791void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {1792  if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {1793    OS << ')';1794    printAfter(T->getInnerType(), OS);1795  } else1796    printAfter(T->getInnerType(), OS);1797}1798 1799void TypePrinter::printDependentNameBefore(const DependentNameType *T,1800                                           raw_ostream &OS) {1801  OS << TypeWithKeyword::getKeywordName(T->getKeyword());1802  if (T->getKeyword() != ElaboratedTypeKeyword::None)1803    OS << " ";1804  T->getQualifier().print(OS, Policy);1805  OS << T->getIdentifier()->getName();1806  spaceBeforePlaceHolder(OS);1807}1808 1809void TypePrinter::printDependentNameAfter(const DependentNameType *T,1810                                          raw_ostream &OS) {}1811 1812void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,1813                                           raw_ostream &OS) {1814  printBefore(T->getPattern(), OS);1815}1816 1817void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,1818                                          raw_ostream &OS) {1819  printAfter(T->getPattern(), OS);1820  OS << "...";1821}1822 1823static void printCountAttributedImpl(const CountAttributedType *T,1824                                     raw_ostream &OS,1825                                     const PrintingPolicy &Policy) {1826  OS << ' ';1827  if (T->isCountInBytes() && T->isOrNull())1828    OS << "__sized_by_or_null(";1829  else if (T->isCountInBytes())1830    OS << "__sized_by(";1831  else if (T->isOrNull())1832    OS << "__counted_by_or_null(";1833  else1834    OS << "__counted_by(";1835  if (T->getCountExpr())1836    T->getCountExpr()->printPretty(OS, nullptr, Policy);1837  OS << ')';1838}1839 1840void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,1841                                             raw_ostream &OS) {1842  printBefore(T->desugar(), OS);1843  if (!T->isArrayType())1844    printCountAttributedImpl(T, OS, Policy);1845}1846 1847void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,1848                                            raw_ostream &OS) {1849  printAfter(T->desugar(), OS);1850  if (T->isArrayType())1851    printCountAttributedImpl(T, OS, Policy);1852}1853 1854void TypePrinter::printAttributedBefore(const AttributedType *T,1855                                        raw_ostream &OS) {1856  // FIXME: Generate this with TableGen.1857 1858  // Prefer the macro forms of the GC and ownership qualifiers.1859  if (T->getAttrKind() == attr::ObjCGC ||1860      T->getAttrKind() == attr::ObjCOwnership)1861    return printBefore(T->getEquivalentType(), OS);1862 1863  if (T->getAttrKind() == attr::ObjCKindOf)1864    OS << "__kindof ";1865 1866  if (T->getAttrKind() == attr::PreserveNone) {1867    OS << "__attribute__((preserve_none)) ";1868    spaceBeforePlaceHolder(OS);1869  } else if (T->getAttrKind() == attr::PreserveMost) {1870    OS << "__attribute__((preserve_most)) ";1871    spaceBeforePlaceHolder(OS);1872  } else if (T->getAttrKind() == attr::PreserveAll) {1873    OS << "__attribute__((preserve_all)) ";1874    spaceBeforePlaceHolder(OS);1875  }1876 1877  if (T->getAttrKind() == attr::AddressSpace)1878    printBefore(T->getEquivalentType(), OS);1879  else1880    printBefore(T->getModifiedType(), OS);1881 1882  if (T->isMSTypeSpec()) {1883    switch (T->getAttrKind()) {1884    default: return;1885    case attr::Ptr32: OS << " __ptr32"; break;1886    case attr::Ptr64: OS << " __ptr64"; break;1887    case attr::SPtr: OS << " __sptr"; break;1888    case attr::UPtr: OS << " __uptr"; break;1889    }1890    spaceBeforePlaceHolder(OS);1891  }1892 1893  if (T->isWebAssemblyFuncrefSpec())1894    OS << "__funcref";1895 1896  // Print nullability type specifiers.1897  if (T->getImmediateNullability()) {1898    if (T->getAttrKind() == attr::TypeNonNull)1899      OS << " _Nonnull";1900    else if (T->getAttrKind() == attr::TypeNullable)1901      OS << " _Nullable";1902    else if (T->getAttrKind() == attr::TypeNullUnspecified)1903      OS << " _Null_unspecified";1904    else if (T->getAttrKind() == attr::TypeNullableResult)1905      OS << " _Nullable_result";1906    else1907      llvm_unreachable("unhandled nullability");1908    spaceBeforePlaceHolder(OS);1909  }1910}1911 1912void TypePrinter::printAttributedAfter(const AttributedType *T,1913                                       raw_ostream &OS) {1914  // FIXME: Generate this with TableGen.1915 1916  // Prefer the macro forms of the GC and ownership qualifiers.1917  if (T->getAttrKind() == attr::ObjCGC ||1918      T->getAttrKind() == attr::ObjCOwnership)1919    return printAfter(T->getEquivalentType(), OS);1920 1921  // If this is a calling convention attribute, don't print the implicit CC from1922  // the modified type.1923  SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());1924 1925  printAfter(T->getModifiedType(), OS);1926 1927  // Some attributes are printed as qualifiers before the type, so we have1928  // nothing left to do.1929  if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||1930      T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())1931    return;1932 1933  // Don't print the inert __unsafe_unretained attribute at all.1934  if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)1935    return;1936 1937  // Don't print ns_returns_retained unless it had an effect.1938  if (T->getAttrKind() == attr::NSReturnsRetained &&1939      !T->getEquivalentType()->castAs<FunctionType>()1940                             ->getExtInfo().getProducesResult())1941    return;1942 1943  if (T->getAttrKind() == attr::LifetimeBound) {1944    OS << " [[clang::lifetimebound]]";1945    return;1946  }1947  if (T->getAttrKind() == attr::LifetimeCaptureBy) {1948    OS << " [[clang::lifetime_capture_by(";1949    if (auto *attr = dyn_cast_or_null<LifetimeCaptureByAttr>(T->getAttr()))1950      llvm::interleaveComma(attr->getArgIdents(), OS,1951                            [&](auto it) { OS << it->getName(); });1952    OS << ")]]";1953    return;1954  }1955 1956  // The printing of the address_space attribute is handled by the qualifier1957  // since it is still stored in the qualifier. Return early to prevent printing1958  // this twice.1959  if (T->getAttrKind() == attr::AddressSpace)1960    return;1961 1962  if (T->getAttrKind() == attr::AnnotateType) {1963    // FIXME: Print the attribute arguments once we have a way to retrieve these1964    // here. For the meantime, we just print `[[clang::annotate_type(...)]]`1965    // without the arguments so that we know at least that we had _some_1966    // annotation on the type.1967    OS << " [[clang::annotate_type(...)]]";1968    return;1969  }1970 1971  if (T->getAttrKind() == attr::ArmStreaming) {1972    OS << "__arm_streaming";1973    return;1974  }1975  if (T->getAttrKind() == attr::ArmStreamingCompatible) {1976    OS << "__arm_streaming_compatible";1977    return;1978  }1979 1980  if (T->getAttrKind() == attr::SwiftAttr) {1981    if (auto *swiftAttr = dyn_cast_or_null<SwiftAttrAttr>(T->getAttr())) {1982      OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()1983         << "\")))";1984    }1985    return;1986  }1987 1988  if (T->getAttrKind() == attr::PreserveAll ||1989      T->getAttrKind() == attr::PreserveMost ||1990      T->getAttrKind() == attr::PreserveNone) {1991    // This has to be printed before the type.1992    return;1993  }1994 1995  OS << " __attribute__((";1996  switch (T->getAttrKind()) {1997#define TYPE_ATTR(NAME)1998#define DECL_OR_TYPE_ATTR(NAME)1999#define ATTR(NAME) case attr::NAME:2000#include "clang/Basic/AttrList.inc"2001    llvm_unreachable("non-type attribute attached to type");2002 2003  case attr::BTFTypeTag:2004    llvm_unreachable("BTFTypeTag attribute handled separately");2005 2006  case attr::HLSLResourceClass:2007  case attr::HLSLROV:2008  case attr::HLSLRawBuffer:2009  case attr::HLSLContainedType:2010  case attr::HLSLIsCounter:2011    llvm_unreachable("HLSL resource type attributes handled separately");2012 2013  case attr::OpenCLPrivateAddressSpace:2014  case attr::OpenCLGlobalAddressSpace:2015  case attr::OpenCLGlobalDeviceAddressSpace:2016  case attr::OpenCLGlobalHostAddressSpace:2017  case attr::OpenCLLocalAddressSpace:2018  case attr::OpenCLConstantAddressSpace:2019  case attr::OpenCLGenericAddressSpace:2020  case attr::HLSLGroupSharedAddressSpace:2021    // FIXME: Update printAttributedBefore to print these once we generate2022    // AttributedType nodes for them.2023    break;2024 2025  case attr::CountedBy:2026  case attr::CountedByOrNull:2027  case attr::SizedBy:2028  case attr::SizedByOrNull:2029  case attr::LifetimeBound:2030  case attr::LifetimeCaptureBy:2031  case attr::TypeNonNull:2032  case attr::TypeNullable:2033  case attr::TypeNullableResult:2034  case attr::TypeNullUnspecified:2035  case attr::ObjCGC:2036  case attr::ObjCInertUnsafeUnretained:2037  case attr::ObjCKindOf:2038  case attr::ObjCOwnership:2039  case attr::Ptr32:2040  case attr::Ptr64:2041  case attr::SPtr:2042  case attr::UPtr:2043  case attr::PointerAuth:2044  case attr::AddressSpace:2045  case attr::CmseNSCall:2046  case attr::AnnotateType:2047  case attr::WebAssemblyFuncref:2048  case attr::ArmAgnostic:2049  case attr::ArmStreaming:2050  case attr::ArmStreamingCompatible:2051  case attr::ArmIn:2052  case attr::ArmOut:2053  case attr::ArmInOut:2054  case attr::ArmPreserves:2055  case attr::NonBlocking:2056  case attr::NonAllocating:2057  case attr::Blocking:2058  case attr::Allocating:2059  case attr::SwiftAttr:2060  case attr::PreserveAll:2061  case attr::PreserveMost:2062  case attr::PreserveNone:2063    llvm_unreachable("This attribute should have been handled already");2064 2065  case attr::NSReturnsRetained:2066    OS << "ns_returns_retained";2067    break;2068 2069  // FIXME: When Sema learns to form this AttributedType, avoid printing the2070  // attribute again in printFunctionProtoAfter.2071  case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;2072  case attr::CDecl: OS << "cdecl"; break;2073  case attr::FastCall: OS << "fastcall"; break;2074  case attr::StdCall: OS << "stdcall"; break;2075  case attr::ThisCall: OS << "thiscall"; break;2076  case attr::SwiftCall: OS << "swiftcall"; break;2077  case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;2078  case attr::VectorCall: OS << "vectorcall"; break;2079  case attr::Pascal: OS << "pascal"; break;2080  case attr::MSABI: OS << "ms_abi"; break;2081  case attr::SysVABI: OS << "sysv_abi"; break;2082  case attr::RegCall: OS << "regcall"; break;2083  case attr::Pcs: {2084    OS << "pcs(";2085   QualType t = T->getEquivalentType();2086   while (!t->isFunctionType())2087     t = t->getPointeeType();2088   OS << (t->castAs<FunctionType>()->getCallConv() == CC_AAPCS ?2089         "\"aapcs\"" : "\"aapcs-vfp\"");2090   OS << ')';2091   break;2092  }2093  case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;2094  case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;2095  case attr::IntelOclBicc:2096    OS << "inteloclbicc";2097    break;2098  case attr::M68kRTD:2099    OS << "m68k_rtd";2100    break;2101  case attr::RISCVVectorCC:2102    OS << "riscv_vector_cc";2103    break;2104  case attr::RISCVVLSCC:2105    OS << "riscv_vls_cc";2106    break;2107  case attr::NoDeref:2108    OS << "noderef";2109    break;2110  case attr::CFIUncheckedCallee:2111    OS << "cfi_unchecked_callee";2112    break;2113  case attr::AcquireHandle:2114    OS << "acquire_handle";2115    break;2116  case attr::ArmMveStrictPolymorphism:2117    OS << "__clang_arm_mve_strict_polymorphism";2118    break;2119  case attr::ExtVectorType:2120    OS << "ext_vector_type";2121    break;2122  case attr::CFISalt:2123    OS << "cfi_salt(\"" << cast<CFISaltAttr>(T->getAttr())->getSalt() << "\")";2124    break;2125  }2126  OS << "))";2127}2128 2129void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,2130                                              raw_ostream &OS) {2131  printBefore(T->getWrappedType(), OS);2132  OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";2133}2134 2135void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,2136                                             raw_ostream &OS) {2137  printAfter(T->getWrappedType(), OS);2138}2139 2140void TypePrinter::printHLSLAttributedResourceBefore(2141    const HLSLAttributedResourceType *T, raw_ostream &OS) {2142  printBefore(T->getWrappedType(), OS);2143}2144 2145void TypePrinter::printHLSLAttributedResourceAfter(2146    const HLSLAttributedResourceType *T, raw_ostream &OS) {2147  printAfter(T->getWrappedType(), OS);2148  const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();2149  OS << " [[hlsl::resource_class("2150     << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)2151     << ")]]";2152  if (Attrs.IsROV)2153    OS << " [[hlsl::is_rov]]";2154  if (Attrs.RawBuffer)2155    OS << " [[hlsl::raw_buffer]]";2156  if (Attrs.IsCounter)2157    OS << " [[hlsl::is_counter]]";2158 2159  QualType ContainedTy = T->getContainedType();2160  if (!ContainedTy.isNull()) {2161    OS << " [[hlsl::contained_type(";2162    printBefore(ContainedTy, OS);2163    printAfter(ContainedTy, OS);2164    OS << ")]]";2165  }2166}2167 2168void TypePrinter::printHLSLInlineSpirvBefore(const HLSLInlineSpirvType *T,2169                                             raw_ostream &OS) {2170  OS << "__hlsl_spirv_type<" << T->getOpcode();2171 2172  OS << ", " << T->getSize();2173  OS << ", " << T->getAlignment();2174 2175  for (auto &Operand : T->getOperands()) {2176    using SpirvOperandKind = SpirvOperand::SpirvOperandKind;2177 2178    OS << ", ";2179    switch (Operand.getKind()) {2180    case SpirvOperandKind::ConstantId: {2181      QualType ConstantType = Operand.getResultType();2182      OS << "vk::integral_constant<";2183      printBefore(ConstantType, OS);2184      printAfter(ConstantType, OS);2185      OS << ", ";2186      OS << Operand.getValue();2187      OS << ">";2188      break;2189    }2190    case SpirvOperandKind::Literal:2191      OS << "vk::Literal<vk::integral_constant<uint, ";2192      OS << Operand.getValue();2193      OS << ">>";2194      break;2195    case SpirvOperandKind::TypeId: {2196      QualType Type = Operand.getResultType();2197      printBefore(Type, OS);2198      printAfter(Type, OS);2199      break;2200    }2201    default:2202      llvm_unreachable("Invalid SpirvOperand kind!");2203      break;2204    }2205  }2206 2207  OS << ">";2208}2209 2210void TypePrinter::printHLSLInlineSpirvAfter(const HLSLInlineSpirvType *T,2211                                            raw_ostream &OS) {2212  // nothing to do2213}2214 2215void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,2216                                           raw_ostream &OS) {2217  OS << T->getDecl()->getName();2218  spaceBeforePlaceHolder(OS);2219}2220 2221void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,2222                                          raw_ostream &OS) {}2223 2224void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,2225                                          raw_ostream &OS) {2226  OS << T->getDecl()->getName();2227  if (!T->qual_empty()) {2228    bool isFirst = true;2229    OS << '<';2230    for (const auto *I : T->quals()) {2231      if (isFirst)2232        isFirst = false;2233      else2234        OS << ',';2235      OS << I->getName();2236    }2237    OS << '>';2238  }2239 2240  spaceBeforePlaceHolder(OS);2241}2242 2243void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,2244                                          raw_ostream &OS) {}2245 2246void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,2247                                        raw_ostream &OS) {2248  if (T->qual_empty() && T->isUnspecializedAsWritten() &&2249      !T->isKindOfTypeAsWritten())2250    return printBefore(T->getBaseType(), OS);2251 2252  if (T->isKindOfTypeAsWritten())2253    OS << "__kindof ";2254 2255  print(T->getBaseType(), OS, StringRef());2256 2257  if (T->isSpecializedAsWritten()) {2258    bool isFirst = true;2259    OS << '<';2260    for (auto typeArg : T->getTypeArgsAsWritten()) {2261      if (isFirst)2262        isFirst = false;2263      else2264        OS << ",";2265 2266      print(typeArg, OS, StringRef());2267    }2268    OS << '>';2269  }2270 2271  if (!T->qual_empty()) {2272    bool isFirst = true;2273    OS << '<';2274    for (const auto *I : T->quals()) {2275      if (isFirst)2276        isFirst = false;2277      else2278        OS << ',';2279      OS << I->getName();2280    }2281    OS << '>';2282  }2283 2284  spaceBeforePlaceHolder(OS);2285}2286 2287void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,2288                                        raw_ostream &OS) {2289  if (T->qual_empty() && T->isUnspecializedAsWritten() &&2290      !T->isKindOfTypeAsWritten())2291    return printAfter(T->getBaseType(), OS);2292}2293 2294void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,2295                                               raw_ostream &OS) {2296  printBefore(T->getPointeeType(), OS);2297 2298  // If we need to print the pointer, print it now.2299  if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&2300      !T->isObjCClassType() && !T->isObjCQualifiedClassType()) {2301    if (HasEmptyPlaceHolder)2302      OS << ' ';2303    OS << '*';2304  }2305}2306 2307void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,2308                                              raw_ostream &OS) {}2309 2310static2311const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }2312 2313static const TemplateArgument &getArgument(const TemplateArgumentLoc &A) {2314  return A.getArgument();2315}2316 2317static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP,2318                          llvm::raw_ostream &OS, bool IncludeType) {2319  A.print(PP, OS, IncludeType);2320}2321 2322static void printArgument(const TemplateArgumentLoc &A,2323                          const PrintingPolicy &PP, llvm::raw_ostream &OS,2324                          bool IncludeType) {2325  const TemplateArgument::ArgKind &Kind = A.getArgument().getKind();2326  if (Kind == TemplateArgument::ArgKind::Type)2327    return A.getTypeSourceInfo()->getType().print(OS, PP);2328  return A.getArgument().print(PP, OS, IncludeType);2329}2330 2331static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,2332                                          TemplateArgument Pattern,2333                                          ArrayRef<TemplateArgument> Args,2334                                          unsigned Depth);2335 2336static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern,2337                              ArrayRef<TemplateArgument> Args, unsigned Depth) {2338  if (Ctx.hasSameType(T, Pattern))2339    return true;2340 2341  // A type parameter matches its argument.2342  if (auto *TTPT = Pattern->getAsCanonical<TemplateTypeParmType>()) {2343    if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&2344        Args[TTPT->getIndex()].getKind() == TemplateArgument::Type) {2345      QualType SubstArg = Ctx.getQualifiedType(2346          Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());2347      return Ctx.hasSameType(SubstArg, T);2348    }2349    return false;2350  }2351 2352  // FIXME: Recurse into array types.2353 2354  // All other cases will need the types to be identically qualified.2355  Qualifiers TQual, PatQual;2356  T = Ctx.getUnqualifiedArrayType(T, TQual);2357  Pattern = Ctx.getUnqualifiedArrayType(Pattern, PatQual);2358  if (TQual != PatQual)2359    return false;2360 2361  // Recurse into pointer-like types.2362  {2363    QualType TPointee = T->getPointeeType();2364    QualType PPointee = Pattern->getPointeeType();2365    if (!TPointee.isNull() && !PPointee.isNull())2366      return T->getTypeClass() == Pattern->getTypeClass() &&2367             isSubstitutedType(Ctx, TPointee, PPointee, Args, Depth);2368  }2369 2370  // Recurse into template specialization types.2371  if (auto *PTST =2372          Pattern.getCanonicalType()->getAs<TemplateSpecializationType>()) {2373    TemplateName Template;2374    ArrayRef<TemplateArgument> TemplateArgs;2375    if (auto *TTST = T->getAs<TemplateSpecializationType>()) {2376      Template = TTST->getTemplateName();2377      TemplateArgs = TTST->template_arguments();2378    } else if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(2379                   T->getAsCXXRecordDecl())) {2380      Template = TemplateName(CTSD->getSpecializedTemplate());2381      TemplateArgs = CTSD->getTemplateArgs().asArray();2382    } else {2383      return false;2384    }2385 2386    if (!isSubstitutedTemplateArgument(Ctx, Template, PTST->getTemplateName(),2387                                       Args, Depth))2388      return false;2389    if (TemplateArgs.size() != PTST->template_arguments().size())2390      return false;2391    for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)2392      if (!isSubstitutedTemplateArgument(2393              Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))2394        return false;2395    return true;2396  }2397 2398  // FIXME: Handle more cases.2399  return false;2400}2401 2402/// Evaluates the expression template argument 'Pattern' and returns true2403/// if 'Arg' evaluates to the same result.2404static bool templateArgumentExpressionsEqual(ASTContext const &Ctx,2405                                             TemplateArgument const &Pattern,2406                                             TemplateArgument const &Arg) {2407  if (Pattern.getKind() != TemplateArgument::Expression)2408    return false;2409 2410  // Can't evaluate value-dependent expressions so bail early2411  Expr const *pattern_expr = Pattern.getAsExpr();2412  if (pattern_expr->isValueDependent() ||2413      !pattern_expr->isIntegerConstantExpr(Ctx))2414    return false;2415 2416  if (Arg.getKind() == TemplateArgument::Integral)2417    return llvm::APSInt::isSameValue(pattern_expr->EvaluateKnownConstInt(Ctx),2418                                     Arg.getAsIntegral());2419 2420  if (Arg.getKind() == TemplateArgument::Expression) {2421    Expr const *args_expr = Arg.getAsExpr();2422    if (args_expr->isValueDependent() || !args_expr->isIntegerConstantExpr(Ctx))2423      return false;2424 2425    return llvm::APSInt::isSameValue(args_expr->EvaluateKnownConstInt(Ctx),2426                                     pattern_expr->EvaluateKnownConstInt(Ctx));2427  }2428 2429  return false;2430}2431 2432static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,2433                                          TemplateArgument Pattern,2434                                          ArrayRef<TemplateArgument> Args,2435                                          unsigned Depth) {2436  Arg = Ctx.getCanonicalTemplateArgument(Arg);2437  Pattern = Ctx.getCanonicalTemplateArgument(Pattern);2438  if (Arg.structurallyEquals(Pattern))2439    return true;2440 2441  if (Pattern.getKind() == TemplateArgument::Expression) {2442    if (auto *DRE =2443            dyn_cast<DeclRefExpr>(Pattern.getAsExpr()->IgnoreParenImpCasts())) {2444      if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl()))2445        return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&2446               Args[NTTP->getIndex()].structurallyEquals(Arg);2447    }2448  }2449 2450  if (templateArgumentExpressionsEqual(Ctx, Pattern, Arg))2451    return true;2452 2453  if (Arg.getKind() != Pattern.getKind())2454    return false;2455 2456  if (Arg.getKind() == TemplateArgument::Type)2457    return isSubstitutedType(Ctx, Arg.getAsType(), Pattern.getAsType(), Args,2458                             Depth);2459 2460  if (Arg.getKind() == TemplateArgument::Template) {2461    TemplateDecl *PatTD = Pattern.getAsTemplate().getAsTemplateDecl();2462    if (auto *TTPD = dyn_cast_or_null<TemplateTemplateParmDecl>(PatTD))2463      return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&2464             Ctx.getCanonicalTemplateArgument(Args[TTPD->getIndex()])2465                 .structurallyEquals(Arg);2466  }2467 2468  // FIXME: Handle more cases.2469  return false;2470}2471 2472bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,2473                                         const NamedDecl *Param,2474                                         ArrayRef<TemplateArgument> Args,2475                                         unsigned Depth) {2476  // An empty pack is equivalent to not providing a pack argument.2477  if (Arg.getKind() == TemplateArgument::Pack && Arg.pack_size() == 0)2478    return true;2479 2480  if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Param)) {2481    return TTPD->hasDefaultArgument() &&2482           isSubstitutedTemplateArgument(2483               Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);2484  } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {2485    return TTPD->hasDefaultArgument() &&2486           isSubstitutedTemplateArgument(2487               Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);2488  } else if (auto *NTTPD = dyn_cast<NonTypeTemplateParmDecl>(Param)) {2489    return NTTPD->hasDefaultArgument() &&2490           isSubstitutedTemplateArgument(2491               Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,2492               Depth);2493  }2494  return false;2495}2496 2497template <typename TA>2498static void2499printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy,2500        const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex) {2501  // Drop trailing template arguments that match default arguments.2502  if (TPL && Policy.SuppressDefaultTemplateArgs && !Policy.PrintAsCanonical &&2503      !Args.empty() && !IsPack && Args.size() <= TPL->size()) {2504    llvm::SmallVector<TemplateArgument, 8> OrigArgs;2505    for (const TA &A : Args)2506      OrigArgs.push_back(getArgument(A));2507    while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())2508      Args = Args.drop_back();2509  }2510 2511  const char *Comma = Policy.MSVCFormatting ? "," : ", ";2512  if (!IsPack)2513    OS << '<';2514 2515  bool NeedSpace = false;2516  bool FirstArg = true;2517  for (const auto &Arg : Args) {2518    // Print the argument into a string.2519    SmallString<128> Buf;2520    llvm::raw_svector_ostream ArgOS(Buf);2521    const TemplateArgument &Argument = getArgument(Arg);2522    if (Argument.getKind() == TemplateArgument::Pack) {2523      if (Argument.pack_size() && !FirstArg)2524        OS << Comma;2525      printTo(ArgOS, Argument.getPackAsArray(), Policy, TPL,2526              /*IsPack*/ true, ParmIndex);2527    } else {2528      if (!FirstArg)2529        OS << Comma;2530      // Tries to print the argument with location info if exists.2531      printArgument(Arg, Policy, ArgOS,2532                    TemplateParameterList::shouldIncludeTypeForArgument(2533                        Policy, TPL, ParmIndex));2534    }2535    StringRef ArgString = ArgOS.str();2536 2537    // If this is the first argument and its string representation2538    // begins with the global scope specifier ('::foo'), add a space2539    // to avoid printing the diagraph '<:'.2540    if (FirstArg && ArgString.starts_with(":"))2541      OS << ' ';2542 2543    OS << ArgString;2544 2545    // If the last character of our string is '>', add another space to2546    // keep the two '>''s separate tokens.2547    if (!ArgString.empty()) {2548      NeedSpace = Policy.SplitTemplateClosers && ArgString.back() == '>';2549      FirstArg = false;2550    }2551 2552    // Use same template parameter for all elements of Pack2553    if (!IsPack)2554      ParmIndex++;2555  }2556 2557  if (!IsPack) {2558    if (NeedSpace)2559      OS << ' ';2560    OS << '>';2561  }2562}2563 2564void clang::printTemplateArgumentList(raw_ostream &OS,2565                                      const TemplateArgumentListInfo &Args,2566                                      const PrintingPolicy &Policy,2567                                      const TemplateParameterList *TPL) {2568  printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);2569}2570 2571void clang::printTemplateArgumentList(raw_ostream &OS,2572                                      ArrayRef<TemplateArgument> Args,2573                                      const PrintingPolicy &Policy,2574                                      const TemplateParameterList *TPL) {2575  PrintingPolicy InnerPolicy = Policy;2576  InnerPolicy.SuppressScope = false;2577  printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);2578}2579 2580void clang::printTemplateArgumentList(raw_ostream &OS,2581                                      ArrayRef<TemplateArgumentLoc> Args,2582                                      const PrintingPolicy &Policy,2583                                      const TemplateParameterList *TPL) {2584  PrintingPolicy InnerPolicy = Policy;2585  InnerPolicy.SuppressScope = false;2586  printTo(OS, Args, InnerPolicy, TPL, /*isPack*/ false, /*parmIndex*/ 0);2587}2588 2589std::string PointerAuthQualifier::getAsString() const {2590  LangOptions LO;2591  return getAsString(PrintingPolicy(LO));2592}2593 2594std::string PointerAuthQualifier::getAsString(const PrintingPolicy &P) const {2595  SmallString<64> Buf;2596  llvm::raw_svector_ostream StrOS(Buf);2597  print(StrOS, P);2598  return StrOS.str().str();2599}2600 2601bool PointerAuthQualifier::isEmptyWhenPrinted(const PrintingPolicy &P) const {2602  return !isPresent();2603}2604 2605void PointerAuthQualifier::print(raw_ostream &OS,2606                                 const PrintingPolicy &P) const {2607  if (!isPresent())2608    return;2609 2610  OS << "__ptrauth(";2611  OS << getKey();2612  OS << "," << unsigned(isAddressDiscriminated()) << ","2613     << getExtraDiscriminator() << ")";2614}2615 2616std::string Qualifiers::getAsString() const {2617  LangOptions LO;2618  return getAsString(PrintingPolicy(LO));2619}2620 2621// Appends qualifiers to the given string, separated by spaces.  Will2622// prefix a space if the string is non-empty.  Will not append a final2623// space.2624std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const {2625  SmallString<64> Buf;2626  llvm::raw_svector_ostream StrOS(Buf);2627  print(StrOS, Policy);2628  return std::string(StrOS.str());2629}2630 2631bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const {2632  if (getCVRQualifiers())2633    return false;2634 2635  if (getAddressSpace() != LangAS::Default)2636    return false;2637 2638  if (getObjCGCAttr())2639    return false;2640 2641  if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime())2642    if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime))2643      return false;2644 2645  if (PointerAuthQualifier PointerAuth = getPointerAuth();2646      PointerAuth && !PointerAuth.isEmptyWhenPrinted(Policy))2647    return false;2648 2649  return true;2650}2651 2652std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {2653  switch (AS) {2654  case LangAS::Default:2655    return "";2656  case LangAS::opencl_global:2657  case LangAS::sycl_global:2658    return "__global";2659  case LangAS::opencl_local:2660  case LangAS::sycl_local:2661    return "__local";2662  case LangAS::opencl_private:2663  case LangAS::sycl_private:2664    return "__private";2665  case LangAS::opencl_constant:2666    return "__constant";2667  case LangAS::opencl_generic:2668    return "__generic";2669  case LangAS::opencl_global_device:2670  case LangAS::sycl_global_device:2671    return "__global_device";2672  case LangAS::opencl_global_host:2673  case LangAS::sycl_global_host:2674    return "__global_host";2675  case LangAS::cuda_device:2676    return "__device__";2677  case LangAS::cuda_constant:2678    return "__constant__";2679  case LangAS::cuda_shared:2680    return "__shared__";2681  case LangAS::ptr32_sptr:2682    return "__sptr __ptr32";2683  case LangAS::ptr32_uptr:2684    return "__uptr __ptr32";2685  case LangAS::ptr64:2686    return "__ptr64";2687  case LangAS::hlsl_groupshared:2688    return "groupshared";2689  case LangAS::hlsl_constant:2690    return "hlsl_constant";2691  case LangAS::hlsl_private:2692    return "hlsl_private";2693  case LangAS::hlsl_device:2694    return "hlsl_device";2695  case LangAS::hlsl_input:2696    return "hlsl_input";2697  case LangAS::wasm_funcref:2698    return "__funcref";2699  default:2700    return std::to_string(toTargetAddressSpace(AS));2701  }2702}2703 2704// Appends qualifiers to the given string, separated by spaces.  Will2705// prefix a space if the string is non-empty.  Will not append a final2706// space.2707void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,2708                       bool appendSpaceIfNonEmpty) const {2709  bool addSpace = false;2710 2711  unsigned quals = getCVRQualifiers();2712  if (quals) {2713    AppendTypeQualList(OS, quals, Policy.Restrict);2714    addSpace = true;2715  }2716  if (hasUnaligned()) {2717    if (addSpace)2718      OS << ' ';2719    OS << "__unaligned";2720    addSpace = true;2721  }2722  auto ASStr = getAddrSpaceAsString(getAddressSpace());2723  if (!ASStr.empty()) {2724    if (addSpace)2725      OS << ' ';2726    addSpace = true;2727    // Wrap target address space into an attribute syntax2728    if (isTargetAddressSpace(getAddressSpace()))2729      OS << "__attribute__((address_space(" << ASStr << ")))";2730    else2731      OS << ASStr;2732  }2733 2734  if (Qualifiers::GC gc = getObjCGCAttr()) {2735    if (addSpace)2736      OS << ' ';2737    addSpace = true;2738    if (gc == Qualifiers::Weak)2739      OS << "__weak";2740    else2741      OS << "__strong";2742  }2743  if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) {2744    if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){2745      if (addSpace)2746        OS << ' ';2747      addSpace = true;2748    }2749 2750    switch (lifetime) {2751    case Qualifiers::OCL_None: llvm_unreachable("none but true");2752    case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break;2753    case Qualifiers::OCL_Strong:2754      if (!Policy.SuppressStrongLifetime)2755        OS << "__strong";2756      break;2757 2758    case Qualifiers::OCL_Weak: OS << "__weak"; break;2759    case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break;2760    }2761  }2762 2763  if (PointerAuthQualifier PointerAuth = getPointerAuth()) {2764    if (addSpace)2765      OS << ' ';2766    addSpace = true;2767 2768    PointerAuth.print(OS, Policy);2769  }2770 2771  if (appendSpaceIfNonEmpty && addSpace)2772    OS << ' ';2773}2774 2775std::string QualType::getAsString() const {2776  return getAsString(split(), LangOptions());2777}2778 2779std::string QualType::getAsString(const PrintingPolicy &Policy) const {2780  std::string S;2781  getAsStringInternal(S, Policy);2782  return S;2783}2784 2785std::string QualType::getAsString(const Type *ty, Qualifiers qs,2786                                  const PrintingPolicy &Policy) {2787  std::string buffer;2788  getAsStringInternal(ty, qs, buffer, Policy);2789  return buffer;2790}2791 2792void QualType::print(raw_ostream &OS, const PrintingPolicy &Policy,2793                     const Twine &PlaceHolder, unsigned Indentation) const {2794  print(splitAccordingToPolicy(*this, Policy), OS, Policy, PlaceHolder,2795        Indentation);2796}2797 2798void QualType::print(const Type *ty, Qualifiers qs,2799                     raw_ostream &OS, const PrintingPolicy &policy,2800                     const Twine &PlaceHolder, unsigned Indentation) {2801  SmallString<128> PHBuf;2802  StringRef PH = PlaceHolder.toStringRef(PHBuf);2803 2804  TypePrinter(policy, Indentation).print(ty, qs, OS, PH);2805}2806 2807void QualType::getAsStringInternal(std::string &Str,2808                                   const PrintingPolicy &Policy) const {2809  return getAsStringInternal(splitAccordingToPolicy(*this, Policy), Str,2810                             Policy);2811}2812 2813void QualType::getAsStringInternal(const Type *ty, Qualifiers qs,2814                                   std::string &buffer,2815                                   const PrintingPolicy &policy) {2816  SmallString<256> Buf;2817  llvm::raw_svector_ostream StrOS(Buf);2818  TypePrinter(policy).print(ty, qs, StrOS, buffer);2819  std::string str = std::string(StrOS.str());2820  buffer.swap(str);2821}2822 2823raw_ostream &clang::operator<<(raw_ostream &OS, QualType QT) {2824  SplitQualType S = QT.split();2825  TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, /*PlaceHolder=*/"");2826  return OS;2827}2828