TypePrinter.cpp revision 35178dc09d97bb2e0612813def09833866e3ad82
1//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This contains code to print types from Clang's type system. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/AST/PrettyPrinter.h" 15#include "clang/AST/ASTContext.h" 16#include "clang/AST/Decl.h" 17#include "clang/AST/DeclObjC.h" 18#include "clang/AST/DeclTemplate.h" 19#include "clang/AST/Expr.h" 20#include "clang/AST/Type.h" 21#include "clang/Basic/LangOptions.h" 22#include "clang/Basic/SourceManager.h" 23#include "llvm/ADT/SmallString.h" 24#include "llvm/ADT/StringExtras.h" 25#include "llvm/Support/SaveAndRestore.h" 26#include "llvm/Support/raw_ostream.h" 27using namespace clang; 28 29namespace { 30 /// \brief RAII object that enables printing of the ARC __strong lifetime 31 /// qualifier. 32 class IncludeStrongLifetimeRAII { 33 PrintingPolicy &Policy; 34 bool Old; 35 36 public: 37 explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy) 38 : Policy(Policy), Old(Policy.SuppressStrongLifetime) { 39 Policy.SuppressStrongLifetime = false; 40 } 41 42 ~IncludeStrongLifetimeRAII() { 43 Policy.SuppressStrongLifetime = Old; 44 } 45 }; 46 47 class ParamPolicyRAII { 48 PrintingPolicy &Policy; 49 bool Old; 50 51 public: 52 explicit ParamPolicyRAII(PrintingPolicy &Policy) 53 : Policy(Policy), Old(Policy.SuppressSpecifiers) { 54 Policy.SuppressSpecifiers = false; 55 } 56 57 ~ParamPolicyRAII() { 58 Policy.SuppressSpecifiers = Old; 59 } 60 }; 61 62 class ElaboratedTypePolicyRAII { 63 PrintingPolicy &Policy; 64 bool SuppressTagKeyword; 65 bool SuppressScope; 66 67 public: 68 explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) { 69 SuppressTagKeyword = Policy.SuppressTagKeyword; 70 SuppressScope = Policy.SuppressScope; 71 Policy.SuppressTagKeyword = true; 72 Policy.SuppressScope = true; 73 } 74 75 ~ElaboratedTypePolicyRAII() { 76 Policy.SuppressTagKeyword = SuppressTagKeyword; 77 Policy.SuppressScope = SuppressScope; 78 } 79 }; 80 81 class TypePrinter { 82 PrintingPolicy Policy; 83 bool HasEmptyPlaceHolder; 84 85 public: 86 explicit TypePrinter(const PrintingPolicy &Policy) 87 : Policy(Policy), HasEmptyPlaceHolder(false) { } 88 89 void print(const Type *ty, Qualifiers qs, raw_ostream &OS, 90 StringRef PlaceHolder); 91 void print(QualType T, raw_ostream &OS, StringRef PlaceHolder); 92 93 static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier); 94 void spaceBeforePlaceHolder(raw_ostream &OS); 95 void printTypeSpec(const NamedDecl *D, raw_ostream &OS); 96 97 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS); 98 void printBefore(QualType T, raw_ostream &OS); 99 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS); 100 void printAfter(QualType T, raw_ostream &OS); 101 void AppendScope(DeclContext *DC, raw_ostream &OS); 102 void printTag(TagDecl *T, raw_ostream &OS); 103#define ABSTRACT_TYPE(CLASS, PARENT) 104#define TYPE(CLASS, PARENT) \ 105 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \ 106 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS); 107#include "clang/AST/TypeNodes.def" 108 }; 109} 110 111static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals) { 112 bool appendSpace = false; 113 if (TypeQuals & Qualifiers::Const) { 114 OS << "const"; 115 appendSpace = true; 116 } 117 if (TypeQuals & Qualifiers::Volatile) { 118 if (appendSpace) OS << ' '; 119 OS << "volatile"; 120 appendSpace = true; 121 } 122 if (TypeQuals & Qualifiers::Restrict) { 123 if (appendSpace) OS << ' '; 124 OS << "restrict"; 125 } 126} 127 128void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) { 129 if (!HasEmptyPlaceHolder) 130 OS << ' '; 131} 132 133void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) { 134 SplitQualType split = t.split(); 135 print(split.Ty, split.Quals, OS, PlaceHolder); 136} 137 138void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS, 139 StringRef PlaceHolder) { 140 if (!T) { 141 OS << "NULL TYPE"; 142 return; 143 } 144 145 SaveAndRestore<bool> PHVal(HasEmptyPlaceHolder, PlaceHolder.empty()); 146 147 printBefore(T, Quals, OS); 148 OS << PlaceHolder; 149 printAfter(T, Quals, OS); 150} 151 152bool TypePrinter::canPrefixQualifiers(const Type *T, 153 bool &NeedARCStrongQualifier) { 154 // CanPrefixQualifiers - We prefer to print type qualifiers before the type, 155 // so that we get "const int" instead of "int const", but we can't do this if 156 // the type is complex. For example if the type is "int*", we *must* print 157 // "int * const", printing "const int *" is different. Only do this when the 158 // type expands to a simple string. 159 bool CanPrefixQualifiers = false; 160 NeedARCStrongQualifier = false; 161 Type::TypeClass TC = T->getTypeClass(); 162 if (const AutoType *AT = dyn_cast<AutoType>(T)) 163 TC = AT->desugar()->getTypeClass(); 164 if (const SubstTemplateTypeParmType *Subst 165 = dyn_cast<SubstTemplateTypeParmType>(T)) 166 TC = Subst->getReplacementType()->getTypeClass(); 167 168 switch (TC) { 169 case Type::Builtin: 170 case Type::Complex: 171 case Type::UnresolvedUsing: 172 case Type::Typedef: 173 case Type::TypeOfExpr: 174 case Type::TypeOf: 175 case Type::Decltype: 176 case Type::UnaryTransform: 177 case Type::Record: 178 case Type::Enum: 179 case Type::Elaborated: 180 case Type::TemplateTypeParm: 181 case Type::SubstTemplateTypeParmPack: 182 case Type::TemplateSpecialization: 183 case Type::InjectedClassName: 184 case Type::DependentName: 185 case Type::DependentTemplateSpecialization: 186 case Type::ObjCObject: 187 case Type::ObjCInterface: 188 case Type::Atomic: 189 CanPrefixQualifiers = true; 190 break; 191 192 case Type::ObjCObjectPointer: 193 CanPrefixQualifiers = T->isObjCIdType() || T->isObjCClassType() || 194 T->isObjCQualifiedIdType() || T->isObjCQualifiedClassType(); 195 break; 196 197 case Type::ConstantArray: 198 case Type::IncompleteArray: 199 case Type::VariableArray: 200 case Type::DependentSizedArray: 201 NeedARCStrongQualifier = true; 202 // Fall through 203 204 case Type::Pointer: 205 case Type::BlockPointer: 206 case Type::LValueReference: 207 case Type::RValueReference: 208 case Type::MemberPointer: 209 case Type::DependentSizedExtVector: 210 case Type::Vector: 211 case Type::ExtVector: 212 case Type::FunctionProto: 213 case Type::FunctionNoProto: 214 case Type::Paren: 215 case Type::Attributed: 216 case Type::PackExpansion: 217 case Type::SubstTemplateTypeParm: 218 case Type::Auto: 219 CanPrefixQualifiers = false; 220 break; 221 } 222 223 return CanPrefixQualifiers; 224} 225 226void TypePrinter::printBefore(QualType T, raw_ostream &OS) { 227 SplitQualType Split = T.split(); 228 229 // If we have cv1 T, where T is substituted for cv2 U, only print cv1 - cv2 230 // at this level. 231 Qualifiers Quals = Split.Quals; 232 if (const SubstTemplateTypeParmType *Subst = 233 dyn_cast<SubstTemplateTypeParmType>(Split.Ty)) 234 Quals -= QualType(Subst, 0).getQualifiers(); 235 236 printBefore(Split.Ty, Quals, OS); 237} 238 239/// \brief Prints the part of the type string before an identifier, e.g. for 240/// "int foo[10]" it prints "int ". 241void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) { 242 if (Policy.SuppressSpecifiers && T->isSpecifierType()) 243 return; 244 245 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder); 246 247 // Print qualifiers as appropriate. 248 249 bool CanPrefixQualifiers = false; 250 bool NeedARCStrongQualifier = false; 251 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier); 252 253 if (CanPrefixQualifiers && !Quals.empty()) { 254 if (NeedARCStrongQualifier) { 255 IncludeStrongLifetimeRAII Strong(Policy); 256 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true); 257 } else { 258 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true); 259 } 260 } 261 262 bool hasAfterQuals = false; 263 if (!CanPrefixQualifiers && !Quals.empty()) { 264 hasAfterQuals = !Quals.isEmptyWhenPrinted(Policy); 265 if (hasAfterQuals) 266 HasEmptyPlaceHolder = false; 267 } 268 269 switch (T->getTypeClass()) { 270#define ABSTRACT_TYPE(CLASS, PARENT) 271#define TYPE(CLASS, PARENT) case Type::CLASS: \ 272 print##CLASS##Before(cast<CLASS##Type>(T), OS); \ 273 break; 274#include "clang/AST/TypeNodes.def" 275 } 276 277 if (hasAfterQuals) { 278 if (NeedARCStrongQualifier) { 279 IncludeStrongLifetimeRAII Strong(Policy); 280 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get()); 281 } else { 282 Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/!PrevPHIsEmpty.get()); 283 } 284 } 285} 286 287void TypePrinter::printAfter(QualType t, raw_ostream &OS) { 288 SplitQualType split = t.split(); 289 printAfter(split.Ty, split.Quals, OS); 290} 291 292/// \brief Prints the part of the type string after an identifier, e.g. for 293/// "int foo[10]" it prints "[10]". 294void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) { 295 switch (T->getTypeClass()) { 296#define ABSTRACT_TYPE(CLASS, PARENT) 297#define TYPE(CLASS, PARENT) case Type::CLASS: \ 298 print##CLASS##After(cast<CLASS##Type>(T), OS); \ 299 break; 300#include "clang/AST/TypeNodes.def" 301 } 302} 303 304void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) { 305 OS << T->getName(Policy); 306 spaceBeforePlaceHolder(OS); 307} 308void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) { } 309 310void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) { 311 OS << "_Complex "; 312 printBefore(T->getElementType(), OS); 313} 314void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) { 315 printAfter(T->getElementType(), OS); 316} 317 318void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) { 319 IncludeStrongLifetimeRAII Strong(Policy); 320 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 321 printBefore(T->getPointeeType(), OS); 322 // Handle things like 'int (*A)[4];' correctly. 323 // FIXME: this should include vectors, but vectors use attributes I guess. 324 if (isa<ArrayType>(T->getPointeeType())) 325 OS << '('; 326 OS << '*'; 327} 328void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) { 329 IncludeStrongLifetimeRAII Strong(Policy); 330 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 331 // Handle things like 'int (*A)[4];' correctly. 332 // FIXME: this should include vectors, but vectors use attributes I guess. 333 if (isa<ArrayType>(T->getPointeeType())) 334 OS << ')'; 335 printAfter(T->getPointeeType(), OS); 336} 337 338void TypePrinter::printBlockPointerBefore(const BlockPointerType *T, 339 raw_ostream &OS) { 340 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 341 printBefore(T->getPointeeType(), OS); 342 OS << '^'; 343} 344void TypePrinter::printBlockPointerAfter(const BlockPointerType *T, 345 raw_ostream &OS) { 346 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 347 printAfter(T->getPointeeType(), OS); 348} 349 350void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T, 351 raw_ostream &OS) { 352 IncludeStrongLifetimeRAII Strong(Policy); 353 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 354 printBefore(T->getPointeeTypeAsWritten(), OS); 355 // Handle things like 'int (&A)[4];' correctly. 356 // FIXME: this should include vectors, but vectors use attributes I guess. 357 if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 358 OS << '('; 359 OS << '&'; 360} 361void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T, 362 raw_ostream &OS) { 363 IncludeStrongLifetimeRAII Strong(Policy); 364 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 365 // Handle things like 'int (&A)[4];' correctly. 366 // FIXME: this should include vectors, but vectors use attributes I guess. 367 if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 368 OS << ')'; 369 printAfter(T->getPointeeTypeAsWritten(), OS); 370} 371 372void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T, 373 raw_ostream &OS) { 374 IncludeStrongLifetimeRAII Strong(Policy); 375 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 376 printBefore(T->getPointeeTypeAsWritten(), OS); 377 // Handle things like 'int (&&A)[4];' correctly. 378 // FIXME: this should include vectors, but vectors use attributes I guess. 379 if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 380 OS << '('; 381 OS << "&&"; 382} 383void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T, 384 raw_ostream &OS) { 385 IncludeStrongLifetimeRAII Strong(Policy); 386 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 387 // Handle things like 'int (&&A)[4];' correctly. 388 // FIXME: this should include vectors, but vectors use attributes I guess. 389 if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 390 OS << ')'; 391 printAfter(T->getPointeeTypeAsWritten(), OS); 392} 393 394void TypePrinter::printMemberPointerBefore(const MemberPointerType *T, 395 raw_ostream &OS) { 396 IncludeStrongLifetimeRAII Strong(Policy); 397 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 398 printBefore(T->getPointeeType(), OS); 399 // Handle things like 'int (Cls::*A)[4];' correctly. 400 // FIXME: this should include vectors, but vectors use attributes I guess. 401 if (isa<ArrayType>(T->getPointeeType())) 402 OS << '('; 403 404 PrintingPolicy InnerPolicy(Policy); 405 InnerPolicy.SuppressTag = false; 406 TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef()); 407 408 OS << "::*"; 409} 410void TypePrinter::printMemberPointerAfter(const MemberPointerType *T, 411 raw_ostream &OS) { 412 IncludeStrongLifetimeRAII Strong(Policy); 413 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 414 // Handle things like 'int (Cls::*A)[4];' correctly. 415 // FIXME: this should include vectors, but vectors use attributes I guess. 416 if (isa<ArrayType>(T->getPointeeType())) 417 OS << ')'; 418 printAfter(T->getPointeeType(), OS); 419} 420 421void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T, 422 raw_ostream &OS) { 423 IncludeStrongLifetimeRAII Strong(Policy); 424 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 425 printBefore(T->getElementType(), OS); 426} 427void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T, 428 raw_ostream &OS) { 429 OS << '[' << T->getSize().getZExtValue() << ']'; 430 printAfter(T->getElementType(), OS); 431} 432 433void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T, 434 raw_ostream &OS) { 435 IncludeStrongLifetimeRAII Strong(Policy); 436 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 437 printBefore(T->getElementType(), OS); 438} 439void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T, 440 raw_ostream &OS) { 441 OS << "[]"; 442 printAfter(T->getElementType(), OS); 443} 444 445void TypePrinter::printVariableArrayBefore(const VariableArrayType *T, 446 raw_ostream &OS) { 447 IncludeStrongLifetimeRAII Strong(Policy); 448 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 449 printBefore(T->getElementType(), OS); 450} 451void TypePrinter::printVariableArrayAfter(const VariableArrayType *T, 452 raw_ostream &OS) { 453 OS << '['; 454 if (T->getIndexTypeQualifiers().hasQualifiers()) { 455 AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers()); 456 OS << ' '; 457 } 458 459 if (T->getSizeModifier() == VariableArrayType::Static) 460 OS << "static"; 461 else if (T->getSizeModifier() == VariableArrayType::Star) 462 OS << '*'; 463 464 if (T->getSizeExpr()) 465 T->getSizeExpr()->printPretty(OS, 0, Policy); 466 OS << ']'; 467 468 printAfter(T->getElementType(), OS); 469} 470 471void TypePrinter::printDependentSizedArrayBefore( 472 const DependentSizedArrayType *T, 473 raw_ostream &OS) { 474 IncludeStrongLifetimeRAII Strong(Policy); 475 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 476 printBefore(T->getElementType(), OS); 477} 478void TypePrinter::printDependentSizedArrayAfter( 479 const DependentSizedArrayType *T, 480 raw_ostream &OS) { 481 OS << '['; 482 if (T->getSizeExpr()) 483 T->getSizeExpr()->printPretty(OS, 0, Policy); 484 OS << ']'; 485 printAfter(T->getElementType(), OS); 486} 487 488void TypePrinter::printDependentSizedExtVectorBefore( 489 const DependentSizedExtVectorType *T, 490 raw_ostream &OS) { 491 printBefore(T->getElementType(), OS); 492} 493void TypePrinter::printDependentSizedExtVectorAfter( 494 const DependentSizedExtVectorType *T, 495 raw_ostream &OS) { 496 OS << " __attribute__((ext_vector_type("; 497 if (T->getSizeExpr()) 498 T->getSizeExpr()->printPretty(OS, 0, Policy); 499 OS << ")))"; 500 printAfter(T->getElementType(), OS); 501} 502 503void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) { 504 switch (T->getVectorKind()) { 505 case VectorType::AltiVecPixel: 506 OS << "__vector __pixel "; 507 break; 508 case VectorType::AltiVecBool: 509 OS << "__vector __bool "; 510 printBefore(T->getElementType(), OS); 511 break; 512 case VectorType::AltiVecVector: 513 OS << "__vector "; 514 printBefore(T->getElementType(), OS); 515 break; 516 case VectorType::NeonVector: 517 OS << "__attribute__((neon_vector_type(" 518 << T->getNumElements() << "))) "; 519 printBefore(T->getElementType(), OS); 520 break; 521 case VectorType::NeonPolyVector: 522 OS << "__attribute__((neon_polyvector_type(" << 523 T->getNumElements() << "))) "; 524 printBefore(T->getElementType(), OS); 525 break; 526 case VectorType::GenericVector: { 527 // FIXME: We prefer to print the size directly here, but have no way 528 // to get the size of the type. 529 OS << "__attribute__((__vector_size__(" 530 << T->getNumElements() 531 << " * sizeof("; 532 print(T->getElementType(), OS, StringRef()); 533 OS << ")))) "; 534 printBefore(T->getElementType(), OS); 535 break; 536 } 537 } 538} 539void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) { 540 printAfter(T->getElementType(), OS); 541} 542 543void TypePrinter::printExtVectorBefore(const ExtVectorType *T, 544 raw_ostream &OS) { 545 printBefore(T->getElementType(), OS); 546} 547void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) { 548 printAfter(T->getElementType(), OS); 549 OS << " __attribute__((ext_vector_type("; 550 OS << T->getNumElements(); 551 OS << ")))"; 552} 553 554void 555FunctionProtoType::printExceptionSpecification(raw_ostream &OS, 556 const PrintingPolicy &Policy) 557 const { 558 559 if (hasDynamicExceptionSpec()) { 560 OS << " throw("; 561 if (getExceptionSpecType() == EST_MSAny) 562 OS << "..."; 563 else 564 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) { 565 if (I) 566 OS << ", "; 567 568 OS << getExceptionType(I).stream(Policy); 569 } 570 OS << ')'; 571 } else if (isNoexceptExceptionSpec(getExceptionSpecType())) { 572 OS << " noexcept"; 573 if (getExceptionSpecType() == EST_ComputedNoexcept) { 574 OS << '('; 575 getNoexceptExpr()->printPretty(OS, 0, Policy); 576 OS << ')'; 577 } 578 } 579} 580 581void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T, 582 raw_ostream &OS) { 583 if (T->hasTrailingReturn()) { 584 OS << "auto "; 585 if (!HasEmptyPlaceHolder) 586 OS << '('; 587 } else { 588 // If needed for precedence reasons, wrap the inner part in grouping parens. 589 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false); 590 printBefore(T->getResultType(), OS); 591 if (!PrevPHIsEmpty.get()) 592 OS << '('; 593 } 594} 595 596void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, 597 raw_ostream &OS) { 598 // If needed for precedence reasons, wrap the inner part in grouping parens. 599 if (!HasEmptyPlaceHolder) 600 OS << ')'; 601 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 602 603 OS << '('; 604 { 605 ParamPolicyRAII ParamPolicy(Policy); 606 for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) { 607 if (i) OS << ", "; 608 print(T->getArgType(i), OS, StringRef()); 609 } 610 } 611 612 if (T->isVariadic()) { 613 if (T->getNumArgs()) 614 OS << ", "; 615 OS << "..."; 616 } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) { 617 // Do not emit int() if we have a proto, emit 'int(void)'. 618 OS << "void"; 619 } 620 621 OS << ')'; 622 623 FunctionType::ExtInfo Info = T->getExtInfo(); 624 switch(Info.getCC()) { 625 case CC_Default: break; 626 case CC_C: 627 OS << " __attribute__((cdecl))"; 628 break; 629 case CC_X86StdCall: 630 OS << " __attribute__((stdcall))"; 631 break; 632 case CC_X86FastCall: 633 OS << " __attribute__((fastcall))"; 634 break; 635 case CC_X86ThisCall: 636 OS << " __attribute__((thiscall))"; 637 break; 638 case CC_X86Pascal: 639 OS << " __attribute__((pascal))"; 640 break; 641 case CC_AAPCS: 642 OS << " __attribute__((pcs(\"aapcs\")))"; 643 break; 644 case CC_AAPCS_VFP: 645 OS << " __attribute__((pcs(\"aapcs-vfp\")))"; 646 break; 647 case CC_PnaclCall: 648 OS << " __attribute__((pnaclcall))"; 649 break; 650 case CC_IntelOclBicc: 651 OS << " __attribute__((intel_ocl_bicc))"; 652 break; 653 } 654 if (Info.getNoReturn()) 655 OS << " __attribute__((noreturn))"; 656 if (Info.getRegParm()) 657 OS << " __attribute__((regparm (" 658 << Info.getRegParm() << ")))"; 659 660 if (unsigned quals = T->getTypeQuals()) { 661 OS << ' '; 662 AppendTypeQualList(OS, quals); 663 } 664 665 switch (T->getRefQualifier()) { 666 case RQ_None: 667 break; 668 669 case RQ_LValue: 670 OS << " &"; 671 break; 672 673 case RQ_RValue: 674 OS << " &&"; 675 break; 676 } 677 T->printExceptionSpecification(OS, Policy); 678 679 if (T->hasTrailingReturn()) { 680 OS << " -> "; 681 print(T->getResultType(), OS, StringRef()); 682 } else 683 printAfter(T->getResultType(), OS); 684} 685 686void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T, 687 raw_ostream &OS) { 688 // If needed for precedence reasons, wrap the inner part in grouping parens. 689 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false); 690 printBefore(T->getResultType(), OS); 691 if (!PrevPHIsEmpty.get()) 692 OS << '('; 693} 694void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T, 695 raw_ostream &OS) { 696 // If needed for precedence reasons, wrap the inner part in grouping parens. 697 if (!HasEmptyPlaceHolder) 698 OS << ')'; 699 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 700 701 OS << "()"; 702 if (T->getNoReturnAttr()) 703 OS << " __attribute__((noreturn))"; 704 printAfter(T->getResultType(), OS); 705} 706 707void TypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) { 708 IdentifierInfo *II = D->getIdentifier(); 709 OS << II->getName(); 710 spaceBeforePlaceHolder(OS); 711} 712 713void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T, 714 raw_ostream &OS) { 715 printTypeSpec(T->getDecl(), OS); 716} 717void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T, 718 raw_ostream &OS) { } 719 720void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) { 721 printTypeSpec(T->getDecl(), OS); 722} 723void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) { } 724 725void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T, 726 raw_ostream &OS) { 727 OS << "typeof "; 728 T->getUnderlyingExpr()->printPretty(OS, 0, Policy); 729 spaceBeforePlaceHolder(OS); 730} 731void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T, 732 raw_ostream &OS) { } 733 734void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) { 735 OS << "typeof("; 736 print(T->getUnderlyingType(), OS, StringRef()); 737 OS << ')'; 738 spaceBeforePlaceHolder(OS); 739} 740void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) { } 741 742void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) { 743 OS << "decltype("; 744 T->getUnderlyingExpr()->printPretty(OS, 0, Policy); 745 OS << ')'; 746 spaceBeforePlaceHolder(OS); 747} 748void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) { } 749 750void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T, 751 raw_ostream &OS) { 752 IncludeStrongLifetimeRAII Strong(Policy); 753 754 switch (T->getUTTKind()) { 755 case UnaryTransformType::EnumUnderlyingType: 756 OS << "__underlying_type("; 757 print(T->getBaseType(), OS, StringRef()); 758 OS << ')'; 759 spaceBeforePlaceHolder(OS); 760 return; 761 } 762 763 printBefore(T->getBaseType(), OS); 764} 765void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T, 766 raw_ostream &OS) { 767 IncludeStrongLifetimeRAII Strong(Policy); 768 769 switch (T->getUTTKind()) { 770 case UnaryTransformType::EnumUnderlyingType: 771 return; 772 } 773 774 printAfter(T->getBaseType(), OS); 775} 776 777void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) { 778 // If the type has been deduced, do not print 'auto'. 779 if (!T->getDeducedType().isNull()) { 780 printBefore(T->getDeducedType(), OS); 781 } else { 782 OS << (T->isDecltypeAuto() ? "decltype(auto)" : "auto"); 783 spaceBeforePlaceHolder(OS); 784 } 785} 786void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) { 787 // If the type has been deduced, do not print 'auto'. 788 if (!T->getDeducedType().isNull()) 789 printAfter(T->getDeducedType(), OS); 790} 791 792void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) { 793 IncludeStrongLifetimeRAII Strong(Policy); 794 795 OS << "_Atomic("; 796 print(T->getValueType(), OS, StringRef()); 797 OS << ')'; 798 spaceBeforePlaceHolder(OS); 799} 800void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { } 801 802/// Appends the given scope to the end of a string. 803void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) { 804 if (DC->isTranslationUnit()) return; 805 if (DC->isFunctionOrMethod()) return; 806 AppendScope(DC->getParent(), OS); 807 808 if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { 809 if (Policy.SuppressUnwrittenScope && 810 (NS->isAnonymousNamespace() || NS->isInline())) 811 return; 812 if (NS->getIdentifier()) 813 OS << NS->getName() << "::"; 814 else 815 OS << "<anonymous>::"; 816 } else if (ClassTemplateSpecializationDecl *Spec 817 = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { 818 IncludeStrongLifetimeRAII Strong(Policy); 819 OS << Spec->getIdentifier()->getName(); 820 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 821 TemplateSpecializationType::PrintTemplateArgumentList(OS, 822 TemplateArgs.data(), 823 TemplateArgs.size(), 824 Policy); 825 OS << "::"; 826 } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { 827 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl()) 828 OS << Typedef->getIdentifier()->getName() << "::"; 829 else if (Tag->getIdentifier()) 830 OS << Tag->getIdentifier()->getName() << "::"; 831 else 832 return; 833 } 834} 835 836void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) { 837 if (Policy.SuppressTag) 838 return; 839 840 bool HasKindDecoration = false; 841 842 // bool SuppressTagKeyword 843 // = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword; 844 845 // We don't print tags unless this is an elaborated type. 846 // In C, we just assume every RecordType is an elaborated type. 847 if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword || 848 D->getTypedefNameForAnonDecl())) { 849 HasKindDecoration = true; 850 OS << D->getKindName(); 851 OS << ' '; 852 } 853 854 // Compute the full nested-name-specifier for this type. 855 // In C, this will always be empty except when the type 856 // being printed is anonymous within other Record. 857 if (!Policy.SuppressScope) 858 AppendScope(D->getDeclContext(), OS); 859 860 if (const IdentifierInfo *II = D->getIdentifier()) 861 OS << II->getName(); 862 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) { 863 assert(Typedef->getIdentifier() && "Typedef without identifier?"); 864 OS << Typedef->getIdentifier()->getName(); 865 } else { 866 // Make an unambiguous representation for anonymous types, e.g. 867 // <anonymous enum at /usr/include/string.h:120:9> 868 869 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) { 870 OS << "<lambda"; 871 HasKindDecoration = true; 872 } else { 873 OS << "<anonymous"; 874 } 875 876 if (Policy.AnonymousTagLocations) { 877 // Suppress the redundant tag keyword if we just printed one. 878 // We don't have to worry about ElaboratedTypes here because you can't 879 // refer to an anonymous type with one. 880 if (!HasKindDecoration) 881 OS << " " << D->getKindName(); 882 883 PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc( 884 D->getLocation()); 885 if (PLoc.isValid()) { 886 OS << " at " << PLoc.getFilename() 887 << ':' << PLoc.getLine() 888 << ':' << PLoc.getColumn(); 889 } 890 } 891 892 OS << '>'; 893 } 894 895 // If this is a class template specialization, print the template 896 // arguments. 897 if (ClassTemplateSpecializationDecl *Spec 898 = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 899 const TemplateArgument *Args; 900 unsigned NumArgs; 901 if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { 902 const TemplateSpecializationType *TST = 903 cast<TemplateSpecializationType>(TAW->getType()); 904 Args = TST->getArgs(); 905 NumArgs = TST->getNumArgs(); 906 } else { 907 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 908 Args = TemplateArgs.data(); 909 NumArgs = TemplateArgs.size(); 910 } 911 IncludeStrongLifetimeRAII Strong(Policy); 912 TemplateSpecializationType::PrintTemplateArgumentList(OS, 913 Args, NumArgs, 914 Policy); 915 } 916 917 spaceBeforePlaceHolder(OS); 918} 919 920void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) { 921 printTag(T->getDecl(), OS); 922} 923void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) { } 924 925void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) { 926 printTag(T->getDecl(), OS); 927} 928void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) { } 929 930void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T, 931 raw_ostream &OS) { 932 if (IdentifierInfo *Id = T->getIdentifier()) 933 OS << Id->getName(); 934 else 935 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex(); 936 spaceBeforePlaceHolder(OS); 937} 938void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T, 939 raw_ostream &OS) { } 940 941void TypePrinter::printSubstTemplateTypeParmBefore( 942 const SubstTemplateTypeParmType *T, 943 raw_ostream &OS) { 944 IncludeStrongLifetimeRAII Strong(Policy); 945 printBefore(T->getReplacementType(), OS); 946} 947void TypePrinter::printSubstTemplateTypeParmAfter( 948 const SubstTemplateTypeParmType *T, 949 raw_ostream &OS) { 950 IncludeStrongLifetimeRAII Strong(Policy); 951 printAfter(T->getReplacementType(), OS); 952} 953 954void TypePrinter::printSubstTemplateTypeParmPackBefore( 955 const SubstTemplateTypeParmPackType *T, 956 raw_ostream &OS) { 957 IncludeStrongLifetimeRAII Strong(Policy); 958 printTemplateTypeParmBefore(T->getReplacedParameter(), OS); 959} 960void TypePrinter::printSubstTemplateTypeParmPackAfter( 961 const SubstTemplateTypeParmPackType *T, 962 raw_ostream &OS) { 963 IncludeStrongLifetimeRAII Strong(Policy); 964 printTemplateTypeParmAfter(T->getReplacedParameter(), OS); 965} 966 967void TypePrinter::printTemplateSpecializationBefore( 968 const TemplateSpecializationType *T, 969 raw_ostream &OS) { 970 IncludeStrongLifetimeRAII Strong(Policy); 971 T->getTemplateName().print(OS, Policy); 972 973 TemplateSpecializationType::PrintTemplateArgumentList(OS, 974 T->getArgs(), 975 T->getNumArgs(), 976 Policy); 977 spaceBeforePlaceHolder(OS); 978} 979void TypePrinter::printTemplateSpecializationAfter( 980 const TemplateSpecializationType *T, 981 raw_ostream &OS) { } 982 983void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T, 984 raw_ostream &OS) { 985 printTemplateSpecializationBefore(T->getInjectedTST(), OS); 986} 987void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T, 988 raw_ostream &OS) { } 989 990void TypePrinter::printElaboratedBefore(const ElaboratedType *T, 991 raw_ostream &OS) { 992 OS << TypeWithKeyword::getKeywordName(T->getKeyword()); 993 if (T->getKeyword() != ETK_None) 994 OS << " "; 995 NestedNameSpecifier* Qualifier = T->getQualifier(); 996 if (Qualifier) 997 Qualifier->print(OS, Policy); 998 999 ElaboratedTypePolicyRAII PolicyRAII(Policy); 1000 printBefore(T->getNamedType(), OS); 1001} 1002void TypePrinter::printElaboratedAfter(const ElaboratedType *T, 1003 raw_ostream &OS) { 1004 ElaboratedTypePolicyRAII PolicyRAII(Policy); 1005 printAfter(T->getNamedType(), OS); 1006} 1007 1008void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) { 1009 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) { 1010 printBefore(T->getInnerType(), OS); 1011 OS << '('; 1012 } else 1013 printBefore(T->getInnerType(), OS); 1014} 1015void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) { 1016 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) { 1017 OS << ')'; 1018 printAfter(T->getInnerType(), OS); 1019 } else 1020 printAfter(T->getInnerType(), OS); 1021} 1022 1023void TypePrinter::printDependentNameBefore(const DependentNameType *T, 1024 raw_ostream &OS) { 1025 OS << TypeWithKeyword::getKeywordName(T->getKeyword()); 1026 if (T->getKeyword() != ETK_None) 1027 OS << " "; 1028 1029 T->getQualifier()->print(OS, Policy); 1030 1031 OS << T->getIdentifier()->getName(); 1032 spaceBeforePlaceHolder(OS); 1033} 1034void TypePrinter::printDependentNameAfter(const DependentNameType *T, 1035 raw_ostream &OS) { } 1036 1037void TypePrinter::printDependentTemplateSpecializationBefore( 1038 const DependentTemplateSpecializationType *T, raw_ostream &OS) { 1039 IncludeStrongLifetimeRAII Strong(Policy); 1040 1041 OS << TypeWithKeyword::getKeywordName(T->getKeyword()); 1042 if (T->getKeyword() != ETK_None) 1043 OS << " "; 1044 1045 if (T->getQualifier()) 1046 T->getQualifier()->print(OS, Policy); 1047 OS << T->getIdentifier()->getName(); 1048 TemplateSpecializationType::PrintTemplateArgumentList(OS, 1049 T->getArgs(), 1050 T->getNumArgs(), 1051 Policy); 1052 spaceBeforePlaceHolder(OS); 1053} 1054void TypePrinter::printDependentTemplateSpecializationAfter( 1055 const DependentTemplateSpecializationType *T, raw_ostream &OS) { } 1056 1057void TypePrinter::printPackExpansionBefore(const PackExpansionType *T, 1058 raw_ostream &OS) { 1059 printBefore(T->getPattern(), OS); 1060} 1061void TypePrinter::printPackExpansionAfter(const PackExpansionType *T, 1062 raw_ostream &OS) { 1063 printAfter(T->getPattern(), OS); 1064 OS << "..."; 1065} 1066 1067void TypePrinter::printAttributedBefore(const AttributedType *T, 1068 raw_ostream &OS) { 1069 // Prefer the macro forms of the GC and ownership qualifiers. 1070 if (T->getAttrKind() == AttributedType::attr_objc_gc || 1071 T->getAttrKind() == AttributedType::attr_objc_ownership) 1072 return printBefore(T->getEquivalentType(), OS); 1073 1074 printBefore(T->getModifiedType(), OS); 1075 1076 if (T->isMSTypeSpec()) { 1077 switch (T->getAttrKind()) { 1078 default: return; 1079 case AttributedType::attr_ptr32: OS << " __ptr32"; break; 1080 case AttributedType::attr_ptr64: OS << " __ptr64"; break; 1081 case AttributedType::attr_sptr: OS << " __sptr"; break; 1082 case AttributedType::attr_uptr: OS << " __uptr"; break; 1083} 1084 spaceBeforePlaceHolder(OS); 1085 } 1086} 1087 1088void TypePrinter::printAttributedAfter(const AttributedType *T, 1089 raw_ostream &OS) { 1090 // Prefer the macro forms of the GC and ownership qualifiers. 1091 if (T->getAttrKind() == AttributedType::attr_objc_gc || 1092 T->getAttrKind() == AttributedType::attr_objc_ownership) 1093 return printAfter(T->getEquivalentType(), OS); 1094 1095 // TODO: not all attributes are GCC-style attributes. 1096 if (T->isMSTypeSpec()) 1097 return; 1098 1099 OS << " __attribute__(("; 1100 switch (T->getAttrKind()) { 1101 default: llvm_unreachable("This attribute should have been handled already"); 1102 case AttributedType::attr_address_space: 1103 OS << "address_space("; 1104 OS << T->getEquivalentType().getAddressSpace(); 1105 OS << ')'; 1106 break; 1107 1108 case AttributedType::attr_vector_size: { 1109 OS << "__vector_size__("; 1110 if (const VectorType *vector =T->getEquivalentType()->getAs<VectorType>()) { 1111 OS << vector->getNumElements(); 1112 OS << " * sizeof("; 1113 print(vector->getElementType(), OS, StringRef()); 1114 OS << ')'; 1115 } 1116 OS << ')'; 1117 break; 1118 } 1119 1120 case AttributedType::attr_neon_vector_type: 1121 case AttributedType::attr_neon_polyvector_type: { 1122 if (T->getAttrKind() == AttributedType::attr_neon_vector_type) 1123 OS << "neon_vector_type("; 1124 else 1125 OS << "neon_polyvector_type("; 1126 const VectorType *vector = T->getEquivalentType()->getAs<VectorType>(); 1127 OS << vector->getNumElements(); 1128 OS << ')'; 1129 break; 1130 } 1131 1132 case AttributedType::attr_regparm: { 1133 OS << "regparm("; 1134 QualType t = T->getEquivalentType(); 1135 while (!t->isFunctionType()) 1136 t = t->getPointeeType(); 1137 OS << t->getAs<FunctionType>()->getRegParmType(); 1138 OS << ')'; 1139 break; 1140 } 1141 1142 case AttributedType::attr_objc_gc: { 1143 OS << "objc_gc("; 1144 1145 QualType tmp = T->getEquivalentType(); 1146 while (tmp.getObjCGCAttr() == Qualifiers::GCNone) { 1147 QualType next = tmp->getPointeeType(); 1148 if (next == tmp) break; 1149 tmp = next; 1150 } 1151 1152 if (tmp.isObjCGCWeak()) 1153 OS << "weak"; 1154 else 1155 OS << "strong"; 1156 OS << ')'; 1157 break; 1158 } 1159 1160 case AttributedType::attr_objc_ownership: 1161 OS << "objc_ownership("; 1162 switch (T->getEquivalentType().getObjCLifetime()) { 1163 case Qualifiers::OCL_None: llvm_unreachable("no ownership!"); 1164 case Qualifiers::OCL_ExplicitNone: OS << "none"; break; 1165 case Qualifiers::OCL_Strong: OS << "strong"; break; 1166 case Qualifiers::OCL_Weak: OS << "weak"; break; 1167 case Qualifiers::OCL_Autoreleasing: OS << "autoreleasing"; break; 1168 } 1169 OS << ')'; 1170 break; 1171 1172 case AttributedType::attr_noreturn: OS << "noreturn"; break; 1173 case AttributedType::attr_cdecl: OS << "cdecl"; break; 1174 case AttributedType::attr_fastcall: OS << "fastcall"; break; 1175 case AttributedType::attr_stdcall: OS << "stdcall"; break; 1176 case AttributedType::attr_thiscall: OS << "thiscall"; break; 1177 case AttributedType::attr_pascal: OS << "pascal"; break; 1178 case AttributedType::attr_pcs: { 1179 OS << "pcs("; 1180 QualType t = T->getEquivalentType(); 1181 while (!t->isFunctionType()) 1182 t = t->getPointeeType(); 1183 OS << (t->getAs<FunctionType>()->getCallConv() == CC_AAPCS ? 1184 "\"aapcs\"" : "\"aapcs-vfp\""); 1185 OS << ')'; 1186 break; 1187 } 1188 case AttributedType::attr_pnaclcall: OS << "pnaclcall"; break; 1189 case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break; 1190 } 1191 OS << "))"; 1192} 1193 1194void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T, 1195 raw_ostream &OS) { 1196 OS << T->getDecl()->getName(); 1197 spaceBeforePlaceHolder(OS); 1198} 1199void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T, 1200 raw_ostream &OS) { } 1201 1202void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T, 1203 raw_ostream &OS) { 1204 if (T->qual_empty()) 1205 return printBefore(T->getBaseType(), OS); 1206 1207 print(T->getBaseType(), OS, StringRef()); 1208 OS << '<'; 1209 bool isFirst = true; 1210 for (ObjCObjectType::qual_iterator 1211 I = T->qual_begin(), E = T->qual_end(); I != E; ++I) { 1212 if (isFirst) 1213 isFirst = false; 1214 else 1215 OS << ','; 1216 OS << (*I)->getName(); 1217 } 1218 OS << '>'; 1219 spaceBeforePlaceHolder(OS); 1220} 1221void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T, 1222 raw_ostream &OS) { 1223 if (T->qual_empty()) 1224 return printAfter(T->getBaseType(), OS); 1225} 1226 1227void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T, 1228 raw_ostream &OS) { 1229 T->getPointeeType().getLocalQualifiers().print(OS, Policy, 1230 /*appendSpaceIfNonEmpty=*/true); 1231 1232 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) 1233 OS << "id"; 1234 else if (T->isObjCClassType() || T->isObjCQualifiedClassType()) 1235 OS << "Class"; 1236 else if (T->isObjCSelType()) 1237 OS << "SEL"; 1238 else 1239 OS << T->getInterfaceDecl()->getName(); 1240 1241 if (!T->qual_empty()) { 1242 OS << '<'; 1243 for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(), 1244 E = T->qual_end(); 1245 I != E; ++I) { 1246 OS << (*I)->getName(); 1247 if (I+1 != E) 1248 OS << ','; 1249 } 1250 OS << '>'; 1251 } 1252 1253 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType()) { 1254 OS << " *"; // Don't forget the implicit pointer. 1255 } else { 1256 spaceBeforePlaceHolder(OS); 1257 } 1258} 1259void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T, 1260 raw_ostream &OS) { } 1261 1262void TemplateSpecializationType:: 1263 PrintTemplateArgumentList(raw_ostream &OS, 1264 const TemplateArgumentListInfo &Args, 1265 const PrintingPolicy &Policy) { 1266 return PrintTemplateArgumentList(OS, 1267 Args.getArgumentArray(), 1268 Args.size(), 1269 Policy); 1270} 1271 1272void 1273TemplateSpecializationType::PrintTemplateArgumentList( 1274 raw_ostream &OS, 1275 const TemplateArgument *Args, 1276 unsigned NumArgs, 1277 const PrintingPolicy &Policy, 1278 bool SkipBrackets) { 1279 if (!SkipBrackets) 1280 OS << '<'; 1281 1282 bool needSpace = false; 1283 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 1284 // Print the argument into a string. 1285 SmallString<128> Buf; 1286 llvm::raw_svector_ostream ArgOS(Buf); 1287 if (Args[Arg].getKind() == TemplateArgument::Pack) { 1288 if (Args[Arg].pack_size() && Arg > 0) 1289 OS << ", "; 1290 PrintTemplateArgumentList(ArgOS, 1291 Args[Arg].pack_begin(), 1292 Args[Arg].pack_size(), 1293 Policy, true); 1294 } else { 1295 if (Arg > 0) 1296 OS << ", "; 1297 Args[Arg].print(Policy, ArgOS); 1298 } 1299 StringRef ArgString = ArgOS.str(); 1300 1301 // If this is the first argument and its string representation 1302 // begins with the global scope specifier ('::foo'), add a space 1303 // to avoid printing the diagraph '<:'. 1304 if (!Arg && !ArgString.empty() && ArgString[0] == ':') 1305 OS << ' '; 1306 1307 OS << ArgString; 1308 1309 needSpace = (!ArgString.empty() && ArgString.back() == '>'); 1310 } 1311 1312 // If the last character of our string is '>', add another space to 1313 // keep the two '>''s separate tokens. We don't *have* to do this in 1314 // C++0x, but it's still good hygiene. 1315 if (needSpace) 1316 OS << ' '; 1317 1318 if (!SkipBrackets) 1319 OS << '>'; 1320} 1321 1322// Sadly, repeat all that with TemplateArgLoc. 1323void TemplateSpecializationType:: 1324PrintTemplateArgumentList(raw_ostream &OS, 1325 const TemplateArgumentLoc *Args, unsigned NumArgs, 1326 const PrintingPolicy &Policy) { 1327 OS << '<'; 1328 1329 bool needSpace = false; 1330 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 1331 if (Arg > 0) 1332 OS << ", "; 1333 1334 // Print the argument into a string. 1335 SmallString<128> Buf; 1336 llvm::raw_svector_ostream ArgOS(Buf); 1337 if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) { 1338 PrintTemplateArgumentList(ArgOS, 1339 Args[Arg].getArgument().pack_begin(), 1340 Args[Arg].getArgument().pack_size(), 1341 Policy, true); 1342 } else { 1343 Args[Arg].getArgument().print(Policy, ArgOS); 1344 } 1345 StringRef ArgString = ArgOS.str(); 1346 1347 // If this is the first argument and its string representation 1348 // begins with the global scope specifier ('::foo'), add a space 1349 // to avoid printing the diagraph '<:'. 1350 if (!Arg && !ArgString.empty() && ArgString[0] == ':') 1351 OS << ' '; 1352 1353 OS << ArgString; 1354 1355 needSpace = (!ArgString.empty() && ArgString.back() == '>'); 1356 } 1357 1358 // If the last character of our string is '>', add another space to 1359 // keep the two '>''s separate tokens. We don't *have* to do this in 1360 // C++0x, but it's still good hygiene. 1361 if (needSpace) 1362 OS << ' '; 1363 1364 OS << '>'; 1365} 1366 1367void QualType::dump(const char *msg) const { 1368 if (msg) 1369 llvm::errs() << msg << ": "; 1370 LangOptions LO; 1371 print(llvm::errs(), PrintingPolicy(LO), "identifier"); 1372 llvm::errs() << '\n'; 1373} 1374void QualType::dump() const { 1375 dump(0); 1376} 1377 1378void Type::dump() const { 1379 QualType(this, 0).dump(); 1380} 1381 1382std::string Qualifiers::getAsString() const { 1383 LangOptions LO; 1384 return getAsString(PrintingPolicy(LO)); 1385} 1386 1387// Appends qualifiers to the given string, separated by spaces. Will 1388// prefix a space if the string is non-empty. Will not append a final 1389// space. 1390std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const { 1391 SmallString<64> Buf; 1392 llvm::raw_svector_ostream StrOS(Buf); 1393 print(StrOS, Policy); 1394 return StrOS.str(); 1395} 1396 1397bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const { 1398 if (getCVRQualifiers()) 1399 return false; 1400 1401 if (getAddressSpace()) 1402 return false; 1403 1404 if (getObjCGCAttr()) 1405 return false; 1406 1407 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) 1408 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)) 1409 return false; 1410 1411 return true; 1412} 1413 1414// Appends qualifiers to the given string, separated by spaces. Will 1415// prefix a space if the string is non-empty. Will not append a final 1416// space. 1417void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy, 1418 bool appendSpaceIfNonEmpty) const { 1419 bool addSpace = false; 1420 1421 unsigned quals = getCVRQualifiers(); 1422 if (quals) { 1423 AppendTypeQualList(OS, quals); 1424 addSpace = true; 1425 } 1426 if (unsigned addrspace = getAddressSpace()) { 1427 if (addSpace) 1428 OS << ' '; 1429 addSpace = true; 1430 switch (addrspace) { 1431 case LangAS::opencl_global: 1432 OS << "__global"; 1433 break; 1434 case LangAS::opencl_local: 1435 OS << "__local"; 1436 break; 1437 case LangAS::opencl_constant: 1438 OS << "__constant"; 1439 break; 1440 default: 1441 OS << "__attribute__((address_space("; 1442 OS << addrspace; 1443 OS << ")))"; 1444 } 1445 } 1446 if (Qualifiers::GC gc = getObjCGCAttr()) { 1447 if (addSpace) 1448 OS << ' '; 1449 addSpace = true; 1450 if (gc == Qualifiers::Weak) 1451 OS << "__weak"; 1452 else 1453 OS << "__strong"; 1454 } 1455 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) { 1456 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){ 1457 if (addSpace) 1458 OS << ' '; 1459 addSpace = true; 1460 } 1461 1462 switch (lifetime) { 1463 case Qualifiers::OCL_None: llvm_unreachable("none but true"); 1464 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break; 1465 case Qualifiers::OCL_Strong: 1466 if (!Policy.SuppressStrongLifetime) 1467 OS << "__strong"; 1468 break; 1469 1470 case Qualifiers::OCL_Weak: OS << "__weak"; break; 1471 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break; 1472 } 1473 } 1474 1475 if (appendSpaceIfNonEmpty && addSpace) 1476 OS << ' '; 1477} 1478 1479std::string QualType::getAsString(const PrintingPolicy &Policy) const { 1480 std::string S; 1481 getAsStringInternal(S, Policy); 1482 return S; 1483} 1484 1485std::string QualType::getAsString(const Type *ty, Qualifiers qs) { 1486 std::string buffer; 1487 LangOptions options; 1488 getAsStringInternal(ty, qs, buffer, PrintingPolicy(options)); 1489 return buffer; 1490} 1491 1492void QualType::print(const Type *ty, Qualifiers qs, 1493 raw_ostream &OS, const PrintingPolicy &policy, 1494 const Twine &PlaceHolder) { 1495 SmallString<128> PHBuf; 1496 StringRef PH = PlaceHolder.toStringRef(PHBuf); 1497 1498 TypePrinter(policy).print(ty, qs, OS, PH); 1499} 1500 1501void QualType::getAsStringInternal(const Type *ty, Qualifiers qs, 1502 std::string &buffer, 1503 const PrintingPolicy &policy) { 1504 SmallString<256> Buf; 1505 llvm::raw_svector_ostream StrOS(Buf); 1506 TypePrinter(policy).print(ty, qs, StrOS, buffer); 1507 std::string str = StrOS.str(); 1508 buffer.swap(str); 1509} 1510