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