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