TypePrinter.cpp revision 9705697d18844b35cbeeb747cfc9aa6d7d86241e
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/Decl.h" 15#include "clang/AST/DeclObjC.h" 16#include "clang/AST/DeclTemplate.h" 17#include "clang/AST/Expr.h" 18#include "clang/AST/Type.h" 19#include "clang/AST/PrettyPrinter.h" 20#include "clang/Basic/LangOptions.h" 21#include "clang/Basic/SourceManager.h" 22#include "llvm/ADT/StringExtras.h" 23#include "llvm/Support/raw_ostream.h" 24using namespace clang; 25 26namespace { 27 class TypePrinter { 28 PrintingPolicy Policy; 29 30 public: 31 explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { } 32 33 void Print(QualType T, std::string &S); 34 void AppendScope(DeclContext *DC, std::string &S); 35 void PrintTag(TagDecl *T, std::string &S); 36#define ABSTRACT_TYPE(CLASS, PARENT) 37#define TYPE(CLASS, PARENT) \ 38 void Print##CLASS(const CLASS##Type *T, std::string &S); 39#include "clang/AST/TypeNodes.def" 40 }; 41} 42 43static void AppendTypeQualList(std::string &S, unsigned TypeQuals) { 44 if (TypeQuals & Qualifiers::Const) { 45 if (!S.empty()) S += ' '; 46 S += "const"; 47 } 48 if (TypeQuals & Qualifiers::Volatile) { 49 if (!S.empty()) S += ' '; 50 S += "volatile"; 51 } 52 if (TypeQuals & Qualifiers::Restrict) { 53 if (!S.empty()) S += ' '; 54 S += "restrict"; 55 } 56} 57 58void TypePrinter::Print(QualType T, std::string &S) { 59 if (T.isNull()) { 60 S += "NULL TYPE"; 61 return; 62 } 63 64 if (Policy.SuppressSpecifiers && T->isSpecifierType()) 65 return; 66 67 // Print qualifiers as appropriate. 68 Qualifiers Quals = T.getLocalQualifiers(); 69 if (!Quals.empty()) { 70 std::string TQS; 71 Quals.getAsStringInternal(TQS, Policy); 72 73 if (!S.empty()) { 74 TQS += ' '; 75 TQS += S; 76 } 77 std::swap(S, TQS); 78 } 79 80 switch (T->getTypeClass()) { 81#define ABSTRACT_TYPE(CLASS, PARENT) 82#define TYPE(CLASS, PARENT) case Type::CLASS: \ 83 Print##CLASS(cast<CLASS##Type>(T.getTypePtr()), S); \ 84 break; 85#include "clang/AST/TypeNodes.def" 86 } 87} 88 89void TypePrinter::PrintBuiltin(const BuiltinType *T, std::string &S) { 90 if (S.empty()) { 91 S = T->getName(Policy.LangOpts); 92 } else { 93 // Prefix the basic type, e.g. 'int X'. 94 S = ' ' + S; 95 S = T->getName(Policy.LangOpts) + S; 96 } 97} 98 99void TypePrinter::PrintComplex(const ComplexType *T, std::string &S) { 100 Print(T->getElementType(), S); 101 S = "_Complex " + S; 102} 103 104void TypePrinter::PrintPointer(const PointerType *T, std::string &S) { 105 S = '*' + S; 106 107 // Handle things like 'int (*A)[4];' correctly. 108 // FIXME: this should include vectors, but vectors use attributes I guess. 109 if (isa<ArrayType>(T->getPointeeType())) 110 S = '(' + S + ')'; 111 112 Print(T->getPointeeType(), S); 113} 114 115void TypePrinter::PrintBlockPointer(const BlockPointerType *T, std::string &S) { 116 S = '^' + S; 117 Print(T->getPointeeType(), S); 118} 119 120void TypePrinter::PrintLValueReference(const LValueReferenceType *T, 121 std::string &S) { 122 S = '&' + S; 123 124 // Handle things like 'int (&A)[4];' correctly. 125 // FIXME: this should include vectors, but vectors use attributes I guess. 126 if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 127 S = '(' + S + ')'; 128 129 Print(T->getPointeeTypeAsWritten(), S); 130} 131 132void TypePrinter::PrintRValueReference(const RValueReferenceType *T, 133 std::string &S) { 134 S = "&&" + S; 135 136 // Handle things like 'int (&&A)[4];' correctly. 137 // FIXME: this should include vectors, but vectors use attributes I guess. 138 if (isa<ArrayType>(T->getPointeeTypeAsWritten())) 139 S = '(' + S + ')'; 140 141 Print(T->getPointeeTypeAsWritten(), S); 142} 143 144void TypePrinter::PrintMemberPointer(const MemberPointerType *T, 145 std::string &S) { 146 std::string C; 147 Print(QualType(T->getClass(), 0), C); 148 C += "::*"; 149 S = C + S; 150 151 // Handle things like 'int (Cls::*A)[4];' correctly. 152 // FIXME: this should include vectors, but vectors use attributes I guess. 153 if (isa<ArrayType>(T->getPointeeType())) 154 S = '(' + S + ')'; 155 156 Print(T->getPointeeType(), S); 157} 158 159void TypePrinter::PrintConstantArray(const ConstantArrayType *T, 160 std::string &S) { 161 S += '['; 162 S += llvm::utostr(T->getSize().getZExtValue()); 163 S += ']'; 164 165 Print(T->getElementType(), S); 166} 167 168void TypePrinter::PrintIncompleteArray(const IncompleteArrayType *T, 169 std::string &S) { 170 S += "[]"; 171 Print(T->getElementType(), S); 172} 173 174void TypePrinter::PrintVariableArray(const VariableArrayType *T, 175 std::string &S) { 176 S += '['; 177 178 if (T->getIndexTypeQualifiers().hasQualifiers()) { 179 AppendTypeQualList(S, T->getIndexTypeCVRQualifiers()); 180 S += ' '; 181 } 182 183 if (T->getSizeModifier() == VariableArrayType::Static) 184 S += "static"; 185 else if (T->getSizeModifier() == VariableArrayType::Star) 186 S += '*'; 187 188 if (T->getSizeExpr()) { 189 std::string SStr; 190 llvm::raw_string_ostream s(SStr); 191 T->getSizeExpr()->printPretty(s, 0, Policy); 192 S += s.str(); 193 } 194 S += ']'; 195 196 Print(T->getElementType(), S); 197} 198 199void TypePrinter::PrintDependentSizedArray(const DependentSizedArrayType *T, 200 std::string &S) { 201 S += '['; 202 203 if (T->getSizeExpr()) { 204 std::string SStr; 205 llvm::raw_string_ostream s(SStr); 206 T->getSizeExpr()->printPretty(s, 0, Policy); 207 S += s.str(); 208 } 209 S += ']'; 210 211 Print(T->getElementType(), S); 212} 213 214void TypePrinter::PrintDependentSizedExtVector( 215 const DependentSizedExtVectorType *T, 216 std::string &S) { 217 Print(T->getElementType(), S); 218 219 S += " __attribute__((ext_vector_type("; 220 if (T->getSizeExpr()) { 221 std::string SStr; 222 llvm::raw_string_ostream s(SStr); 223 T->getSizeExpr()->printPretty(s, 0, Policy); 224 S += s.str(); 225 } 226 S += ")))"; 227} 228 229void TypePrinter::PrintVector(const VectorType *T, std::string &S) { 230 if (T->isAltiVec()) { 231 if (T->isPixel()) 232 S = "__vector __pixel " + S; 233 else { 234 Print(T->getElementType(), S); 235 S = "__vector " + S; 236 } 237 } else { 238 // FIXME: We prefer to print the size directly here, but have no way 239 // to get the size of the type. 240 Print(T->getElementType(), S); 241 std::string V = "__attribute__((__vector_size__("; 242 V += llvm::utostr_32(T->getNumElements()); // convert back to bytes. 243 std::string ET; 244 Print(T->getElementType(), ET); 245 V += " * sizeof(" + ET + ")))) "; 246 S = V + S; 247 } 248} 249 250void TypePrinter::PrintExtVector(const ExtVectorType *T, std::string &S) { 251 S += " __attribute__((ext_vector_type("; 252 S += llvm::utostr_32(T->getNumElements()); 253 S += ")))"; 254 Print(T->getElementType(), S); 255} 256 257void TypePrinter::PrintFunctionProto(const FunctionProtoType *T, 258 std::string &S) { 259 // If needed for precedence reasons, wrap the inner part in grouping parens. 260 if (!S.empty()) 261 S = "(" + S + ")"; 262 263 S += "("; 264 std::string Tmp; 265 PrintingPolicy ParamPolicy(Policy); 266 ParamPolicy.SuppressSpecifiers = false; 267 for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) { 268 if (i) S += ", "; 269 Print(T->getArgType(i), Tmp); 270 S += Tmp; 271 Tmp.clear(); 272 } 273 274 if (T->isVariadic()) { 275 if (T->getNumArgs()) 276 S += ", "; 277 S += "..."; 278 } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) { 279 // Do not emit int() if we have a proto, emit 'int(void)'. 280 S += "void"; 281 } 282 283 S += ")"; 284 285 FunctionType::ExtInfo Info = T->getExtInfo(); 286 switch(Info.getCC()) { 287 case CC_Default: 288 default: break; 289 case CC_C: 290 S += " __attribute__((cdecl))"; 291 break; 292 case CC_X86StdCall: 293 S += " __attribute__((stdcall))"; 294 break; 295 case CC_X86FastCall: 296 S += " __attribute__((fastcall))"; 297 break; 298 } 299 if (Info.getNoReturn()) 300 S += " __attribute__((noreturn))"; 301 if (Info.getRegParm()) 302 S += " __attribute__((regparm (" + 303 llvm::utostr_32(Info.getRegParm()) + ")))"; 304 305 if (T->hasExceptionSpec()) { 306 S += " throw("; 307 if (T->hasAnyExceptionSpec()) 308 S += "..."; 309 else 310 for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) { 311 if (I) 312 S += ", "; 313 314 std::string ExceptionType; 315 Print(T->getExceptionType(I), ExceptionType); 316 S += ExceptionType; 317 } 318 S += ")"; 319 } 320 321 AppendTypeQualList(S, T->getTypeQuals()); 322 323 Print(T->getResultType(), S); 324} 325 326void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T, 327 std::string &S) { 328 // If needed for precedence reasons, wrap the inner part in grouping parens. 329 if (!S.empty()) 330 S = "(" + S + ")"; 331 332 S += "()"; 333 if (T->getNoReturnAttr()) 334 S += " __attribute__((noreturn))"; 335 Print(T->getResultType(), S); 336} 337 338static void PrintTypeSpec(const NamedDecl *D, std::string &S) { 339 IdentifierInfo *II = D->getIdentifier(); 340 if (S.empty()) 341 S = II->getName().str(); 342 else 343 S = II->getName().str() + ' ' + S; 344} 345 346void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T, 347 std::string &S) { 348 PrintTypeSpec(T->getDecl(), S); 349} 350 351void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) { 352 PrintTypeSpec(T->getDecl(), S); 353} 354 355void TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) { 356 if (!S.empty()) // Prefix the basic type, e.g. 'typeof(e) X'. 357 S = ' ' + S; 358 std::string Str; 359 llvm::raw_string_ostream s(Str); 360 T->getUnderlyingExpr()->printPretty(s, 0, Policy); 361 S = "typeof " + s.str() + S; 362} 363 364void TypePrinter::PrintTypeOf(const TypeOfType *T, std::string &S) { 365 if (!S.empty()) // Prefix the basic type, e.g. 'typeof(t) X'. 366 S = ' ' + S; 367 std::string Tmp; 368 Print(T->getUnderlyingType(), Tmp); 369 S = "typeof(" + Tmp + ")" + S; 370} 371 372void TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) { 373 if (!S.empty()) // Prefix the basic type, e.g. 'decltype(t) X'. 374 S = ' ' + S; 375 std::string Str; 376 llvm::raw_string_ostream s(Str); 377 T->getUnderlyingExpr()->printPretty(s, 0, Policy); 378 S = "decltype(" + s.str() + ")" + S; 379} 380 381/// Appends the given scope to the end of a string. 382void TypePrinter::AppendScope(DeclContext *DC, std::string &Buffer) { 383 if (DC->isTranslationUnit()) return; 384 AppendScope(DC->getParent(), Buffer); 385 386 unsigned OldSize = Buffer.size(); 387 388 if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) { 389 if (NS->getIdentifier()) 390 Buffer += NS->getNameAsString(); 391 else 392 Buffer += "<anonymous>"; 393 } else if (ClassTemplateSpecializationDecl *Spec 394 = dyn_cast<ClassTemplateSpecializationDecl>(DC)) { 395 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 396 std::string TemplateArgsStr 397 = TemplateSpecializationType::PrintTemplateArgumentList( 398 TemplateArgs.getFlatArgumentList(), 399 TemplateArgs.flat_size(), 400 Policy); 401 Buffer += Spec->getIdentifier()->getName(); 402 Buffer += TemplateArgsStr; 403 } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { 404 if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl()) 405 Buffer += Typedef->getIdentifier()->getName(); 406 else if (Tag->getIdentifier()) 407 Buffer += Tag->getIdentifier()->getName(); 408 } 409 410 if (Buffer.size() != OldSize) 411 Buffer += "::"; 412} 413 414void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) { 415 if (Policy.SuppressTag) 416 return; 417 418 std::string Buffer; 419 bool HasKindDecoration = false; 420 421 // We don't print tags unless this is an elaborated type. 422 // In C, we just assume every RecordType is an elaborated type. 423 if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) { 424 HasKindDecoration = true; 425 Buffer += D->getKindName(); 426 Buffer += ' '; 427 } 428 429 if (!Policy.SuppressScope) 430 // Compute the full nested-name-specifier for this type. In C, 431 // this will always be empty. 432 AppendScope(D->getDeclContext(), Buffer); 433 434 if (const IdentifierInfo *II = D->getIdentifier()) 435 Buffer += II->getNameStart(); 436 else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) { 437 assert(Typedef->getIdentifier() && "Typedef without identifier?"); 438 Buffer += Typedef->getIdentifier()->getNameStart(); 439 } else { 440 // Make an unambiguous representation for anonymous types, e.g. 441 // <anonymous enum at /usr/include/string.h:120:9> 442 llvm::raw_string_ostream OS(Buffer); 443 OS << "<anonymous"; 444 445 if (Policy.AnonymousTagLocations) { 446 // Suppress the redundant tag keyword if we just printed one. 447 // We don't have to worry about ElaboratedTypes here because you can't 448 // refer to an anonymous type with one. 449 if (!HasKindDecoration) 450 OS << " " << D->getKindName(); 451 452 PresumedLoc PLoc = D->getASTContext().getSourceManager().getPresumedLoc( 453 D->getLocation()); 454 OS << " at " << PLoc.getFilename() 455 << ':' << PLoc.getLine() 456 << ':' << PLoc.getColumn(); 457 } 458 459 OS << '>'; 460 OS.flush(); 461 } 462 463 // If this is a class template specialization, print the template 464 // arguments. 465 if (ClassTemplateSpecializationDecl *Spec 466 = dyn_cast<ClassTemplateSpecializationDecl>(D)) { 467 const TemplateArgument *Args; 468 unsigned NumArgs; 469 if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) { 470 const TemplateSpecializationType *TST = 471 cast<TemplateSpecializationType>(TAW->getType()); 472 Args = TST->getArgs(); 473 NumArgs = TST->getNumArgs(); 474 } else { 475 const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); 476 Args = TemplateArgs.getFlatArgumentList(); 477 NumArgs = TemplateArgs.flat_size(); 478 } 479 Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args, 480 NumArgs, 481 Policy); 482 } 483 484 if (!InnerString.empty()) { 485 Buffer += ' '; 486 Buffer += InnerString; 487 } 488 489 std::swap(Buffer, InnerString); 490} 491 492void TypePrinter::PrintRecord(const RecordType *T, std::string &S) { 493 PrintTag(T->getDecl(), S); 494} 495 496void TypePrinter::PrintEnum(const EnumType *T, std::string &S) { 497 PrintTag(T->getDecl(), S); 498} 499 500void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) { 501 Print(T->getUnderlyingType(), S); 502 503 // We don't actually make these in C, but the language options 504 // sometimes lie to us -- for example, if someone calls 505 // QualType::getAsString(). Just suppress the redundant tag if so. 506 if (Policy.LangOpts.CPlusPlus) 507 S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S; 508} 509 510void TypePrinter::PrintTemplateTypeParm(const TemplateTypeParmType *T, 511 std::string &S) { 512 if (!S.empty()) // Prefix the basic type, e.g. 'parmname X'. 513 S = ' ' + S; 514 515 if (!T->getName()) 516 S = "type-parameter-" + llvm::utostr_32(T->getDepth()) + '-' + 517 llvm::utostr_32(T->getIndex()) + S; 518 else 519 S = T->getName()->getName().str() + S; 520} 521 522void TypePrinter::PrintSubstTemplateTypeParm(const SubstTemplateTypeParmType *T, 523 std::string &S) { 524 Print(T->getReplacementType(), S); 525} 526 527void TypePrinter::PrintTemplateSpecialization( 528 const TemplateSpecializationType *T, 529 std::string &S) { 530 std::string SpecString; 531 532 { 533 llvm::raw_string_ostream OS(SpecString); 534 T->getTemplateName().print(OS, Policy); 535 } 536 537 SpecString += TemplateSpecializationType::PrintTemplateArgumentList( 538 T->getArgs(), 539 T->getNumArgs(), 540 Policy); 541 if (S.empty()) 542 S.swap(SpecString); 543 else 544 S = SpecString + ' ' + S; 545} 546 547void TypePrinter::PrintInjectedClassName(const InjectedClassNameType *T, 548 std::string &S) { 549 PrintTemplateSpecialization(T->getInjectedTST(), S); 550} 551 552void TypePrinter::PrintQualifiedName(const QualifiedNameType *T, 553 std::string &S) { 554 std::string MyString; 555 556 { 557 llvm::raw_string_ostream OS(MyString); 558 T->getQualifier()->print(OS, Policy); 559 } 560 561 std::string TypeStr; 562 PrintingPolicy InnerPolicy(Policy); 563 InnerPolicy.SuppressScope = true; 564 TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr); 565 566 MyString += TypeStr; 567 if (S.empty()) 568 S.swap(MyString); 569 else 570 S = MyString + ' ' + S; 571} 572 573void TypePrinter::PrintDependentName(const DependentNameType *T, std::string &S) { 574 std::string MyString; 575 576 { 577 llvm::raw_string_ostream OS(MyString); 578 switch (T->getKeyword()) { 579 case ETK_None: break; 580 case ETK_Typename: OS << "typename "; break; 581 case ETK_Class: OS << "class "; break; 582 case ETK_Struct: OS << "struct "; break; 583 case ETK_Union: OS << "union "; break; 584 case ETK_Enum: OS << "enum "; break; 585 } 586 587 T->getQualifier()->print(OS, Policy); 588 589 if (const IdentifierInfo *Ident = T->getIdentifier()) 590 OS << Ident->getName(); 591 else if (const TemplateSpecializationType *Spec = T->getTemplateId()) { 592 Spec->getTemplateName().print(OS, Policy, true); 593 OS << TemplateSpecializationType::PrintTemplateArgumentList( 594 Spec->getArgs(), 595 Spec->getNumArgs(), 596 Policy); 597 } 598 } 599 600 if (S.empty()) 601 S.swap(MyString); 602 else 603 S = MyString + ' ' + S; 604} 605 606void TypePrinter::PrintObjCInterface(const ObjCInterfaceType *T, 607 std::string &S) { 608 if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. 609 S = ' ' + S; 610 611 std::string ObjCQIString = T->getDecl()->getNameAsString(); 612 if (T->getNumProtocols()) { 613 ObjCQIString += '<'; 614 bool isFirst = true; 615 for (ObjCInterfaceType::qual_iterator I = T->qual_begin(), 616 E = T->qual_end(); 617 I != E; ++I) { 618 if (isFirst) 619 isFirst = false; 620 else 621 ObjCQIString += ','; 622 ObjCQIString += (*I)->getNameAsString(); 623 } 624 ObjCQIString += '>'; 625 } 626 S = ObjCQIString + S; 627} 628 629void TypePrinter::PrintObjCObjectPointer(const ObjCObjectPointerType *T, 630 std::string &S) { 631 std::string ObjCQIString; 632 633 if (T->isObjCIdType() || T->isObjCQualifiedIdType()) 634 ObjCQIString = "id"; 635 else if (T->isObjCClassType() || T->isObjCQualifiedClassType()) 636 ObjCQIString = "Class"; 637 else if (T->isObjCSelType()) 638 ObjCQIString = "SEL"; 639 else 640 ObjCQIString = T->getInterfaceDecl()->getNameAsString(); 641 642 if (!T->qual_empty()) { 643 ObjCQIString += '<'; 644 for (ObjCObjectPointerType::qual_iterator I = T->qual_begin(), 645 E = T->qual_end(); 646 I != E; ++I) { 647 ObjCQIString += (*I)->getNameAsString(); 648 if (I+1 != E) 649 ObjCQIString += ','; 650 } 651 ObjCQIString += '>'; 652 } 653 654 T->getPointeeType().getLocalQualifiers().getAsStringInternal(ObjCQIString, 655 Policy); 656 657 if (!T->isObjCIdType() && !T->isObjCQualifiedIdType()) 658 ObjCQIString += " *"; // Don't forget the implicit pointer. 659 else if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'. 660 S = ' ' + S; 661 662 S = ObjCQIString + S; 663} 664 665static void PrintTemplateArgument(std::string &Buffer, 666 const TemplateArgument &Arg, 667 const PrintingPolicy &Policy) { 668 switch (Arg.getKind()) { 669 case TemplateArgument::Null: 670 assert(false && "Null template argument"); 671 break; 672 673 case TemplateArgument::Type: 674 Arg.getAsType().getAsStringInternal(Buffer, Policy); 675 break; 676 677 case TemplateArgument::Declaration: 678 Buffer = cast<NamedDecl>(Arg.getAsDecl())->getNameAsString(); 679 break; 680 681 case TemplateArgument::Template: { 682 llvm::raw_string_ostream s(Buffer); 683 Arg.getAsTemplate().print(s, Policy); 684 break; 685 } 686 687 case TemplateArgument::Integral: 688 Buffer = Arg.getAsIntegral()->toString(10, true); 689 break; 690 691 case TemplateArgument::Expression: { 692 llvm::raw_string_ostream s(Buffer); 693 Arg.getAsExpr()->printPretty(s, 0, Policy); 694 break; 695 } 696 697 case TemplateArgument::Pack: 698 assert(0 && "FIXME: Implement!"); 699 break; 700 } 701} 702 703std::string TemplateSpecializationType:: 704 PrintTemplateArgumentList(const TemplateArgumentListInfo &Args, 705 const PrintingPolicy &Policy) { 706 return PrintTemplateArgumentList(Args.getArgumentArray(), 707 Args.size(), 708 Policy); 709} 710 711std::string 712TemplateSpecializationType::PrintTemplateArgumentList( 713 const TemplateArgument *Args, 714 unsigned NumArgs, 715 const PrintingPolicy &Policy) { 716 std::string SpecString; 717 SpecString += '<'; 718 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 719 if (Arg) 720 SpecString += ", "; 721 722 // Print the argument into a string. 723 std::string ArgString; 724 PrintTemplateArgument(ArgString, Args[Arg], Policy); 725 726 // If this is the first argument and its string representation 727 // begins with the global scope specifier ('::foo'), add a space 728 // to avoid printing the diagraph '<:'. 729 if (!Arg && !ArgString.empty() && ArgString[0] == ':') 730 SpecString += ' '; 731 732 SpecString += ArgString; 733 } 734 735 // If the last character of our string is '>', add another space to 736 // keep the two '>''s separate tokens. We don't *have* to do this in 737 // C++0x, but it's still good hygiene. 738 if (SpecString[SpecString.size() - 1] == '>') 739 SpecString += ' '; 740 741 SpecString += '>'; 742 743 return SpecString; 744} 745 746// Sadly, repeat all that with TemplateArgLoc. 747std::string TemplateSpecializationType:: 748PrintTemplateArgumentList(const TemplateArgumentLoc *Args, unsigned NumArgs, 749 const PrintingPolicy &Policy) { 750 std::string SpecString; 751 SpecString += '<'; 752 for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { 753 if (Arg) 754 SpecString += ", "; 755 756 // Print the argument into a string. 757 std::string ArgString; 758 PrintTemplateArgument(ArgString, Args[Arg].getArgument(), Policy); 759 760 // If this is the first argument and its string representation 761 // begins with the global scope specifier ('::foo'), add a space 762 // to avoid printing the diagraph '<:'. 763 if (!Arg && !ArgString.empty() && ArgString[0] == ':') 764 SpecString += ' '; 765 766 SpecString += ArgString; 767 } 768 769 // If the last character of our string is '>', add another space to 770 // keep the two '>''s separate tokens. We don't *have* to do this in 771 // C++0x, but it's still good hygiene. 772 if (SpecString[SpecString.size() - 1] == '>') 773 SpecString += ' '; 774 775 SpecString += '>'; 776 777 return SpecString; 778} 779 780void QualType::dump(const char *msg) const { 781 std::string R = "identifier"; 782 LangOptions LO; 783 getAsStringInternal(R, PrintingPolicy(LO)); 784 if (msg) 785 llvm::errs() << msg << ": "; 786 llvm::errs() << R << "\n"; 787} 788void QualType::dump() const { 789 dump(""); 790} 791 792void Type::dump() const { 793 QualType(this, 0).dump(); 794} 795 796std::string Qualifiers::getAsString() const { 797 LangOptions LO; 798 return getAsString(PrintingPolicy(LO)); 799} 800 801// Appends qualifiers to the given string, separated by spaces. Will 802// prefix a space if the string is non-empty. Will not append a final 803// space. 804void Qualifiers::getAsStringInternal(std::string &S, 805 const PrintingPolicy&) const { 806 AppendTypeQualList(S, getCVRQualifiers()); 807 if (unsigned AddressSpace = getAddressSpace()) { 808 if (!S.empty()) S += ' '; 809 S += "__attribute__((address_space("; 810 S += llvm::utostr_32(AddressSpace); 811 S += ")))"; 812 } 813 if (Qualifiers::GC GCAttrType = getObjCGCAttr()) { 814 if (!S.empty()) S += ' '; 815 S += "__attribute__((objc_gc("; 816 if (GCAttrType == Qualifiers::Weak) 817 S += "weak"; 818 else 819 S += "strong"; 820 S += ")))"; 821 } 822} 823 824std::string QualType::getAsString() const { 825 std::string S; 826 LangOptions LO; 827 getAsStringInternal(S, PrintingPolicy(LO)); 828 return S; 829} 830 831void QualType::getAsStringInternal(std::string &S, 832 const PrintingPolicy &Policy) const { 833 TypePrinter Printer(Policy); 834 Printer.Print(*this, S); 835} 836