TypePrinter.cpp revision 263508
1251876Speter//===--- TypePrinter.cpp - Pretty-Print Clang Types -----------------------===// 2251876Speter// 3251876Speter// The LLVM Compiler Infrastructure 4251876Speter// 5251876Speter// This file is distributed under the University of Illinois Open Source 6251876Speter// License. See LICENSE.TXT for details. 7251876Speter// 8251876Speter//===----------------------------------------------------------------------===// 9251876Speter// 10251876Speter// This contains code to print types from Clang's type system. 11251876Speter// 12251876Speter//===----------------------------------------------------------------------===// 13251876Speter 14251876Speter#include "clang/AST/PrettyPrinter.h" 15251876Speter#include "clang/AST/ASTContext.h" 16251876Speter#include "clang/AST/Decl.h" 17251876Speter#include "clang/AST/DeclObjC.h" 18251876Speter#include "clang/AST/DeclTemplate.h" 19251876Speter#include "clang/AST/Expr.h" 20251876Speter#include "clang/AST/Type.h" 21251876Speter#include "clang/Basic/LangOptions.h" 22251876Speter#include "clang/Basic/SourceManager.h" 23251876Speter#include "llvm/ADT/SmallString.h" 24251876Speter#include "llvm/ADT/StringExtras.h" 25258602Speter#include "llvm/Support/SaveAndRestore.h" 26251876Speter#include "llvm/Support/raw_ostream.h" 27251876Speterusing namespace clang; 28251876Speter 29251876Speternamespace { 30251876Speter /// \brief RAII object that enables printing of the ARC __strong lifetime 31251876Speter /// qualifier. 32251876Speter class IncludeStrongLifetimeRAII { 33251876Speter PrintingPolicy &Policy; 34251876Speter bool Old; 35251876Speter 36251876Speter public: 37251876Speter explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy) 38251876Speter : Policy(Policy), Old(Policy.SuppressStrongLifetime) { 39251876Speter if (!Policy.SuppressLifetimeQualifiers) 40251876Speter Policy.SuppressStrongLifetime = false; 41251876Speter } 42251876Speter 43251876Speter ~IncludeStrongLifetimeRAII() { 44251876Speter Policy.SuppressStrongLifetime = Old; 45251876Speter } 46251876Speter }; 47251876Speter 48251876Speter class ParamPolicyRAII { 49251876Speter PrintingPolicy &Policy; 50251876Speter bool Old; 51251876Speter 52251876Speter public: 53251876Speter explicit ParamPolicyRAII(PrintingPolicy &Policy) 54251876Speter : Policy(Policy), Old(Policy.SuppressSpecifiers) { 55251876Speter Policy.SuppressSpecifiers = false; 56251876Speter } 57251876Speter 58251876Speter ~ParamPolicyRAII() { 59251876Speter Policy.SuppressSpecifiers = Old; 60251876Speter } 61251876Speter }; 62251876Speter 63251876Speter class ElaboratedTypePolicyRAII { 64251876Speter PrintingPolicy &Policy; 65251876Speter bool SuppressTagKeyword; 66251876Speter bool SuppressScope; 67251876Speter 68251876Speter public: 69251876Speter explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) { 70251876Speter SuppressTagKeyword = Policy.SuppressTagKeyword; 71251876Speter SuppressScope = Policy.SuppressScope; 72251876Speter Policy.SuppressTagKeyword = true; 73251876Speter Policy.SuppressScope = true; 74251876Speter } 75251876Speter 76251876Speter ~ElaboratedTypePolicyRAII() { 77251876Speter Policy.SuppressTagKeyword = SuppressTagKeyword; 78251876Speter Policy.SuppressScope = SuppressScope; 79251876Speter } 80251876Speter }; 81251876Speter 82251876Speter class TypePrinter { 83251876Speter PrintingPolicy Policy; 84251876Speter bool HasEmptyPlaceHolder; 85251876Speter bool InsideCCAttribute; 86251876Speter 87251876Speter public: 88251876Speter explicit TypePrinter(const PrintingPolicy &Policy) 89251876Speter : Policy(Policy), HasEmptyPlaceHolder(false), InsideCCAttribute(false) { } 90251876Speter 91251876Speter void print(const Type *ty, Qualifiers qs, raw_ostream &OS, 92251876Speter StringRef PlaceHolder); 93251876Speter void print(QualType T, raw_ostream &OS, StringRef PlaceHolder); 94251876Speter 95251876Speter static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier); 96251876Speter void spaceBeforePlaceHolder(raw_ostream &OS); 97251876Speter void printTypeSpec(const NamedDecl *D, raw_ostream &OS); 98251876Speter 99251876Speter void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS); 100251876Speter void printBefore(QualType T, raw_ostream &OS); 101253734Speter void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS); 102251876Speter void printAfter(QualType T, raw_ostream &OS); 103251876Speter void AppendScope(DeclContext *DC, raw_ostream &OS); 104251876Speter void printTag(TagDecl *T, raw_ostream &OS); 105251876Speter#define ABSTRACT_TYPE(CLASS, PARENT) 106251876Speter#define TYPE(CLASS, PARENT) \ 107251876Speter void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \ 108251876Speter void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS); 109251876Speter#include "clang/AST/TypeNodes.def" 110251876Speter }; 111251876Speter} 112251876Speter 113251876Speterstatic void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals) { 114251876Speter bool appendSpace = false; 115251876Speter if (TypeQuals & Qualifiers::Const) { 116251876Speter OS << "const"; 117251876Speter appendSpace = true; 118251876Speter } 119251876Speter if (TypeQuals & Qualifiers::Volatile) { 120251876Speter if (appendSpace) OS << ' '; 121251876Speter OS << "volatile"; 122251876Speter appendSpace = true; 123251876Speter } 124251876Speter if (TypeQuals & Qualifiers::Restrict) { 125251876Speter if (appendSpace) OS << ' '; 126251876Speter OS << "restrict"; 127251876Speter } 128251876Speter} 129251876Speter 130251876Spetervoid TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) { 131251876Speter if (!HasEmptyPlaceHolder) 132251876Speter OS << ' '; 133251876Speter} 134251876Speter 135251876Spetervoid TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) { 136251876Speter SplitQualType split = t.split(); 137251876Speter print(split.Ty, split.Quals, OS, PlaceHolder); 138251876Speter} 139 140void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS, 141 StringRef PlaceHolder) { 142 if (!T) { 143 OS << "NULL TYPE"; 144 return; 145 } 146 147 SaveAndRestore<bool> PHVal(HasEmptyPlaceHolder, PlaceHolder.empty()); 148 149 printBefore(T, Quals, OS); 150 OS << PlaceHolder; 151 printAfter(T, Quals, OS); 152} 153 154bool TypePrinter::canPrefixQualifiers(const Type *T, 155 bool &NeedARCStrongQualifier) { 156 // CanPrefixQualifiers - We prefer to print type qualifiers before the type, 157 // so that we get "const int" instead of "int const", but we can't do this if 158 // the type is complex. For example if the type is "int*", we *must* print 159 // "int * const", printing "const int *" is different. Only do this when the 160 // type expands to a simple string. 161 bool CanPrefixQualifiers = false; 162 NeedARCStrongQualifier = false; 163 Type::TypeClass TC = T->getTypeClass(); 164 if (const AutoType *AT = dyn_cast<AutoType>(T)) 165 TC = AT->desugar()->getTypeClass(); 166 if (const SubstTemplateTypeParmType *Subst 167 = dyn_cast<SubstTemplateTypeParmType>(T)) 168 TC = Subst->getReplacementType()->getTypeClass(); 169 170 switch (TC) { 171 case Type::Auto: 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::Decayed: 208 case Type::Pointer: 209 case Type::BlockPointer: 210 case Type::LValueReference: 211 case Type::RValueReference: 212 case Type::MemberPointer: 213 case Type::DependentSizedExtVector: 214 case Type::Vector: 215 case Type::ExtVector: 216 case Type::FunctionProto: 217 case Type::FunctionNoProto: 218 case Type::Paren: 219 case Type::Attributed: 220 case Type::PackExpansion: 221 case Type::SubstTemplateTypeParm: 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::printDecayedBefore(const DecayedType *T, raw_ostream &OS) { 475 // Print as though it's a pointer. 476 printBefore(T->getDecayedType(), OS); 477} 478void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) { 479 printAfter(T->getDecayedType(), OS); 480} 481 482void TypePrinter::printDependentSizedArrayBefore( 483 const DependentSizedArrayType *T, 484 raw_ostream &OS) { 485 IncludeStrongLifetimeRAII Strong(Policy); 486 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 487 printBefore(T->getElementType(), OS); 488} 489void TypePrinter::printDependentSizedArrayAfter( 490 const DependentSizedArrayType *T, 491 raw_ostream &OS) { 492 OS << '['; 493 if (T->getSizeExpr()) 494 T->getSizeExpr()->printPretty(OS, 0, Policy); 495 OS << ']'; 496 printAfter(T->getElementType(), OS); 497} 498 499void TypePrinter::printDependentSizedExtVectorBefore( 500 const DependentSizedExtVectorType *T, 501 raw_ostream &OS) { 502 printBefore(T->getElementType(), OS); 503} 504void TypePrinter::printDependentSizedExtVectorAfter( 505 const DependentSizedExtVectorType *T, 506 raw_ostream &OS) { 507 OS << " __attribute__((ext_vector_type("; 508 if (T->getSizeExpr()) 509 T->getSizeExpr()->printPretty(OS, 0, Policy); 510 OS << ")))"; 511 printAfter(T->getElementType(), OS); 512} 513 514void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) { 515 switch (T->getVectorKind()) { 516 case VectorType::AltiVecPixel: 517 OS << "__vector __pixel "; 518 break; 519 case VectorType::AltiVecBool: 520 OS << "__vector __bool "; 521 printBefore(T->getElementType(), OS); 522 break; 523 case VectorType::AltiVecVector: 524 OS << "__vector "; 525 printBefore(T->getElementType(), OS); 526 break; 527 case VectorType::NeonVector: 528 OS << "__attribute__((neon_vector_type(" 529 << T->getNumElements() << "))) "; 530 printBefore(T->getElementType(), OS); 531 break; 532 case VectorType::NeonPolyVector: 533 OS << "__attribute__((neon_polyvector_type(" << 534 T->getNumElements() << "))) "; 535 printBefore(T->getElementType(), OS); 536 break; 537 case VectorType::GenericVector: { 538 // FIXME: We prefer to print the size directly here, but have no way 539 // to get the size of the type. 540 OS << "__attribute__((__vector_size__(" 541 << T->getNumElements() 542 << " * sizeof("; 543 print(T->getElementType(), OS, StringRef()); 544 OS << ")))) "; 545 printBefore(T->getElementType(), OS); 546 break; 547 } 548 } 549} 550void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) { 551 printAfter(T->getElementType(), OS); 552} 553 554void TypePrinter::printExtVectorBefore(const ExtVectorType *T, 555 raw_ostream &OS) { 556 printBefore(T->getElementType(), OS); 557} 558void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) { 559 printAfter(T->getElementType(), OS); 560 OS << " __attribute__((ext_vector_type("; 561 OS << T->getNumElements(); 562 OS << ")))"; 563} 564 565void 566FunctionProtoType::printExceptionSpecification(raw_ostream &OS, 567 const PrintingPolicy &Policy) 568 const { 569 570 if (hasDynamicExceptionSpec()) { 571 OS << " throw("; 572 if (getExceptionSpecType() == EST_MSAny) 573 OS << "..."; 574 else 575 for (unsigned I = 0, N = getNumExceptions(); I != N; ++I) { 576 if (I) 577 OS << ", "; 578 579 OS << getExceptionType(I).stream(Policy); 580 } 581 OS << ')'; 582 } else if (isNoexceptExceptionSpec(getExceptionSpecType())) { 583 OS << " noexcept"; 584 if (getExceptionSpecType() == EST_ComputedNoexcept) { 585 OS << '('; 586 getNoexceptExpr()->printPretty(OS, 0, Policy); 587 OS << ')'; 588 } 589 } 590} 591 592void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T, 593 raw_ostream &OS) { 594 if (T->hasTrailingReturn()) { 595 OS << "auto "; 596 if (!HasEmptyPlaceHolder) 597 OS << '('; 598 } else { 599 // If needed for precedence reasons, wrap the inner part in grouping parens. 600 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false); 601 printBefore(T->getResultType(), OS); 602 if (!PrevPHIsEmpty.get()) 603 OS << '('; 604 } 605} 606 607void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, 608 raw_ostream &OS) { 609 // If needed for precedence reasons, wrap the inner part in grouping parens. 610 if (!HasEmptyPlaceHolder) 611 OS << ')'; 612 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 613 614 OS << '('; 615 { 616 ParamPolicyRAII ParamPolicy(Policy); 617 for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) { 618 if (i) OS << ", "; 619 print(T->getArgType(i), OS, StringRef()); 620 } 621 } 622 623 if (T->isVariadic()) { 624 if (T->getNumArgs()) 625 OS << ", "; 626 OS << "..."; 627 } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) { 628 // Do not emit int() if we have a proto, emit 'int(void)'. 629 OS << "void"; 630 } 631 632 OS << ')'; 633 634 FunctionType::ExtInfo Info = T->getExtInfo(); 635 636 if (!InsideCCAttribute) { 637 switch (Info.getCC()) { 638 case CC_C: 639 // The C calling convention is the default on the vast majority of platforms 640 // we support. If the user wrote it explicitly, it will usually be printed 641 // while traversing the AttributedType. If the type has been desugared, let 642 // the canonical spelling be the implicit calling convention. 643 // FIXME: It would be better to be explicit in certain contexts, such as a 644 // cdecl function typedef used to declare a member function with the 645 // Microsoft C++ ABI. 646 break; 647 case CC_X86StdCall: 648 OS << " __attribute__((stdcall))"; 649 break; 650 case CC_X86FastCall: 651 OS << " __attribute__((fastcall))"; 652 break; 653 case CC_X86ThisCall: 654 OS << " __attribute__((thiscall))"; 655 break; 656 case CC_X86Pascal: 657 OS << " __attribute__((pascal))"; 658 break; 659 case CC_AAPCS: 660 OS << " __attribute__((pcs(\"aapcs\")))"; 661 break; 662 case CC_AAPCS_VFP: 663 OS << " __attribute__((pcs(\"aapcs-vfp\")))"; 664 break; 665 case CC_PnaclCall: 666 OS << " __attribute__((pnaclcall))"; 667 break; 668 case CC_IntelOclBicc: 669 OS << " __attribute__((intel_ocl_bicc))"; 670 break; 671 case CC_X86_64Win64: 672 OS << " __attribute__((ms_abi))"; 673 break; 674 case CC_X86_64SysV: 675 OS << " __attribute__((sysv_abi))"; 676 break; 677 } 678 } 679 680 if (Info.getNoReturn()) 681 OS << " __attribute__((noreturn))"; 682 if (Info.getRegParm()) 683 OS << " __attribute__((regparm (" 684 << Info.getRegParm() << ")))"; 685 686 if (unsigned quals = T->getTypeQuals()) { 687 OS << ' '; 688 AppendTypeQualList(OS, quals); 689 } 690 691 switch (T->getRefQualifier()) { 692 case RQ_None: 693 break; 694 695 case RQ_LValue: 696 OS << " &"; 697 break; 698 699 case RQ_RValue: 700 OS << " &&"; 701 break; 702 } 703 T->printExceptionSpecification(OS, Policy); 704 705 if (T->hasTrailingReturn()) { 706 OS << " -> "; 707 print(T->getResultType(), OS, StringRef()); 708 } else 709 printAfter(T->getResultType(), OS); 710} 711 712void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T, 713 raw_ostream &OS) { 714 // If needed for precedence reasons, wrap the inner part in grouping parens. 715 SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false); 716 printBefore(T->getResultType(), OS); 717 if (!PrevPHIsEmpty.get()) 718 OS << '('; 719} 720void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T, 721 raw_ostream &OS) { 722 // If needed for precedence reasons, wrap the inner part in grouping parens. 723 if (!HasEmptyPlaceHolder) 724 OS << ')'; 725 SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false); 726 727 OS << "()"; 728 if (T->getNoReturnAttr()) 729 OS << " __attribute__((noreturn))"; 730 printAfter(T->getResultType(), OS); 731} 732 733void TypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) { 734 IdentifierInfo *II = D->getIdentifier(); 735 OS << II->getName(); 736 spaceBeforePlaceHolder(OS); 737} 738 739void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T, 740 raw_ostream &OS) { 741 printTypeSpec(T->getDecl(), OS); 742} 743void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T, 744 raw_ostream &OS) { } 745 746void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) { 747 printTypeSpec(T->getDecl(), OS); 748} 749void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) { } 750 751void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T, 752 raw_ostream &OS) { 753 OS << "typeof "; 754 T->getUnderlyingExpr()->printPretty(OS, 0, Policy); 755 spaceBeforePlaceHolder(OS); 756} 757void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T, 758 raw_ostream &OS) { } 759 760void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) { 761 OS << "typeof("; 762 print(T->getUnderlyingType(), OS, StringRef()); 763 OS << ')'; 764 spaceBeforePlaceHolder(OS); 765} 766void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) { } 767 768void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) { 769 OS << "decltype("; 770 T->getUnderlyingExpr()->printPretty(OS, 0, Policy); 771 OS << ')'; 772 spaceBeforePlaceHolder(OS); 773} 774void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) { } 775 776void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T, 777 raw_ostream &OS) { 778 IncludeStrongLifetimeRAII Strong(Policy); 779 780 switch (T->getUTTKind()) { 781 case UnaryTransformType::EnumUnderlyingType: 782 OS << "__underlying_type("; 783 print(T->getBaseType(), OS, StringRef()); 784 OS << ')'; 785 spaceBeforePlaceHolder(OS); 786 return; 787 } 788 789 printBefore(T->getBaseType(), OS); 790} 791void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T, 792 raw_ostream &OS) { 793 IncludeStrongLifetimeRAII Strong(Policy); 794 795 switch (T->getUTTKind()) { 796 case UnaryTransformType::EnumUnderlyingType: 797 return; 798 } 799 800 printAfter(T->getBaseType(), OS); 801} 802 803void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) { 804 // If the type has been deduced, do not print 'auto'. 805 if (!T->getDeducedType().isNull()) { 806 printBefore(T->getDeducedType(), OS); 807 } else { 808 OS << (T->isDecltypeAuto() ? "decltype(auto)" : "auto"); 809 spaceBeforePlaceHolder(OS); 810 } 811} 812void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) { 813 // If the type has been deduced, do not print 'auto'. 814 if (!T->getDeducedType().isNull()) 815 printAfter(T->getDeducedType(), OS); 816} 817 818void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) { 819 IncludeStrongLifetimeRAII Strong(Policy); 820 821 OS << "_Atomic("; 822 print(T->getValueType(), OS, StringRef()); 823 OS << ')'; 824 spaceBeforePlaceHolder(OS); 825} 826void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) { } 827 828/// Appends the given scope to the end of a string. 829void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) { 830 if (DC->isTranslationUnit()) return; 831 if (DC->isFunctionOrMethod()) return; 832 AppendScope(DC->getParent(), OS); 833 834 if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { 835 if (Policy.SuppressUnwrittenScope && 836 (NS->isAnonymousNamespace() || NS->isInline())) 837 return; 838 if (NS->getIdentifier()) 839 OS << NS->getName() << "::"; 840 else 841 OS << "<anonymous>::"; 842 } else if (ClassTemplateSpecializationDecl *Spec 843 = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { 844 IncludeStrongLifetimeRAII Strong(Policy); 845 OS << Spec->getIdentifier()->getName(); 846 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 847 TemplateSpecializationType::PrintTemplateArgumentList(OS, 848 TemplateArgs.data(), 849 TemplateArgs.size(), 850 Policy); 851 OS << "::"; 852 } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { 853 if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl()) 854 OS << Typedef->getIdentifier()->getName() << "::"; 855 else if (Tag->getIdentifier()) 856 OS << Tag->getIdentifier()->getName() << "::"; 857 else 858 return; 859 } 860} 861 862void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) { 863 if (Policy.SuppressTag) 864 return; 865 866 bool HasKindDecoration = false; 867 868 // bool SuppressTagKeyword 869 // = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword; 870 871 // We don't print tags unless this is an elaborated type. 872 // In C, we just assume every RecordType is an elaborated type. 873 if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword || 874 D->getTypedefNameForAnonDecl())) { 875 HasKindDecoration = true; 876 OS << D->getKindName(); 877 OS << ' '; 878 } 879 880 // Compute the full nested-name-specifier for this type. 881 // In C, this will always be empty except when the type 882 // being printed is anonymous within other Record. 883 if (!Policy.SuppressScope) 884 AppendScope(D->getDeclContext(), OS); 885 886 if (const IdentifierInfo *II = D->getIdentifier()) 887 OS << II->getName(); 888 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) { 889 assert(Typedef->getIdentifier() && "Typedef without identifier?"); 890 OS << Typedef->getIdentifier()->getName(); 891 } else { 892 // Make an unambiguous representation for anonymous types, e.g. 893 // <anonymous enum at /usr/include/string.h:120:9> 894 895 if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) { 896 OS << "<lambda"; 897 HasKindDecoration = true; 898 } else { 899 OS << "<anonymous"; 900 } 901 902 if (Policy.AnonymousTagLocations) { 903 // Suppress the redundant tag keyword if we just printed one. 904 // We don't have to worry about ElaboratedTypes here because you can't 905 // refer to an anonymous type with one. 906 if (!HasKindDecoration) 907 OS << " " << D->getKindName(); 908 909 PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc( 910 D->getLocation()); 911 if (PLoc.isValid()) { 912 OS << " at " << PLoc.getFilename() 913 << ':' << PLoc.getLine() 914 << ':' << PLoc.getColumn(); 915 } 916 } 917 918 OS << '>'; 919 } 920 921 // If this is a class template specialization, print the template 922 // arguments. 923 if (ClassTemplateSpecializationDecl *Spec 924 = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 925 const TemplateArgument *Args; 926 unsigned NumArgs; 927 if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { 928 const TemplateSpecializationType *TST = 929 cast<TemplateSpecializationType>(TAW->getType()); 930 Args = TST->getArgs(); 931 NumArgs = TST->getNumArgs(); 932 } else { 933 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 934 Args = TemplateArgs.data(); 935 NumArgs = TemplateArgs.size(); 936 } 937 IncludeStrongLifetimeRAII Strong(Policy); 938 TemplateSpecializationType::PrintTemplateArgumentList(OS, 939 Args, NumArgs, 940 Policy); 941 } 942 943 spaceBeforePlaceHolder(OS); 944} 945 946void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) { 947 printTag(T->getDecl(), OS); 948} 949void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) { } 950 951void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) { 952 printTag(T->getDecl(), OS); 953} 954void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) { } 955 956void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T, 957 raw_ostream &OS) { 958 if (IdentifierInfo *Id = T->getIdentifier()) 959 OS << Id->getName(); 960 else 961 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex(); 962 spaceBeforePlaceHolder(OS); 963} 964void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T, 965 raw_ostream &OS) { } 966 967void TypePrinter::printSubstTemplateTypeParmBefore( 968 const SubstTemplateTypeParmType *T, 969 raw_ostream &OS) { 970 IncludeStrongLifetimeRAII Strong(Policy); 971 printBefore(T->getReplacementType(), OS); 972} 973void TypePrinter::printSubstTemplateTypeParmAfter( 974 const SubstTemplateTypeParmType *T, 975 raw_ostream &OS) { 976 IncludeStrongLifetimeRAII Strong(Policy); 977 printAfter(T->getReplacementType(), OS); 978} 979 980void TypePrinter::printSubstTemplateTypeParmPackBefore( 981 const SubstTemplateTypeParmPackType *T, 982 raw_ostream &OS) { 983 IncludeStrongLifetimeRAII Strong(Policy); 984 printTemplateTypeParmBefore(T->getReplacedParameter(), OS); 985} 986void TypePrinter::printSubstTemplateTypeParmPackAfter( 987 const SubstTemplateTypeParmPackType *T, 988 raw_ostream &OS) { 989 IncludeStrongLifetimeRAII Strong(Policy); 990 printTemplateTypeParmAfter(T->getReplacedParameter(), OS); 991} 992 993void TypePrinter::printTemplateSpecializationBefore( 994 const TemplateSpecializationType *T, 995 raw_ostream &OS) { 996 IncludeStrongLifetimeRAII Strong(Policy); 997 T->getTemplateName().print(OS, Policy); 998 999 TemplateSpecializationType::PrintTemplateArgumentList(OS, 1000 T->getArgs(), 1001 T->getNumArgs(), 1002 Policy); 1003 spaceBeforePlaceHolder(OS); 1004} 1005void TypePrinter::printTemplateSpecializationAfter( 1006 const TemplateSpecializationType *T, 1007 raw_ostream &OS) { } 1008 1009void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T, 1010 raw_ostream &OS) { 1011 printTemplateSpecializationBefore(T->getInjectedTST(), OS); 1012} 1013void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T, 1014 raw_ostream &OS) { } 1015 1016void TypePrinter::printElaboratedBefore(const ElaboratedType *T, 1017 raw_ostream &OS) { 1018 if (Policy.SuppressTag && isa<TagType>(T->getNamedType())) 1019 return; 1020 OS << TypeWithKeyword::getKeywordName(T->getKeyword()); 1021 if (T->getKeyword() != ETK_None) 1022 OS << " "; 1023 NestedNameSpecifier* Qualifier = T->getQualifier(); 1024 if (Qualifier) 1025 Qualifier->print(OS, Policy); 1026 1027 ElaboratedTypePolicyRAII PolicyRAII(Policy); 1028 printBefore(T->getNamedType(), OS); 1029} 1030void TypePrinter::printElaboratedAfter(const ElaboratedType *T, 1031 raw_ostream &OS) { 1032 ElaboratedTypePolicyRAII PolicyRAII(Policy); 1033 printAfter(T->getNamedType(), OS); 1034} 1035 1036void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) { 1037 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) { 1038 printBefore(T->getInnerType(), OS); 1039 OS << '('; 1040 } else 1041 printBefore(T->getInnerType(), OS); 1042} 1043void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) { 1044 if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) { 1045 OS << ')'; 1046 printAfter(T->getInnerType(), OS); 1047 } else 1048 printAfter(T->getInnerType(), OS); 1049} 1050 1051void TypePrinter::printDependentNameBefore(const DependentNameType *T, 1052 raw_ostream &OS) { 1053 OS << TypeWithKeyword::getKeywordName(T->getKeyword()); 1054 if (T->getKeyword() != ETK_None) 1055 OS << " "; 1056 1057 T->getQualifier()->print(OS, Policy); 1058 1059 OS << T->getIdentifier()->getName(); 1060 spaceBeforePlaceHolder(OS); 1061} 1062void TypePrinter::printDependentNameAfter(const DependentNameType *T, 1063 raw_ostream &OS) { } 1064 1065void TypePrinter::printDependentTemplateSpecializationBefore( 1066 const DependentTemplateSpecializationType *T, raw_ostream &OS) { 1067 IncludeStrongLifetimeRAII Strong(Policy); 1068 1069 OS << TypeWithKeyword::getKeywordName(T->getKeyword()); 1070 if (T->getKeyword() != ETK_None) 1071 OS << " "; 1072 1073 if (T->getQualifier()) 1074 T->getQualifier()->print(OS, Policy); 1075 OS << T->getIdentifier()->getName(); 1076 TemplateSpecializationType::PrintTemplateArgumentList(OS, 1077 T->getArgs(), 1078 T->getNumArgs(), 1079 Policy); 1080 spaceBeforePlaceHolder(OS); 1081} 1082void TypePrinter::printDependentTemplateSpecializationAfter( 1083 const DependentTemplateSpecializationType *T, raw_ostream &OS) { } 1084 1085void TypePrinter::printPackExpansionBefore(const PackExpansionType *T, 1086 raw_ostream &OS) { 1087 printBefore(T->getPattern(), OS); 1088} 1089void TypePrinter::printPackExpansionAfter(const PackExpansionType *T, 1090 raw_ostream &OS) { 1091 printAfter(T->getPattern(), OS); 1092 OS << "..."; 1093} 1094 1095void TypePrinter::printAttributedBefore(const AttributedType *T, 1096 raw_ostream &OS) { 1097 // Prefer the macro forms of the GC and ownership qualifiers. 1098 if (T->getAttrKind() == AttributedType::attr_objc_gc || 1099 T->getAttrKind() == AttributedType::attr_objc_ownership) 1100 return printBefore(T->getEquivalentType(), OS); 1101 1102 printBefore(T->getModifiedType(), OS); 1103 1104 if (T->isMSTypeSpec()) { 1105 switch (T->getAttrKind()) { 1106 default: return; 1107 case AttributedType::attr_ptr32: OS << " __ptr32"; break; 1108 case AttributedType::attr_ptr64: OS << " __ptr64"; break; 1109 case AttributedType::attr_sptr: OS << " __sptr"; break; 1110 case AttributedType::attr_uptr: OS << " __uptr"; break; 1111 } 1112 spaceBeforePlaceHolder(OS); 1113 } 1114} 1115 1116void TypePrinter::printAttributedAfter(const AttributedType *T, 1117 raw_ostream &OS) { 1118 // Prefer the macro forms of the GC and ownership qualifiers. 1119 if (T->getAttrKind() == AttributedType::attr_objc_gc || 1120 T->getAttrKind() == AttributedType::attr_objc_ownership) 1121 return printAfter(T->getEquivalentType(), OS); 1122 1123 // TODO: not all attributes are GCC-style attributes. 1124 if (T->isMSTypeSpec()) 1125 return; 1126 1127 // If this is a calling convention attribute, don't print the implicit CC from 1128 // the modified type. 1129 SaveAndRestore<bool> MaybeSuppressCC(InsideCCAttribute, T->isCallingConv()); 1130 1131 printAfter(T->getModifiedType(), OS); 1132 1133 OS << " __attribute__(("; 1134 switch (T->getAttrKind()) { 1135 default: llvm_unreachable("This attribute should have been handled already"); 1136 case AttributedType::attr_address_space: 1137 OS << "address_space("; 1138 OS << T->getEquivalentType().getAddressSpace(); 1139 OS << ')'; 1140 break; 1141 1142 case AttributedType::attr_vector_size: { 1143 OS << "__vector_size__("; 1144 if (const VectorType *vector =T->getEquivalentType()->getAs<VectorType>()) { 1145 OS << vector->getNumElements(); 1146 OS << " * sizeof("; 1147 print(vector->getElementType(), OS, StringRef()); 1148 OS << ')'; 1149 } 1150 OS << ')'; 1151 break; 1152 } 1153 1154 case AttributedType::attr_neon_vector_type: 1155 case AttributedType::attr_neon_polyvector_type: { 1156 if (T->getAttrKind() == AttributedType::attr_neon_vector_type) 1157 OS << "neon_vector_type("; 1158 else 1159 OS << "neon_polyvector_type("; 1160 const VectorType *vector = T->getEquivalentType()->getAs<VectorType>(); 1161 OS << vector->getNumElements(); 1162 OS << ')'; 1163 break; 1164 } 1165 1166 case AttributedType::attr_regparm: { 1167 // FIXME: When Sema learns to form this AttributedType, avoid printing the 1168 // attribute again in printFunctionProtoAfter. 1169 OS << "regparm("; 1170 QualType t = T->getEquivalentType(); 1171 while (!t->isFunctionType()) 1172 t = t->getPointeeType(); 1173 OS << t->getAs<FunctionType>()->getRegParmType(); 1174 OS << ')'; 1175 break; 1176 } 1177 1178 case AttributedType::attr_objc_gc: { 1179 OS << "objc_gc("; 1180 1181 QualType tmp = T->getEquivalentType(); 1182 while (tmp.getObjCGCAttr() == Qualifiers::GCNone) { 1183 QualType next = tmp->getPointeeType(); 1184 if (next == tmp) break; 1185 tmp = next; 1186 } 1187 1188 if (tmp.isObjCGCWeak()) 1189 OS << "weak"; 1190 else 1191 OS << "strong"; 1192 OS << ')'; 1193 break; 1194 } 1195 1196 case AttributedType::attr_objc_ownership: 1197 OS << "objc_ownership("; 1198 switch (T->getEquivalentType().getObjCLifetime()) { 1199 case Qualifiers::OCL_None: llvm_unreachable("no ownership!"); 1200 case Qualifiers::OCL_ExplicitNone: OS << "none"; break; 1201 case Qualifiers::OCL_Strong: OS << "strong"; break; 1202 case Qualifiers::OCL_Weak: OS << "weak"; break; 1203 case Qualifiers::OCL_Autoreleasing: OS << "autoreleasing"; break; 1204 } 1205 OS << ')'; 1206 break; 1207 1208 // FIXME: When Sema learns to form this AttributedType, avoid printing the 1209 // attribute again in printFunctionProtoAfter. 1210 case AttributedType::attr_noreturn: OS << "noreturn"; break; 1211 1212 case AttributedType::attr_cdecl: OS << "cdecl"; break; 1213 case AttributedType::attr_fastcall: OS << "fastcall"; break; 1214 case AttributedType::attr_stdcall: OS << "stdcall"; break; 1215 case AttributedType::attr_thiscall: OS << "thiscall"; break; 1216 case AttributedType::attr_pascal: OS << "pascal"; break; 1217 case AttributedType::attr_ms_abi: OS << "ms_abi"; break; 1218 case AttributedType::attr_sysv_abi: OS << "sysv_abi"; break; 1219 case AttributedType::attr_pcs: 1220 case AttributedType::attr_pcs_vfp: { 1221 OS << "pcs("; 1222 QualType t = T->getEquivalentType(); 1223 while (!t->isFunctionType()) 1224 t = t->getPointeeType(); 1225 OS << (t->getAs<FunctionType>()->getCallConv() == CC_AAPCS ? 1226 "\"aapcs\"" : "\"aapcs-vfp\""); 1227 OS << ')'; 1228 break; 1229 } 1230 case AttributedType::attr_pnaclcall: OS << "pnaclcall"; break; 1231 case AttributedType::attr_inteloclbicc: OS << "inteloclbicc"; break; 1232 } 1233 OS << "))"; 1234} 1235 1236void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T, 1237 raw_ostream &OS) { 1238 OS << T->getDecl()->getName(); 1239 spaceBeforePlaceHolder(OS); 1240} 1241void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T, 1242 raw_ostream &OS) { } 1243 1244void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T, 1245 raw_ostream &OS) { 1246 if (T->qual_empty()) 1247 return printBefore(T->getBaseType(), OS); 1248 1249 print(T->getBaseType(), OS, StringRef()); 1250 OS << '<'; 1251 bool isFirst = true; 1252 for (ObjCObjectType::qual_iterator 1253 I = T->qual_begin(), E = T->qual_end(); I != E; ++I) { 1254 if (isFirst) 1255 isFirst = false; 1256 else 1257 OS << ','; 1258 OS << (*I)->getName(); 1259 } 1260 OS << '>'; 1261 spaceBeforePlaceHolder(OS); 1262} 1263void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T, 1264 raw_ostream &OS) { 1265 if (T->qual_empty()) 1266 return printAfter(T->getBaseType(), OS); 1267} 1268 1269void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T, 1270 raw_ostream &OS) { 1271 T->getPointeeType().getLocalQualifiers().print(OS, Policy, 1272 /*appendSpaceIfNonEmpty=*/true); 1273 1274 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) 1275 OS << "id"; 1276 else if (T->isObjCClassType() || T->isObjCQualifiedClassType()) 1277 OS << "Class"; 1278 else if (T->isObjCSelType()) 1279 OS << "SEL"; 1280 else 1281 OS << T->getInterfaceDecl()->getName(); 1282 1283 if (!T->qual_empty()) { 1284 OS << '<'; 1285 for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(), 1286 E = T->qual_end(); 1287 I != E; ++I) { 1288 OS << (*I)->getName(); 1289 if (I+1 != E) 1290 OS << ','; 1291 } 1292 OS << '>'; 1293 } 1294 1295 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType()) { 1296 OS << " *"; // Don't forget the implicit pointer. 1297 } else { 1298 spaceBeforePlaceHolder(OS); 1299 } 1300} 1301void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T, 1302 raw_ostream &OS) { } 1303 1304void TemplateSpecializationType:: 1305 PrintTemplateArgumentList(raw_ostream &OS, 1306 const TemplateArgumentListInfo &Args, 1307 const PrintingPolicy &Policy) { 1308 return PrintTemplateArgumentList(OS, 1309 Args.getArgumentArray(), 1310 Args.size(), 1311 Policy); 1312} 1313 1314void 1315TemplateSpecializationType::PrintTemplateArgumentList( 1316 raw_ostream &OS, 1317 const TemplateArgument *Args, 1318 unsigned NumArgs, 1319 const PrintingPolicy &Policy, 1320 bool SkipBrackets) { 1321 if (!SkipBrackets) 1322 OS << '<'; 1323 1324 bool needSpace = false; 1325 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 1326 // Print the argument into a string. 1327 SmallString<128> Buf; 1328 llvm::raw_svector_ostream ArgOS(Buf); 1329 if (Args[Arg].getKind() == TemplateArgument::Pack) { 1330 if (Args[Arg].pack_size() && Arg > 0) 1331 OS << ", "; 1332 PrintTemplateArgumentList(ArgOS, 1333 Args[Arg].pack_begin(), 1334 Args[Arg].pack_size(), 1335 Policy, true); 1336 } else { 1337 if (Arg > 0) 1338 OS << ", "; 1339 Args[Arg].print(Policy, ArgOS); 1340 } 1341 StringRef ArgString = ArgOS.str(); 1342 1343 // If this is the first argument and its string representation 1344 // begins with the global scope specifier ('::foo'), add a space 1345 // to avoid printing the diagraph '<:'. 1346 if (!Arg && !ArgString.empty() && ArgString[0] == ':') 1347 OS << ' '; 1348 1349 OS << ArgString; 1350 1351 needSpace = (!ArgString.empty() && ArgString.back() == '>'); 1352 } 1353 1354 // If the last character of our string is '>', add another space to 1355 // keep the two '>''s separate tokens. We don't *have* to do this in 1356 // C++0x, but it's still good hygiene. 1357 if (needSpace) 1358 OS << ' '; 1359 1360 if (!SkipBrackets) 1361 OS << '>'; 1362} 1363 1364// Sadly, repeat all that with TemplateArgLoc. 1365void TemplateSpecializationType:: 1366PrintTemplateArgumentList(raw_ostream &OS, 1367 const TemplateArgumentLoc *Args, unsigned NumArgs, 1368 const PrintingPolicy &Policy) { 1369 OS << '<'; 1370 1371 bool needSpace = false; 1372 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 1373 if (Arg > 0) 1374 OS << ", "; 1375 1376 // Print the argument into a string. 1377 SmallString<128> Buf; 1378 llvm::raw_svector_ostream ArgOS(Buf); 1379 if (Args[Arg].getArgument().getKind() == TemplateArgument::Pack) { 1380 PrintTemplateArgumentList(ArgOS, 1381 Args[Arg].getArgument().pack_begin(), 1382 Args[Arg].getArgument().pack_size(), 1383 Policy, true); 1384 } else { 1385 Args[Arg].getArgument().print(Policy, ArgOS); 1386 } 1387 StringRef ArgString = ArgOS.str(); 1388 1389 // If this is the first argument and its string representation 1390 // begins with the global scope specifier ('::foo'), add a space 1391 // to avoid printing the diagraph '<:'. 1392 if (!Arg && !ArgString.empty() && ArgString[0] == ':') 1393 OS << ' '; 1394 1395 OS << ArgString; 1396 1397 needSpace = (!ArgString.empty() && ArgString.back() == '>'); 1398 } 1399 1400 // If the last character of our string is '>', add another space to 1401 // keep the two '>''s separate tokens. We don't *have* to do this in 1402 // C++0x, but it's still good hygiene. 1403 if (needSpace) 1404 OS << ' '; 1405 1406 OS << '>'; 1407} 1408 1409void QualType::dump(const char *msg) const { 1410 if (msg) 1411 llvm::errs() << msg << ": "; 1412 LangOptions LO; 1413 print(llvm::errs(), PrintingPolicy(LO), "identifier"); 1414 llvm::errs() << '\n'; 1415} 1416void QualType::dump() const { 1417 dump(0); 1418} 1419 1420void Type::dump() const { 1421 QualType(this, 0).dump(); 1422} 1423 1424std::string Qualifiers::getAsString() const { 1425 LangOptions LO; 1426 return getAsString(PrintingPolicy(LO)); 1427} 1428 1429// Appends qualifiers to the given string, separated by spaces. Will 1430// prefix a space if the string is non-empty. Will not append a final 1431// space. 1432std::string Qualifiers::getAsString(const PrintingPolicy &Policy) const { 1433 SmallString<64> Buf; 1434 llvm::raw_svector_ostream StrOS(Buf); 1435 print(StrOS, Policy); 1436 return StrOS.str(); 1437} 1438 1439bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const { 1440 if (getCVRQualifiers()) 1441 return false; 1442 1443 if (getAddressSpace()) 1444 return false; 1445 1446 if (getObjCGCAttr()) 1447 return false; 1448 1449 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) 1450 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)) 1451 return false; 1452 1453 return true; 1454} 1455 1456// Appends qualifiers to the given string, separated by spaces. Will 1457// prefix a space if the string is non-empty. Will not append a final 1458// space. 1459void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy, 1460 bool appendSpaceIfNonEmpty) const { 1461 bool addSpace = false; 1462 1463 unsigned quals = getCVRQualifiers(); 1464 if (quals) { 1465 AppendTypeQualList(OS, quals); 1466 addSpace = true; 1467 } 1468 if (unsigned addrspace = getAddressSpace()) { 1469 if (addSpace) 1470 OS << ' '; 1471 addSpace = true; 1472 switch (addrspace) { 1473 case LangAS::opencl_global: 1474 OS << "__global"; 1475 break; 1476 case LangAS::opencl_local: 1477 OS << "__local"; 1478 break; 1479 case LangAS::opencl_constant: 1480 OS << "__constant"; 1481 break; 1482 default: 1483 OS << "__attribute__((address_space("; 1484 OS << addrspace; 1485 OS << ")))"; 1486 } 1487 } 1488 if (Qualifiers::GC gc = getObjCGCAttr()) { 1489 if (addSpace) 1490 OS << ' '; 1491 addSpace = true; 1492 if (gc == Qualifiers::Weak) 1493 OS << "__weak"; 1494 else 1495 OS << "__strong"; 1496 } 1497 if (Qualifiers::ObjCLifetime lifetime = getObjCLifetime()) { 1498 if (!(lifetime == Qualifiers::OCL_Strong && Policy.SuppressStrongLifetime)){ 1499 if (addSpace) 1500 OS << ' '; 1501 addSpace = true; 1502 } 1503 1504 switch (lifetime) { 1505 case Qualifiers::OCL_None: llvm_unreachable("none but true"); 1506 case Qualifiers::OCL_ExplicitNone: OS << "__unsafe_unretained"; break; 1507 case Qualifiers::OCL_Strong: 1508 if (!Policy.SuppressStrongLifetime) 1509 OS << "__strong"; 1510 break; 1511 1512 case Qualifiers::OCL_Weak: OS << "__weak"; break; 1513 case Qualifiers::OCL_Autoreleasing: OS << "__autoreleasing"; break; 1514 } 1515 } 1516 1517 if (appendSpaceIfNonEmpty && addSpace) 1518 OS << ' '; 1519} 1520 1521std::string QualType::getAsString(const PrintingPolicy &Policy) const { 1522 std::string S; 1523 getAsStringInternal(S, Policy); 1524 return S; 1525} 1526 1527std::string QualType::getAsString(const Type *ty, Qualifiers qs) { 1528 std::string buffer; 1529 LangOptions options; 1530 getAsStringInternal(ty, qs, buffer, PrintingPolicy(options)); 1531 return buffer; 1532} 1533 1534void QualType::print(const Type *ty, Qualifiers qs, 1535 raw_ostream &OS, const PrintingPolicy &policy, 1536 const Twine &PlaceHolder) { 1537 SmallString<128> PHBuf; 1538 StringRef PH = PlaceHolder.toStringRef(PHBuf); 1539 1540 TypePrinter(policy).print(ty, qs, OS, PH); 1541} 1542 1543void QualType::getAsStringInternal(const Type *ty, Qualifiers qs, 1544 std::string &buffer, 1545 const PrintingPolicy &policy) { 1546 SmallString<256> Buf; 1547 llvm::raw_svector_ostream StrOS(Buf); 1548 TypePrinter(policy).print(ty, qs, StrOS, buffer); 1549 std::string str = StrOS.str(); 1550 buffer.swap(str); 1551} 1552