TypePrinter.cpp revision 4c67aa96401b67b5200e701cff87485067ab0792
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_Cold: 630 OS << " __attribute__((coldcc))"; 631 break; 632 case CC_X86StdCall: 633 OS << " __attribute__((stdcall))"; 634 break; 635 case CC_X86FastCall: 636 OS << " __attribute__((fastcall))"; 637 break; 638 case CC_X86ThisCall: 639 OS << " __attribute__((thiscall))"; 640 break; 641 case CC_X86Pascal: 642 OS << " __attribute__((pascal))"; 643 break; 644 case CC_AAPCS: 645 OS << " __attribute__((pcs(\"aapcs\")))"; 646 break; 647 case CC_AAPCS_VFP: 648 OS << " __attribute__((pcs(\"aapcs-vfp\")))"; 649 break; 650 case CC_PnaclCall: 651 OS << " __attribute__((pnaclcall))"; 652 break; 653 case CC_IntelOclBicc: 654 OS << " __attribute__((intel_ocl_bicc))"; 655 break; 656 } 657 if (Info.getNoReturn()) 658 OS << " __attribute__((noreturn))"; 659 if (Info.getRegParm()) 660 OS << " __attribute__((regparm (" 661 << Info.getRegParm() << ")))"; 662 663 if (unsigned quals = T->getTypeQuals()) { 664 OS << ' '; 665 AppendTypeQualList(OS, quals); 666 } 667 668 switch (T->getRefQualifier()) { 669 case RQ_None: 670 break; 671 672 case RQ_LValue: 673 OS << " &"; 674 break; 675 676 case RQ_RValue: 677 OS << " &&"; 678 break; 679 } 680 T->printExceptionSpecification(OS, Policy); 681 682 if (T->hasTrailingReturn()) { 683 OS << " -> "; 684 print(T->getResultType(), OS, StringRef()); 685 } else 686 printAfter(T->getResultType(), OS); 687} 688 689void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T, 690 raw_ostream &OS) { 691 // If needed for precedence reasons, wrap the inner part in grouping parens. 692 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false); 693 printBefore(T->getResultType(), OS); 694 if (!PrevPHIsEmpty.get()) 695 OS << '('; 696} 697void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T, 698 raw_ostream &OS) { 699 // If needed for precedence reasons, wrap the inner part in grouping parens. 700 if (!HasEmptyPlaceHolder) 701 OS << ')'; 702 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 703 704 OS << "()"; 705 if (T->getNoReturnAttr()) 706 OS << " __attribute__((noreturn))"; 707 printAfter(T->getResultType(), OS); 708} 709 710void TypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) { 711 IdentifierInfo *II = D->getIdentifier(); 712 OS << II->getName(); 713 spaceBeforePlaceHolder(OS); 714} 715 716void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T, 717 raw_ostream &OS) { 718 printTypeSpec(T->getDecl(), OS); 719} 720void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T, 721 raw_ostream &OS) { } 722 723void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) { 724 printTypeSpec(T->getDecl(), OS); 725} 726void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) { } 727 728void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T, 729 raw_ostream &OS) { 730 OS << "typeof "; 731 T->getUnderlyingExpr()->printPretty(OS, 0, Policy); 732 spaceBeforePlaceHolder(OS); 733} 734void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T, 735 raw_ostream &OS) { } 736 737void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) { 738 OS << "typeof("; 739 print(T->getUnderlyingType(), OS, StringRef()); 740 OS << ')'; 741 spaceBeforePlaceHolder(OS); 742} 743void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) { } 744 745void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) { 746 OS << "decltype("; 747 T->getUnderlyingExpr()->printPretty(OS, 0, Policy); 748 OS << ')'; 749 spaceBeforePlaceHolder(OS); 750} 751void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) { } 752 753void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T, 754 raw_ostream &OS) { 755 IncludeStrongLifetimeRAII Strong(Policy); 756 757 switch (T->getUTTKind()) { 758 case UnaryTransformType::EnumUnderlyingType: 759 OS << "__underlying_type("; 760 print(T->getBaseType(), OS, StringRef()); 761 OS << ')'; 762 spaceBeforePlaceHolder(OS); 763 return; 764 } 765 766 printBefore(T->getBaseType(), OS); 767} 768void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T, 769 raw_ostream &OS) { 770 IncludeStrongLifetimeRAII Strong(Policy); 771 772 switch (T->getUTTKind()) { 773 case UnaryTransformType::EnumUnderlyingType: 774 return; 775 } 776 777 printAfter(T->getBaseType(), OS); 778} 779 780void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) { 781 // If the type has been deduced, do not print 'auto'. 782 if (T->isDeduced()) { 783 printBefore(T->getDeducedType(), OS); 784 } else { 785 OS << "auto"; 786 spaceBeforePlaceHolder(OS); 787 } 788} 789void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) { 790 // If the type has been deduced, do not print 'auto'. 791 if (T->isDeduced()) 792 printAfter(T->getDeducedType(), OS); 793} 794 795void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) { 796 IncludeStrongLifetimeRAII Strong(Policy); 797 798 OS << "_Atomic("; 799 print(T->getValueType(), OS, StringRef()); 800 OS << ')'; 801 spaceBeforePlaceHolder(OS); 802} 803void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { } 804 805/// Appends the given scope to the end of a string. 806void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) { 807 if (DC->isTranslationUnit()) return; 808 if (DC->isFunctionOrMethod()) return; 809 AppendScope(DC->getParent(), OS); 810 811 if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { 812 if (Policy.SuppressUnwrittenScope && 813 (NS->isAnonymousNamespace() || NS->isInline())) 814 return; 815 if (NS->getIdentifier()) 816 OS << NS->getName() << "::"; 817 else 818 OS << "<anonymous>::"; 819 } else if (ClassTemplateSpecializationDecl *Spec 820 = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { 821 IncludeStrongLifetimeRAII Strong(Policy); 822 OS << Spec->getIdentifier()->getName(); 823 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 824 TemplateSpecializationType::PrintTemplateArgumentList(OS, 825 TemplateArgs.data(), 826 TemplateArgs.size(), 827 Policy); 828 OS << "::"; 829 } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { 830 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl()) 831 OS << Typedef->getIdentifier()->getName() << "::"; 832 else if (Tag->getIdentifier()) 833 OS << Tag->getIdentifier()->getName() << "::"; 834 else 835 return; 836 } 837} 838 839void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) { 840 if (Policy.SuppressTag) 841 return; 842 843 bool HasKindDecoration = false; 844 845 // bool SuppressTagKeyword 846 // = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword; 847 848 // We don't print tags unless this is an elaborated type. 849 // In C, we just assume every RecordType is an elaborated type. 850 if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword || 851 D->getTypedefNameForAnonDecl())) { 852 HasKindDecoration = true; 853 OS << D->getKindName(); 854 OS << ' '; 855 } 856 857 // Compute the full nested-name-specifier for this type. 858 // In C, this will always be empty except when the type 859 // being printed is anonymous within other Record. 860 if (!Policy.SuppressScope) 861 AppendScope(D->getDeclContext(), OS); 862 863 if (const IdentifierInfo *II = D->getIdentifier()) 864 OS << II->getName(); 865 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) { 866 assert(Typedef->getIdentifier() && "Typedef without identifier?"); 867 OS << Typedef->getIdentifier()->getName(); 868 } else { 869 // Make an unambiguous representation for anonymous types, e.g. 870 // <anonymous enum at /usr/include/string.h:120:9> 871 872 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) { 873 OS << "<lambda"; 874 HasKindDecoration = true; 875 } else { 876 OS << "<anonymous"; 877 } 878 879 if (Policy.AnonymousTagLocations) { 880 // Suppress the redundant tag keyword if we just printed one. 881 // We don't have to worry about ElaboratedTypes here because you can't 882 // refer to an anonymous type with one. 883 if (!HasKindDecoration) 884 OS << " " << D->getKindName(); 885 886 PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc( 887 D->getLocation()); 888 if (PLoc.isValid()) { 889 OS << " at " << PLoc.getFilename() 890 << ':' << PLoc.getLine() 891 << ':' << PLoc.getColumn(); 892 } 893 } 894 895 OS << '>'; 896 } 897 898 // If this is a class template specialization, print the template 899 // arguments. 900 if (ClassTemplateSpecializationDecl *Spec 901 = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 902 const TemplateArgument *Args; 903 unsigned NumArgs; 904 if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { 905 const TemplateSpecializationType *TST = 906 cast<TemplateSpecializationType>(TAW->getType()); 907 Args = TST->getArgs(); 908 NumArgs = TST->getNumArgs(); 909 } else { 910 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 911 Args = TemplateArgs.data(); 912 NumArgs = TemplateArgs.size(); 913 } 914 IncludeStrongLifetimeRAII Strong(Policy); 915 TemplateSpecializationType::PrintTemplateArgumentList(OS, 916 Args, NumArgs, 917 Policy); 918 } 919 920 spaceBeforePlaceHolder(OS); 921} 922 923void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) { 924 printTag(T->getDecl(), OS); 925} 926void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) { } 927 928void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) { 929 printTag(T->getDecl(), OS); 930} 931void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) { } 932 933void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T, 934 raw_ostream &OS) { 935 if (IdentifierInfo *Id = T->getIdentifier()) 936 OS << Id->getName(); 937 else 938 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex(); 939 spaceBeforePlaceHolder(OS); 940} 941void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T, 942 raw_ostream &OS) { } 943 944void TypePrinter::printSubstTemplateTypeParmBefore( 945 const SubstTemplateTypeParmType *T, 946 raw_ostream &OS) { 947 IncludeStrongLifetimeRAII Strong(Policy); 948 printBefore(T->getReplacementType(), OS); 949} 950void TypePrinter::printSubstTemplateTypeParmAfter( 951 const SubstTemplateTypeParmType *T, 952 raw_ostream &OS) { 953 IncludeStrongLifetimeRAII Strong(Policy); 954 printAfter(T->getReplacementType(), OS); 955} 956 957void TypePrinter::printSubstTemplateTypeParmPackBefore( 958 const SubstTemplateTypeParmPackType *T, 959 raw_ostream &OS) { 960 IncludeStrongLifetimeRAII Strong(Policy); 961 printTemplateTypeParmBefore(T->getReplacedParameter(), OS); 962} 963void TypePrinter::printSubstTemplateTypeParmPackAfter( 964 const SubstTemplateTypeParmPackType *T, 965 raw_ostream &OS) { 966 IncludeStrongLifetimeRAII Strong(Policy); 967 printTemplateTypeParmAfter(T->getReplacedParameter(), OS); 968} 969 970void TypePrinter::printTemplateSpecializationBefore( 971 const TemplateSpecializationType *T, 972 raw_ostream &OS) { 973 IncludeStrongLifetimeRAII Strong(Policy); 974 T->getTemplateName().print(OS, Policy); 975 976 TemplateSpecializationType::PrintTemplateArgumentList(OS, 977 T->getArgs(), 978 T->getNumArgs(), 979 Policy); 980 spaceBeforePlaceHolder(OS); 981} 982void TypePrinter::printTemplateSpecializationAfter( 983 const TemplateSpecializationType *T, 984 raw_ostream &OS) { } 985 986void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T, 987 raw_ostream &OS) { 988 printTemplateSpecializationBefore(T->getInjectedTST(), OS); 989} 990void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T, 991 raw_ostream &OS) { } 992 993void TypePrinter::printElaboratedBefore(const ElaboratedType *T, 994 raw_ostream &OS) { 995 OS << TypeWithKeyword::getKeywordName(T->getKeyword()); 996 if (T->getKeyword() != ETK_None) 997 OS << " "; 998 NestedNameSpecifier* Qualifier = T->getQualifier(); 999 if (Qualifier) 1000 Qualifier->print(OS, Policy); 1001 1002 ElaboratedTypePolicyRAII PolicyRAII(Policy); 1003 printBefore(T->getNamedType(), OS); 1004} 1005void TypePrinter::printElaboratedAfter(const ElaboratedType *T, 1006 raw_ostream &OS) { 1007 ElaboratedTypePolicyRAII PolicyRAII(Policy); 1008 printAfter(T->getNamedType(), OS); 1009} 1010 1011void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) { 1012 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) { 1013 printBefore(T->getInnerType(), OS); 1014 OS << '('; 1015 } else 1016 printBefore(T->getInnerType(), OS); 1017} 1018void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) { 1019 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) { 1020 OS << ')'; 1021 printAfter(T->getInnerType(), OS); 1022 } else 1023 printAfter(T->getInnerType(), OS); 1024} 1025 1026void TypePrinter::printDependentNameBefore(const DependentNameType *T, 1027 raw_ostream &OS) { 1028 OS << TypeWithKeyword::getKeywordName(T->getKeyword()); 1029 if (T->getKeyword() != ETK_None) 1030 OS << " "; 1031 1032 T->getQualifier()->print(OS, Policy); 1033 1034 OS << T->getIdentifier()->getName(); 1035 spaceBeforePlaceHolder(OS); 1036} 1037void TypePrinter::printDependentNameAfter(const DependentNameType *T, 1038 raw_ostream &OS) { } 1039 1040void TypePrinter::printDependentTemplateSpecializationBefore( 1041 const DependentTemplateSpecializationType *T, raw_ostream &OS) { 1042 IncludeStrongLifetimeRAII Strong(Policy); 1043 1044 OS << TypeWithKeyword::getKeywordName(T->getKeyword()); 1045 if (T->getKeyword() != ETK_None) 1046 OS << " "; 1047 1048 if (T->getQualifier()) 1049 T->getQualifier()->print(OS, Policy); 1050 OS << T->getIdentifier()->getName(); 1051 TemplateSpecializationType::PrintTemplateArgumentList(OS, 1052 T->getArgs(), 1053 T->getNumArgs(), 1054 Policy); 1055 spaceBeforePlaceHolder(OS); 1056} 1057void TypePrinter::printDependentTemplateSpecializationAfter( 1058 const DependentTemplateSpecializationType *T, raw_ostream &OS) { } 1059 1060void TypePrinter::printPackExpansionBefore(const PackExpansionType *T, 1061 raw_ostream &OS) { 1062 printBefore(T->getPattern(), OS); 1063} 1064void TypePrinter::printPackExpansionAfter(const PackExpansionType *T, 1065 raw_ostream &OS) { 1066 printAfter(T->getPattern(), OS); 1067 OS << "..."; 1068} 1069 1070void TypePrinter::printAttributedBefore(const AttributedType *T, 1071 raw_ostream &OS) { 1072 // Prefer the macro forms of the GC and ownership qualifiers. 1073 if (T->getAttrKind() == AttributedType::attr_objc_gc || 1074 T->getAttrKind() == AttributedType::attr_objc_ownership) 1075 return printBefore(T->getEquivalentType(), OS); 1076 1077 printBefore(T->getModifiedType(), OS); 1078} 1079 1080void TypePrinter::printAttributedAfter(const AttributedType *T, 1081 raw_ostream &OS) { 1082 // Prefer the macro forms of the GC and ownership qualifiers. 1083 if (T->getAttrKind() == AttributedType::attr_objc_gc || 1084 T->getAttrKind() == AttributedType::attr_objc_ownership) 1085 return printAfter(T->getEquivalentType(), OS); 1086 1087 // TODO: not all attributes are GCC-style attributes. 1088 OS << " __attribute__(("; 1089 switch (T->getAttrKind()) { 1090 case AttributedType::attr_address_space: 1091 OS << "address_space("; 1092 OS << T->getEquivalentType().getAddressSpace(); 1093 OS << ')'; 1094 break; 1095 1096 case AttributedType::attr_vector_size: { 1097 OS << "__vector_size__("; 1098 if (const VectorType *vector =T->getEquivalentType()->getAs<VectorType>()) { 1099 OS << vector->getNumElements(); 1100 OS << " * sizeof("; 1101 print(vector->getElementType(), OS, StringRef()); 1102 OS << ')'; 1103 } 1104 OS << ')'; 1105 break; 1106 } 1107 1108 case AttributedType::attr_neon_vector_type: 1109 case AttributedType::attr_neon_polyvector_type: { 1110 if (T->getAttrKind() == AttributedType::attr_neon_vector_type) 1111 OS << "neon_vector_type("; 1112 else 1113 OS << "neon_polyvector_type("; 1114 const VectorType *vector = T->getEquivalentType()->getAs<VectorType>(); 1115 OS << vector->getNumElements(); 1116 OS << ')'; 1117 break; 1118 } 1119 1120 case AttributedType::attr_regparm: { 1121 OS << "regparm("; 1122 QualType t = T->getEquivalentType(); 1123 while (!t->isFunctionType()) 1124 t = t->getPointeeType(); 1125 OS << t->getAs<FunctionType>()->getRegParmType(); 1126 OS << ')'; 1127 break; 1128 } 1129 1130 case AttributedType::attr_objc_gc: { 1131 OS << "objc_gc("; 1132 1133 QualType tmp = T->getEquivalentType(); 1134 while (tmp.getObjCGCAttr() == Qualifiers::GCNone) { 1135 QualType next = tmp->getPointeeType(); 1136 if (next == tmp) break; 1137 tmp = next; 1138 } 1139 1140 if (tmp.isObjCGCWeak()) 1141 OS << "weak"; 1142 else 1143 OS << "strong"; 1144 OS << ')'; 1145 break; 1146 } 1147 1148 case AttributedType::attr_objc_ownership: 1149 OS << "objc_ownership("; 1150 switch (T->getEquivalentType().getObjCLifetime()) { 1151 case Qualifiers::OCL_None: llvm_unreachable("no ownership!"); 1152 case Qualifiers::OCL_ExplicitNone: OS << "none"; break; 1153 case Qualifiers::OCL_Strong: OS << "strong"; break; 1154 case Qualifiers::OCL_Weak: OS << "weak"; break; 1155 case Qualifiers::OCL_Autoreleasing: OS << "autoreleasing"; break; 1156 } 1157 OS << ')'; 1158 break; 1159 1160 case AttributedType::attr_noreturn: OS << "noreturn"; break; 1161 case AttributedType::attr_cdecl: OS << "cdecl"; break; 1162 case AttributedType::attr_coldcc: OS << "coldcc"; break; 1163 case AttributedType::attr_fastcall: OS << "fastcall"; break; 1164 case AttributedType::attr_stdcall: OS << "stdcall"; break; 1165 case AttributedType::attr_thiscall: OS << "thiscall"; break; 1166 case AttributedType::attr_pascal: OS << "pascal"; break; 1167 case AttributedType::attr_pcs: { 1168 OS << "pcs("; 1169 QualType t = T->getEquivalentType(); 1170 while (!t->isFunctionType()) 1171 t = t->getPointeeType(); 1172 OS << (t->getAs<FunctionType>()->getCallConv() == CC_AAPCS ? 1173 "\"aapcs\"" : "\"aapcs-vfp\""); 1174 OS << ')'; 1175 break; 1176 } 1177 case AttributedType::attr_pnaclcall: OS << "pnaclcall"; break; 1178 case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break; 1179 } 1180 OS << "))"; 1181} 1182 1183void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T, 1184 raw_ostream &OS) { 1185 OS << T->getDecl()->getName(); 1186 spaceBeforePlaceHolder(OS); 1187} 1188void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T, 1189 raw_ostream &OS) { } 1190 1191void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T, 1192 raw_ostream &OS) { 1193 if (T->qual_empty()) 1194 return printBefore(T->getBaseType(), OS); 1195 1196 print(T->getBaseType(), OS, StringRef()); 1197 OS << '<'; 1198 bool isFirst = true; 1199 for (ObjCObjectType::qual_iterator 1200 I = T->qual_begin(), E = T->qual_end(); I != E; ++I) { 1201 if (isFirst) 1202 isFirst = false; 1203 else 1204 OS << ','; 1205 OS << (*I)->getName(); 1206 } 1207 OS << '>'; 1208 spaceBeforePlaceHolder(OS); 1209} 1210void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T, 1211 raw_ostream &OS) { 1212 if (T->qual_empty()) 1213 return printAfter(T->getBaseType(), OS); 1214} 1215 1216void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T, 1217 raw_ostream &OS) { 1218 T->getPointeeType().getLocalQualifiers().print(OS, Policy, 1219 /*appendSpaceIfNonEmpty=*/true); 1220 1221 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) 1222 OS << "id"; 1223 else if (T->isObjCClassType() || T->isObjCQualifiedClassType()) 1224 OS << "Class"; 1225 else if (T->isObjCSelType()) 1226 OS << "SEL"; 1227 else 1228 OS << T->getInterfaceDecl()->getName(); 1229 1230 if (!T->qual_empty()) { 1231 OS << '<'; 1232 for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(), 1233 E = T->qual_end(); 1234 I != E; ++I) { 1235 OS << (*I)->getName(); 1236 if (I+1 != E) 1237 OS << ','; 1238 } 1239 OS << '>'; 1240 } 1241 1242 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType()) { 1243 OS << " *"; // Don't forget the implicit pointer. 1244 } else { 1245 spaceBeforePlaceHolder(OS); 1246 } 1247} 1248void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T, 1249 raw_ostream &OS) { } 1250 1251void TemplateSpecializationType:: 1252 PrintTemplateArgumentList(raw_ostream &OS, 1253 const TemplateArgumentListInfo &Args, 1254 const PrintingPolicy &Policy) { 1255 return PrintTemplateArgumentList(OS, 1256 Args.getArgumentArray(), 1257 Args.size(), 1258 Policy); 1259} 1260 1261void 1262TemplateSpecializationType::PrintTemplateArgumentList( 1263 raw_ostream &OS, 1264 const TemplateArgument *Args, 1265 unsigned NumArgs, 1266 const PrintingPolicy &Policy, 1267 bool SkipBrackets) { 1268 if (!SkipBrackets) 1269 OS << '<'; 1270 1271 bool needSpace = false; 1272 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 1273 if (Arg > 0) 1274 OS << ", "; 1275 1276 // Print the argument into a string. 1277 SmallString<128> Buf; 1278 llvm::raw_svector_ostream ArgOS(Buf); 1279 if (Args[Arg].getKind() == TemplateArgument::Pack) { 1280 PrintTemplateArgumentList(ArgOS, 1281 Args[Arg].pack_begin(), 1282 Args[Arg].pack_size(), 1283 Policy, true); 1284 } else { 1285 Args[Arg].print(Policy, ArgOS); 1286 } 1287 StringRef ArgString = ArgOS.str(); 1288 1289 // If this is the first argument and its string representation 1290 // begins with the global scope specifier ('::foo'), add a space 1291 // to avoid printing the diagraph '<:'. 1292 if (!Arg && !ArgString.empty() && ArgString[0] == ':') 1293 OS << ' '; 1294 1295 OS << ArgString; 1296 1297 needSpace = (!ArgString.empty() && ArgString.back() == '>'); 1298 } 1299 1300 // If the last character of our string is '>', add another space to 1301 // keep the two '>''s separate tokens. We don't *have* to do this in 1302 // C++0x, but it's still good hygiene. 1303 if (needSpace) 1304 OS << ' '; 1305 1306 if (!SkipBrackets) 1307 OS << '>'; 1308} 1309 1310// Sadly, repeat all that with TemplateArgLoc. 1311void TemplateSpecializationType:: 1312PrintTemplateArgumentList(raw_ostream &OS, 1313 const TemplateArgumentLoc *Args, unsigned NumArgs, 1314 const PrintingPolicy &Policy) { 1315 OS << '<'; 1316 1317 bool needSpace = false; 1318 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 1319 if (Arg > 0) 1320 OS << ", "; 1321 1322 // Print the argument into a string. 1323 SmallString<128> Buf; 1324 llvm::raw_svector_ostream ArgOS(Buf); 1325 if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) { 1326 PrintTemplateArgumentList(ArgOS, 1327 Args[Arg].getArgument().pack_begin(), 1328 Args[Arg].getArgument().pack_size(), 1329 Policy, true); 1330 } else { 1331 Args[Arg].getArgument().print(Policy, ArgOS); 1332 } 1333 StringRef ArgString = ArgOS.str(); 1334 1335 // If this is the first argument and its string representation 1336 // begins with the global scope specifier ('::foo'), add a space 1337 // to avoid printing the diagraph '<:'. 1338 if (!Arg && !ArgString.empty() && ArgString[0] == ':') 1339 OS << ' '; 1340 1341 OS << ArgString; 1342 1343 needSpace = (!ArgString.empty() && ArgString.back() == '>'); 1344 } 1345 1346 // If the last character of our string is '>', add another space to 1347 // keep the two '>''s separate tokens. We don't *have* to do this in 1348 // C++0x, but it's still good hygiene. 1349 if (needSpace) 1350 OS << ' '; 1351 1352 OS << '>'; 1353} 1354 1355void QualType::dump(const char *msg) const { 1356 if (msg) 1357 llvm::errs() << msg << ": "; 1358 LangOptions LO; 1359 print(llvm::errs(), PrintingPolicy(LO), "identifier"); 1360 llvm::errs() << '\n'; 1361} 1362void QualType::dump() const { 1363 dump(0); 1364} 1365 1366void Type::dump() const { 1367 QualType(this, 0).dump(); 1368} 1369 1370std::string Qualifiers::getAsString() const { 1371 LangOptions LO; 1372 return getAsString(PrintingPolicy(LO)); 1373} 1374 1375// Appends qualifiers to the given string, separated by spaces. Will 1376// prefix a space if the string is non-empty. Will not append a final 1377// space. 1378std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const { 1379 SmallString<64> Buf; 1380 llvm::raw_svector_ostream StrOS(Buf); 1381 print(StrOS, Policy); 1382 return StrOS.str(); 1383} 1384 1385bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const { 1386 if (getCVRQualifiers()) 1387 return false; 1388 1389 if (getAddressSpace()) 1390 return false; 1391 1392 if (getObjCGCAttr()) 1393 return false; 1394 1395 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) 1396 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)) 1397 return false; 1398 1399 return true; 1400} 1401 1402// Appends qualifiers to the given string, separated by spaces. Will 1403// prefix a space if the string is non-empty. Will not append a final 1404// space. 1405void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy, 1406 bool appendSpaceIfNonEmpty) const { 1407 bool addSpace = false; 1408 1409 unsigned quals = getCVRQualifiers(); 1410 if (quals) { 1411 AppendTypeQualList(OS, quals); 1412 addSpace = true; 1413 } 1414 if (unsigned addrspace = getAddressSpace()) { 1415 if (addSpace) 1416 OS << ' '; 1417 addSpace = true; 1418 switch (addrspace) { 1419 case LangAS::opencl_global: 1420 OS << "__global"; 1421 break; 1422 case LangAS::opencl_local: 1423 OS << "__local"; 1424 break; 1425 case LangAS::opencl_constant: 1426 OS << "__constant"; 1427 break; 1428 default: 1429 OS << "__attribute__((address_space("; 1430 OS << addrspace; 1431 OS << ")))"; 1432 } 1433 } 1434 if (Qualifiers::GC gc = getObjCGCAttr()) { 1435 if (addSpace) 1436 OS << ' '; 1437 addSpace = true; 1438 if (gc == Qualifiers::Weak) 1439 OS << "__weak"; 1440 else 1441 OS << "__strong"; 1442 } 1443 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) { 1444 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){ 1445 if (addSpace) 1446 OS << ' '; 1447 addSpace = true; 1448 } 1449 1450 switch (lifetime) { 1451 case Qualifiers::OCL_None: llvm_unreachable("none but true"); 1452 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break; 1453 case Qualifiers::OCL_Strong: 1454 if (!Policy.SuppressStrongLifetime) 1455 OS << "__strong"; 1456 break; 1457 1458 case Qualifiers::OCL_Weak: OS << "__weak"; break; 1459 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break; 1460 } 1461 } 1462 1463 if (appendSpaceIfNonEmpty && addSpace) 1464 OS << ' '; 1465} 1466 1467std::string QualType::getAsString(const PrintingPolicy &Policy) const { 1468 std::string S; 1469 getAsStringInternal(S, Policy); 1470 return S; 1471} 1472 1473std::string QualType::getAsString(const Type *ty, Qualifiers qs) { 1474 std::string buffer; 1475 LangOptions options; 1476 getAsStringInternal(ty, qs, buffer, PrintingPolicy(options)); 1477 return buffer; 1478} 1479 1480void QualType::print(const Type *ty, Qualifiers qs, 1481 raw_ostream &OS, const PrintingPolicy &policy, 1482 const Twine &PlaceHolder) { 1483 SmallString<128> PHBuf; 1484 StringRef PH = PlaceHolder.toStringRef(PHBuf); 1485 1486 TypePrinter(policy).print(ty, qs, OS, PH); 1487} 1488 1489void QualType::getAsStringInternal(const Type *ty, Qualifiers qs, 1490 std::string &buffer, 1491 const PrintingPolicy &policy) { 1492 SmallString<256> Buf; 1493 llvm::raw_svector_ostream StrOS(Buf); 1494 TypePrinter(policy).print(ty, qs, StrOS, buffer); 1495 std::string str = StrOS.str(); 1496 buffer.swap(str); 1497} 1498