StmtPrinter.cpp revision e08ce650a2b02410eddd1f60a4aa6b3d4be71e73
1//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===// 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 file implements the Stmt::dumpPretty/Stmt::printPretty methods, which 11// pretty print the AST back out to C code. 12// 13//===----------------------------------------------------------------------===// 14 15#include "clang/AST/StmtVisitor.h" 16#include "clang/AST/DeclCXX.h" 17#include "clang/AST/DeclObjC.h" 18#include "clang/AST/DeclTemplate.h" 19#include "clang/AST/PrettyPrinter.h" 20#include "llvm/Support/Format.h" 21#include "clang/AST/Expr.h" 22#include "clang/AST/ExprCXX.h" 23using namespace clang; 24 25//===----------------------------------------------------------------------===// 26// StmtPrinter Visitor 27//===----------------------------------------------------------------------===// 28 29namespace { 30 class StmtPrinter : public StmtVisitor<StmtPrinter> { 31 llvm::raw_ostream &OS; 32 ASTContext &Context; 33 unsigned IndentLevel; 34 clang::PrinterHelper* Helper; 35 PrintingPolicy Policy; 36 37 public: 38 StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper, 39 const PrintingPolicy &Policy, 40 unsigned Indentation = 0) 41 : OS(os), Context(C), IndentLevel(Indentation), Helper(helper), 42 Policy(Policy) {} 43 44 void PrintStmt(Stmt *S) { 45 PrintStmt(S, Policy.Indentation); 46 } 47 48 void PrintStmt(Stmt *S, int SubIndent) { 49 IndentLevel += SubIndent; 50 if (S && isa<Expr>(S)) { 51 // If this is an expr used in a stmt context, indent and newline it. 52 Indent(); 53 Visit(S); 54 OS << ";\n"; 55 } else if (S) { 56 Visit(S); 57 } else { 58 Indent() << "<<<NULL STATEMENT>>>\n"; 59 } 60 IndentLevel -= SubIndent; 61 } 62 63 void PrintRawCompoundStmt(CompoundStmt *S); 64 void PrintRawDecl(Decl *D); 65 void PrintRawDeclStmt(DeclStmt *S); 66 void PrintRawIfStmt(IfStmt *If); 67 void PrintRawCXXCatchStmt(CXXCatchStmt *Catch); 68 void PrintCallArgs(CallExpr *E); 69 70 void PrintExpr(Expr *E) { 71 if (E) 72 Visit(E); 73 else 74 OS << "<null expr>"; 75 } 76 77 llvm::raw_ostream &Indent(int Delta = 0) { 78 for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 79 OS << " "; 80 return OS; 81 } 82 83 void Visit(Stmt* S) { 84 if (Helper && Helper->handledStmt(S,OS)) 85 return; 86 else StmtVisitor<StmtPrinter>::Visit(S); 87 } 88 89 void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED { 90 Indent() << "<<unknown stmt type>>\n"; 91 } 92 void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED { 93 OS << "<<unknown expr type>>"; 94 } 95 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); 96 97#define ABSTRACT_STMT(CLASS) 98#define STMT(CLASS, PARENT) \ 99 void Visit##CLASS(CLASS *Node); 100#include "clang/AST/StmtNodes.inc" 101 }; 102} 103 104//===----------------------------------------------------------------------===// 105// Stmt printing methods. 106//===----------------------------------------------------------------------===// 107 108/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 109/// with no newline after the }. 110void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 111 OS << "{\n"; 112 for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end(); 113 I != E; ++I) 114 PrintStmt(*I); 115 116 Indent() << "}"; 117} 118 119void StmtPrinter::PrintRawDecl(Decl *D) { 120 D->print(OS, Policy, IndentLevel); 121} 122 123void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) { 124 DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end(); 125 llvm::SmallVector<Decl*, 2> Decls; 126 for ( ; Begin != End; ++Begin) 127 Decls.push_back(*Begin); 128 129 Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel); 130} 131 132void StmtPrinter::VisitNullStmt(NullStmt *Node) { 133 Indent() << ";\n"; 134} 135 136void StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 137 Indent(); 138 PrintRawDeclStmt(Node); 139 OS << ";\n"; 140} 141 142void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 143 Indent(); 144 PrintRawCompoundStmt(Node); 145 OS << "\n"; 146} 147 148void StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 149 Indent(-1) << "case "; 150 PrintExpr(Node->getLHS()); 151 if (Node->getRHS()) { 152 OS << " ... "; 153 PrintExpr(Node->getRHS()); 154 } 155 OS << ":\n"; 156 157 PrintStmt(Node->getSubStmt(), 0); 158} 159 160void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 161 Indent(-1) << "default:\n"; 162 PrintStmt(Node->getSubStmt(), 0); 163} 164 165void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 166 Indent(-1) << Node->getName() << ":\n"; 167 PrintStmt(Node->getSubStmt(), 0); 168} 169 170void StmtPrinter::PrintRawIfStmt(IfStmt *If) { 171 OS << "if ("; 172 PrintExpr(If->getCond()); 173 OS << ')'; 174 175 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) { 176 OS << ' '; 177 PrintRawCompoundStmt(CS); 178 OS << (If->getElse() ? ' ' : '\n'); 179 } else { 180 OS << '\n'; 181 PrintStmt(If->getThen()); 182 if (If->getElse()) Indent(); 183 } 184 185 if (Stmt *Else = If->getElse()) { 186 OS << "else"; 187 188 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) { 189 OS << ' '; 190 PrintRawCompoundStmt(CS); 191 OS << '\n'; 192 } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) { 193 OS << ' '; 194 PrintRawIfStmt(ElseIf); 195 } else { 196 OS << '\n'; 197 PrintStmt(If->getElse()); 198 } 199 } 200} 201 202void StmtPrinter::VisitIfStmt(IfStmt *If) { 203 Indent(); 204 PrintRawIfStmt(If); 205} 206 207void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 208 Indent() << "switch ("; 209 PrintExpr(Node->getCond()); 210 OS << ")"; 211 212 // Pretty print compoundstmt bodies (very common). 213 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 214 OS << " "; 215 PrintRawCompoundStmt(CS); 216 OS << "\n"; 217 } else { 218 OS << "\n"; 219 PrintStmt(Node->getBody()); 220 } 221} 222 223void StmtPrinter::VisitWhileStmt(WhileStmt *Node) { 224 Indent() << "while ("; 225 PrintExpr(Node->getCond()); 226 OS << ")\n"; 227 PrintStmt(Node->getBody()); 228} 229 230void StmtPrinter::VisitDoStmt(DoStmt *Node) { 231 Indent() << "do "; 232 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 233 PrintRawCompoundStmt(CS); 234 OS << " "; 235 } else { 236 OS << "\n"; 237 PrintStmt(Node->getBody()); 238 Indent(); 239 } 240 241 OS << "while ("; 242 PrintExpr(Node->getCond()); 243 OS << ");\n"; 244} 245 246void StmtPrinter::VisitForStmt(ForStmt *Node) { 247 Indent() << "for ("; 248 if (Node->getInit()) { 249 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit())) 250 PrintRawDeclStmt(DS); 251 else 252 PrintExpr(cast<Expr>(Node->getInit())); 253 } 254 OS << ";"; 255 if (Node->getCond()) { 256 OS << " "; 257 PrintExpr(Node->getCond()); 258 } 259 OS << ";"; 260 if (Node->getInc()) { 261 OS << " "; 262 PrintExpr(Node->getInc()); 263 } 264 OS << ") "; 265 266 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 267 PrintRawCompoundStmt(CS); 268 OS << "\n"; 269 } else { 270 OS << "\n"; 271 PrintStmt(Node->getBody()); 272 } 273} 274 275void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) { 276 Indent() << "for ("; 277 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement())) 278 PrintRawDeclStmt(DS); 279 else 280 PrintExpr(cast<Expr>(Node->getElement())); 281 OS << " in "; 282 PrintExpr(Node->getCollection()); 283 OS << ") "; 284 285 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 286 PrintRawCompoundStmt(CS); 287 OS << "\n"; 288 } else { 289 OS << "\n"; 290 PrintStmt(Node->getBody()); 291 } 292} 293 294void StmtPrinter::VisitGotoStmt(GotoStmt *Node) { 295 Indent() << "goto " << Node->getLabel()->getName() << ";\n"; 296} 297 298void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) { 299 Indent() << "goto *"; 300 PrintExpr(Node->getTarget()); 301 OS << ";\n"; 302} 303 304void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) { 305 Indent() << "continue;\n"; 306} 307 308void StmtPrinter::VisitBreakStmt(BreakStmt *Node) { 309 Indent() << "break;\n"; 310} 311 312 313void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) { 314 Indent() << "return"; 315 if (Node->getRetValue()) { 316 OS << " "; 317 PrintExpr(Node->getRetValue()); 318 } 319 OS << ";\n"; 320} 321 322 323void StmtPrinter::VisitAsmStmt(AsmStmt *Node) { 324 Indent() << "asm "; 325 326 if (Node->isVolatile()) 327 OS << "volatile "; 328 329 OS << "("; 330 VisitStringLiteral(Node->getAsmString()); 331 332 // Outputs 333 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 || 334 Node->getNumClobbers() != 0) 335 OS << " : "; 336 337 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) { 338 if (i != 0) 339 OS << ", "; 340 341 if (!Node->getOutputName(i).empty()) { 342 OS << '['; 343 OS << Node->getOutputName(i); 344 OS << "] "; 345 } 346 347 VisitStringLiteral(Node->getOutputConstraintLiteral(i)); 348 OS << " "; 349 Visit(Node->getOutputExpr(i)); 350 } 351 352 // Inputs 353 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0) 354 OS << " : "; 355 356 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) { 357 if (i != 0) 358 OS << ", "; 359 360 if (!Node->getInputName(i).empty()) { 361 OS << '['; 362 OS << Node->getInputName(i); 363 OS << "] "; 364 } 365 366 VisitStringLiteral(Node->getInputConstraintLiteral(i)); 367 OS << " "; 368 Visit(Node->getInputExpr(i)); 369 } 370 371 // Clobbers 372 if (Node->getNumClobbers() != 0) 373 OS << " : "; 374 375 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) { 376 if (i != 0) 377 OS << ", "; 378 379 VisitStringLiteral(Node->getClobber(i)); 380 } 381 382 OS << ");\n"; 383} 384 385void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) { 386 Indent() << "@try"; 387 if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) { 388 PrintRawCompoundStmt(TS); 389 OS << "\n"; 390 } 391 392 for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) { 393 ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I); 394 Indent() << "@catch("; 395 if (catchStmt->getCatchParamDecl()) { 396 if (Decl *DS = catchStmt->getCatchParamDecl()) 397 PrintRawDecl(DS); 398 } 399 OS << ")"; 400 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) { 401 PrintRawCompoundStmt(CS); 402 OS << "\n"; 403 } 404 } 405 406 if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>( 407 Node->getFinallyStmt())) { 408 Indent() << "@finally"; 409 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody())); 410 OS << "\n"; 411 } 412} 413 414void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) { 415} 416 417void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) { 418 Indent() << "@catch (...) { /* todo */ } \n"; 419} 420 421void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) { 422 Indent() << "@throw"; 423 if (Node->getThrowExpr()) { 424 OS << " "; 425 PrintExpr(Node->getThrowExpr()); 426 } 427 OS << ";\n"; 428} 429 430void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) { 431 Indent() << "@synchronized ("; 432 PrintExpr(Node->getSynchExpr()); 433 OS << ")"; 434 PrintRawCompoundStmt(Node->getSynchBody()); 435 OS << "\n"; 436} 437 438void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) { 439 OS << "catch ("; 440 if (Decl *ExDecl = Node->getExceptionDecl()) 441 PrintRawDecl(ExDecl); 442 else 443 OS << "..."; 444 OS << ") "; 445 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock())); 446} 447 448void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) { 449 Indent(); 450 PrintRawCXXCatchStmt(Node); 451 OS << "\n"; 452} 453 454void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) { 455 Indent() << "try "; 456 PrintRawCompoundStmt(Node->getTryBlock()); 457 for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) { 458 OS << " "; 459 PrintRawCXXCatchStmt(Node->getHandler(i)); 460 } 461 OS << "\n"; 462} 463 464//===----------------------------------------------------------------------===// 465// Expr printing methods. 466//===----------------------------------------------------------------------===// 467 468void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { 469 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 470 Qualifier->print(OS, Policy); 471 OS << Node->getNameInfo(); 472 if (Node->hasExplicitTemplateArgs()) 473 OS << TemplateSpecializationType::PrintTemplateArgumentList( 474 Node->getTemplateArgs(), 475 Node->getNumTemplateArgs(), 476 Policy); 477} 478 479void StmtPrinter::VisitDependentScopeDeclRefExpr( 480 DependentScopeDeclRefExpr *Node) { 481 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 482 Qualifier->print(OS, Policy); 483 OS << Node->getNameInfo(); 484 if (Node->hasExplicitTemplateArgs()) 485 OS << TemplateSpecializationType::PrintTemplateArgumentList( 486 Node->getTemplateArgs(), 487 Node->getNumTemplateArgs(), 488 Policy); 489} 490 491void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 492 if (Node->getQualifier()) 493 Node->getQualifier()->print(OS, Policy); 494 OS << Node->getNameInfo(); 495 if (Node->hasExplicitTemplateArgs()) 496 OS << TemplateSpecializationType::PrintTemplateArgumentList( 497 Node->getTemplateArgs(), 498 Node->getNumTemplateArgs(), 499 Policy); 500} 501 502void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 503 if (Node->getBase()) { 504 PrintExpr(Node->getBase()); 505 OS << (Node->isArrow() ? "->" : "."); 506 } 507 OS << Node->getDecl(); 508} 509 510void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 511 if (Node->isSuperReceiver()) 512 OS << "super."; 513 else if (Node->getBase()) { 514 PrintExpr(Node->getBase()); 515 OS << "."; 516 } 517 518 if (Node->isImplicitProperty()) 519 OS << Node->getImplicitPropertyGetter()->getSelector().getAsString(); 520 else 521 OS << Node->getExplicitProperty()->getName(); 522} 523 524void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 525 switch (Node->getIdentType()) { 526 default: 527 assert(0 && "unknown case"); 528 case PredefinedExpr::Func: 529 OS << "__func__"; 530 break; 531 case PredefinedExpr::Function: 532 OS << "__FUNCTION__"; 533 break; 534 case PredefinedExpr::PrettyFunction: 535 OS << "__PRETTY_FUNCTION__"; 536 break; 537 } 538} 539 540void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 541 unsigned value = Node->getValue(); 542 if (Node->isWide()) 543 OS << "L"; 544 switch (value) { 545 case '\\': 546 OS << "'\\\\'"; 547 break; 548 case '\'': 549 OS << "'\\''"; 550 break; 551 case '\a': 552 // TODO: K&R: the meaning of '\\a' is different in traditional C 553 OS << "'\\a'"; 554 break; 555 case '\b': 556 OS << "'\\b'"; 557 break; 558 // Nonstandard escape sequence. 559 /*case '\e': 560 OS << "'\\e'"; 561 break;*/ 562 case '\f': 563 OS << "'\\f'"; 564 break; 565 case '\n': 566 OS << "'\\n'"; 567 break; 568 case '\r': 569 OS << "'\\r'"; 570 break; 571 case '\t': 572 OS << "'\\t'"; 573 break; 574 case '\v': 575 OS << "'\\v'"; 576 break; 577 default: 578 if (value < 256 && isprint(value)) { 579 OS << "'" << (char)value << "'"; 580 } else if (value < 256) { 581 OS << "'\\x" << llvm::format("%x", value) << "'"; 582 } else { 583 // FIXME what to really do here? 584 OS << value; 585 } 586 } 587} 588 589void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 590 bool isSigned = Node->getType()->isSignedIntegerType(); 591 OS << Node->getValue().toString(10, isSigned); 592 593 // Emit suffixes. Integer literals are always a builtin integer type. 594 switch (Node->getType()->getAs<BuiltinType>()->getKind()) { 595 default: assert(0 && "Unexpected type for integer literal!"); 596 case BuiltinType::Int: break; // no suffix. 597 case BuiltinType::UInt: OS << 'U'; break; 598 case BuiltinType::Long: OS << 'L'; break; 599 case BuiltinType::ULong: OS << "UL"; break; 600 case BuiltinType::LongLong: OS << "LL"; break; 601 case BuiltinType::ULongLong: OS << "ULL"; break; 602 } 603} 604void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 605 // FIXME: print value more precisely. 606 OS << Node->getValueAsApproximateDouble(); 607} 608 609void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 610 PrintExpr(Node->getSubExpr()); 611 OS << "i"; 612} 613 614void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 615 if (Str->isWide()) OS << 'L'; 616 OS << '"'; 617 618 // FIXME: this doesn't print wstrings right. 619 llvm::StringRef StrData = Str->getString(); 620 for (llvm::StringRef::iterator I = StrData.begin(), E = StrData.end(); 621 I != E; ++I) { 622 unsigned char Char = *I; 623 624 switch (Char) { 625 default: 626 if (isprint(Char)) 627 OS << (char)Char; 628 else // Output anything hard as an octal escape. 629 OS << '\\' 630 << (char)('0'+ ((Char >> 6) & 7)) 631 << (char)('0'+ ((Char >> 3) & 7)) 632 << (char)('0'+ ((Char >> 0) & 7)); 633 break; 634 // Handle some common non-printable cases to make dumps prettier. 635 case '\\': OS << "\\\\"; break; 636 case '"': OS << "\\\""; break; 637 case '\n': OS << "\\n"; break; 638 case '\t': OS << "\\t"; break; 639 case '\a': OS << "\\a"; break; 640 case '\b': OS << "\\b"; break; 641 } 642 } 643 OS << '"'; 644} 645void StmtPrinter::VisitParenExpr(ParenExpr *Node) { 646 OS << "("; 647 PrintExpr(Node->getSubExpr()); 648 OS << ")"; 649} 650void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 651 if (!Node->isPostfix()) { 652 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 653 654 // Print a space if this is an "identifier operator" like __real, or if 655 // it might be concatenated incorrectly like '+'. 656 switch (Node->getOpcode()) { 657 default: break; 658 case UO_Real: 659 case UO_Imag: 660 case UO_Extension: 661 OS << ' '; 662 break; 663 case UO_Plus: 664 case UO_Minus: 665 if (isa<UnaryOperator>(Node->getSubExpr())) 666 OS << ' '; 667 break; 668 } 669 } 670 PrintExpr(Node->getSubExpr()); 671 672 if (Node->isPostfix()) 673 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 674} 675 676void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) { 677 OS << "__builtin_offsetof("; 678 OS << Node->getTypeSourceInfo()->getType().getAsString(Policy) << ", "; 679 bool PrintedSomething = false; 680 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) { 681 OffsetOfExpr::OffsetOfNode ON = Node->getComponent(i); 682 if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Array) { 683 // Array node 684 OS << "["; 685 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex())); 686 OS << "]"; 687 PrintedSomething = true; 688 continue; 689 } 690 691 // Skip implicit base indirections. 692 if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Base) 693 continue; 694 695 // Field or identifier node. 696 IdentifierInfo *Id = ON.getFieldName(); 697 if (!Id) 698 continue; 699 700 if (PrintedSomething) 701 OS << "."; 702 else 703 PrintedSomething = true; 704 OS << Id->getName(); 705 } 706 OS << ")"; 707} 708 709void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { 710 OS << (Node->isSizeOf() ? "sizeof" : "__alignof"); 711 if (Node->isArgumentType()) 712 OS << "(" << Node->getArgumentType().getAsString(Policy) << ")"; 713 else { 714 OS << " "; 715 PrintExpr(Node->getArgumentExpr()); 716 } 717} 718void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 719 PrintExpr(Node->getLHS()); 720 OS << "["; 721 PrintExpr(Node->getRHS()); 722 OS << "]"; 723} 724 725void StmtPrinter::PrintCallArgs(CallExpr *Call) { 726 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 727 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 728 // Don't print any defaulted arguments 729 break; 730 } 731 732 if (i) OS << ", "; 733 PrintExpr(Call->getArg(i)); 734 } 735} 736 737void StmtPrinter::VisitCallExpr(CallExpr *Call) { 738 PrintExpr(Call->getCallee()); 739 OS << "("; 740 PrintCallArgs(Call); 741 OS << ")"; 742} 743void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 744 // FIXME: Suppress printing implicit bases (like "this") 745 PrintExpr(Node->getBase()); 746 if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl())) 747 if (FD->isAnonymousStructOrUnion()) 748 return; 749 OS << (Node->isArrow() ? "->" : "."); 750 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 751 Qualifier->print(OS, Policy); 752 753 OS << Node->getMemberNameInfo(); 754 755 if (Node->hasExplicitTemplateArgs()) 756 OS << TemplateSpecializationType::PrintTemplateArgumentList( 757 Node->getTemplateArgs(), 758 Node->getNumTemplateArgs(), 759 Policy); 760} 761void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) { 762 PrintExpr(Node->getBase()); 763 OS << (Node->isArrow() ? "->isa" : ".isa"); 764} 765 766void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 767 PrintExpr(Node->getBase()); 768 OS << "."; 769 OS << Node->getAccessor().getName(); 770} 771void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) { 772 OS << "(" << Node->getType().getAsString(Policy) << ")"; 773 PrintExpr(Node->getSubExpr()); 774} 775void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 776 OS << "(" << Node->getType().getAsString(Policy) << ")"; 777 PrintExpr(Node->getInitializer()); 778} 779void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 780 // No need to print anything, simply forward to the sub expression. 781 PrintExpr(Node->getSubExpr()); 782} 783void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 784 PrintExpr(Node->getLHS()); 785 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 786 PrintExpr(Node->getRHS()); 787} 788void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 789 PrintExpr(Node->getLHS()); 790 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 791 PrintExpr(Node->getRHS()); 792} 793void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 794 PrintExpr(Node->getCond()); 795 796 if (Node->getLHS()) { 797 OS << " ? "; 798 PrintExpr(Node->getLHS()); 799 OS << " : "; 800 } 801 else { // Handle GCC extension where LHS can be NULL. 802 OS << " ?: "; 803 } 804 805 PrintExpr(Node->getRHS()); 806} 807 808// GNU extensions. 809 810void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 811 OS << "&&" << Node->getLabel()->getName(); 812} 813 814void StmtPrinter::VisitStmtExpr(StmtExpr *E) { 815 OS << "("; 816 PrintRawCompoundStmt(E->getSubStmt()); 817 OS << ")"; 818} 819 820void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 821 OS << "__builtin_choose_expr("; 822 PrintExpr(Node->getCond()); 823 OS << ", "; 824 PrintExpr(Node->getLHS()); 825 OS << ", "; 826 PrintExpr(Node->getRHS()); 827 OS << ")"; 828} 829 830void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 831 OS << "__null"; 832} 833 834void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 835 OS << "__builtin_shufflevector("; 836 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 837 if (i) OS << ", "; 838 PrintExpr(Node->getExpr(i)); 839 } 840 OS << ")"; 841} 842 843void StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 844 if (Node->getSyntacticForm()) { 845 Visit(Node->getSyntacticForm()); 846 return; 847 } 848 849 OS << "{ "; 850 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 851 if (i) OS << ", "; 852 if (Node->getInit(i)) 853 PrintExpr(Node->getInit(i)); 854 else 855 OS << "0"; 856 } 857 OS << " }"; 858} 859 860void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { 861 OS << "( "; 862 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) { 863 if (i) OS << ", "; 864 PrintExpr(Node->getExpr(i)); 865 } 866 OS << " )"; 867} 868 869void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { 870 for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(), 871 DEnd = Node->designators_end(); 872 D != DEnd; ++D) { 873 if (D->isFieldDesignator()) { 874 if (D->getDotLoc().isInvalid()) 875 OS << D->getFieldName()->getName() << ":"; 876 else 877 OS << "." << D->getFieldName()->getName(); 878 } else { 879 OS << "["; 880 if (D->isArrayDesignator()) { 881 PrintExpr(Node->getArrayIndex(*D)); 882 } else { 883 PrintExpr(Node->getArrayRangeStart(*D)); 884 OS << " ... "; 885 PrintExpr(Node->getArrayRangeEnd(*D)); 886 } 887 OS << "]"; 888 } 889 } 890 891 OS << " = "; 892 PrintExpr(Node->getInit()); 893} 894 895void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { 896 if (Policy.LangOpts.CPlusPlus) 897 OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()"; 898 else { 899 OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")"; 900 if (Node->getType()->isRecordType()) 901 OS << "{}"; 902 else 903 OS << 0; 904 } 905} 906 907void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 908 OS << "__builtin_va_arg("; 909 PrintExpr(Node->getSubExpr()); 910 OS << ", "; 911 OS << Node->getType().getAsString(Policy); 912 OS << ")"; 913} 914 915// C++ 916void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 917 const char *OpStrings[NUM_OVERLOADED_OPERATORS] = { 918 "", 919#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 920 Spelling, 921#include "clang/Basic/OperatorKinds.def" 922 }; 923 924 OverloadedOperatorKind Kind = Node->getOperator(); 925 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 926 if (Node->getNumArgs() == 1) { 927 OS << OpStrings[Kind] << ' '; 928 PrintExpr(Node->getArg(0)); 929 } else { 930 PrintExpr(Node->getArg(0)); 931 OS << ' ' << OpStrings[Kind]; 932 } 933 } else if (Kind == OO_Call) { 934 PrintExpr(Node->getArg(0)); 935 OS << '('; 936 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 937 if (ArgIdx > 1) 938 OS << ", "; 939 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 940 PrintExpr(Node->getArg(ArgIdx)); 941 } 942 OS << ')'; 943 } else if (Kind == OO_Subscript) { 944 PrintExpr(Node->getArg(0)); 945 OS << '['; 946 PrintExpr(Node->getArg(1)); 947 OS << ']'; 948 } else if (Node->getNumArgs() == 1) { 949 OS << OpStrings[Kind] << ' '; 950 PrintExpr(Node->getArg(0)); 951 } else if (Node->getNumArgs() == 2) { 952 PrintExpr(Node->getArg(0)); 953 OS << ' ' << OpStrings[Kind] << ' '; 954 PrintExpr(Node->getArg(1)); 955 } else { 956 assert(false && "unknown overloaded operator"); 957 } 958} 959 960void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 961 VisitCallExpr(cast<CallExpr>(Node)); 962} 963 964void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) { 965 PrintExpr(Node->getCallee()); 966 OS << "<<<"; 967 PrintCallArgs(Node->getConfig()); 968 OS << ">>>("; 969 PrintCallArgs(Node); 970 OS << ")"; 971} 972 973void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 974 OS << Node->getCastName() << '<'; 975 OS << Node->getTypeAsWritten().getAsString(Policy) << ">("; 976 PrintExpr(Node->getSubExpr()); 977 OS << ")"; 978} 979 980void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 981 VisitCXXNamedCastExpr(Node); 982} 983 984void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 985 VisitCXXNamedCastExpr(Node); 986} 987 988void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 989 VisitCXXNamedCastExpr(Node); 990} 991 992void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 993 VisitCXXNamedCastExpr(Node); 994} 995 996void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 997 OS << "typeid("; 998 if (Node->isTypeOperand()) { 999 OS << Node->getTypeOperand().getAsString(Policy); 1000 } else { 1001 PrintExpr(Node->getExprOperand()); 1002 } 1003 OS << ")"; 1004} 1005 1006void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) { 1007 OS << "__uuidof("; 1008 if (Node->isTypeOperand()) { 1009 OS << Node->getTypeOperand().getAsString(Policy); 1010 } else { 1011 PrintExpr(Node->getExprOperand()); 1012 } 1013 OS << ")"; 1014} 1015 1016void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 1017 OS << (Node->getValue() ? "true" : "false"); 1018} 1019 1020void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 1021 OS << "nullptr"; 1022} 1023 1024void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 1025 OS << "this"; 1026} 1027 1028void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 1029 if (Node->getSubExpr() == 0) 1030 OS << "throw"; 1031 else { 1032 OS << "throw "; 1033 PrintExpr(Node->getSubExpr()); 1034 } 1035} 1036 1037void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 1038 // Nothing to print: we picked up the default argument 1039} 1040 1041void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 1042 OS << Node->getType().getAsString(Policy); 1043 OS << "("; 1044 PrintExpr(Node->getSubExpr()); 1045 OS << ")"; 1046} 1047 1048void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 1049 PrintExpr(Node->getSubExpr()); 1050} 1051 1052void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 1053 OS << Node->getType().getAsString(Policy); 1054 OS << "("; 1055 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 1056 ArgEnd = Node->arg_end(); 1057 Arg != ArgEnd; ++Arg) { 1058 if (Arg != Node->arg_begin()) 1059 OS << ", "; 1060 PrintExpr(*Arg); 1061 } 1062 OS << ")"; 1063} 1064 1065void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { 1066 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo()) 1067 OS << TSInfo->getType().getAsString(Policy) << "()"; 1068 else 1069 OS << Node->getType().getAsString(Policy) << "()"; 1070} 1071 1072void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 1073 if (E->isGlobalNew()) 1074 OS << "::"; 1075 OS << "new "; 1076 unsigned NumPlace = E->getNumPlacementArgs(); 1077 if (NumPlace > 0) { 1078 OS << "("; 1079 PrintExpr(E->getPlacementArg(0)); 1080 for (unsigned i = 1; i < NumPlace; ++i) { 1081 OS << ", "; 1082 PrintExpr(E->getPlacementArg(i)); 1083 } 1084 OS << ") "; 1085 } 1086 if (E->isParenTypeId()) 1087 OS << "("; 1088 std::string TypeS; 1089 if (Expr *Size = E->getArraySize()) { 1090 llvm::raw_string_ostream s(TypeS); 1091 Size->printPretty(s, Context, Helper, Policy); 1092 s.flush(); 1093 TypeS = "[" + TypeS + "]"; 1094 } 1095 E->getAllocatedType().getAsStringInternal(TypeS, Policy); 1096 OS << TypeS; 1097 if (E->isParenTypeId()) 1098 OS << ")"; 1099 1100 if (E->hasInitializer()) { 1101 OS << "("; 1102 unsigned NumCons = E->getNumConstructorArgs(); 1103 if (NumCons > 0) { 1104 PrintExpr(E->getConstructorArg(0)); 1105 for (unsigned i = 1; i < NumCons; ++i) { 1106 OS << ", "; 1107 PrintExpr(E->getConstructorArg(i)); 1108 } 1109 } 1110 OS << ")"; 1111 } 1112} 1113 1114void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 1115 if (E->isGlobalDelete()) 1116 OS << "::"; 1117 OS << "delete "; 1118 if (E->isArrayForm()) 1119 OS << "[] "; 1120 PrintExpr(E->getArgument()); 1121} 1122 1123void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 1124 PrintExpr(E->getBase()); 1125 if (E->isArrow()) 1126 OS << "->"; 1127 else 1128 OS << '.'; 1129 if (E->getQualifier()) 1130 E->getQualifier()->print(OS, Policy); 1131 1132 std::string TypeS; 1133 if (IdentifierInfo *II = E->getDestroyedTypeIdentifier()) 1134 OS << II->getName(); 1135 else 1136 E->getDestroyedType().getAsStringInternal(TypeS, Policy); 1137 OS << TypeS; 1138} 1139 1140void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 1141 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 1142 if (isa<CXXDefaultArgExpr>(E->getArg(i))) { 1143 // Don't print any defaulted arguments 1144 break; 1145 } 1146 1147 if (i) OS << ", "; 1148 PrintExpr(E->getArg(i)); 1149 } 1150} 1151 1152void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) { 1153 // Just forward to the sub expression. 1154 PrintExpr(E->getSubExpr()); 1155} 1156 1157void 1158StmtPrinter::VisitCXXUnresolvedConstructExpr( 1159 CXXUnresolvedConstructExpr *Node) { 1160 OS << Node->getTypeAsWritten().getAsString(Policy); 1161 OS << "("; 1162 for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(), 1163 ArgEnd = Node->arg_end(); 1164 Arg != ArgEnd; ++Arg) { 1165 if (Arg != Node->arg_begin()) 1166 OS << ", "; 1167 PrintExpr(*Arg); 1168 } 1169 OS << ")"; 1170} 1171 1172void StmtPrinter::VisitCXXDependentScopeMemberExpr( 1173 CXXDependentScopeMemberExpr *Node) { 1174 if (!Node->isImplicitAccess()) { 1175 PrintExpr(Node->getBase()); 1176 OS << (Node->isArrow() ? "->" : "."); 1177 } 1178 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1179 Qualifier->print(OS, Policy); 1180 else if (Node->hasExplicitTemplateArgs()) 1181 // FIXME: Track use of "template" keyword explicitly? 1182 OS << "template "; 1183 1184 OS << Node->getMemberNameInfo(); 1185 1186 if (Node->hasExplicitTemplateArgs()) { 1187 OS << TemplateSpecializationType::PrintTemplateArgumentList( 1188 Node->getTemplateArgs(), 1189 Node->getNumTemplateArgs(), 1190 Policy); 1191 } 1192} 1193 1194void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 1195 if (!Node->isImplicitAccess()) { 1196 PrintExpr(Node->getBase()); 1197 OS << (Node->isArrow() ? "->" : "."); 1198 } 1199 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1200 Qualifier->print(OS, Policy); 1201 1202 // FIXME: this might originally have been written with 'template' 1203 1204 OS << Node->getMemberNameInfo(); 1205 1206 if (Node->hasExplicitTemplateArgs()) { 1207 OS << TemplateSpecializationType::PrintTemplateArgumentList( 1208 Node->getTemplateArgs(), 1209 Node->getNumTemplateArgs(), 1210 Policy); 1211 } 1212} 1213 1214static const char *getTypeTraitName(UnaryTypeTrait UTT) { 1215 switch (UTT) { 1216 default: llvm_unreachable("Unknown unary type trait"); 1217 case UTT_HasNothrowAssign: return "__has_nothrow_assign"; 1218 case UTT_HasNothrowCopy: return "__has_nothrow_copy"; 1219 case UTT_HasNothrowConstructor: return "__has_nothrow_constructor"; 1220 case UTT_HasTrivialAssign: return "__has_trivial_assign"; 1221 case UTT_HasTrivialCopy: return "__has_trivial_copy"; 1222 case UTT_HasTrivialConstructor: return "__has_trivial_constructor"; 1223 case UTT_HasTrivialDestructor: return "__has_trivial_destructor"; 1224 case UTT_HasVirtualDestructor: return "__has_virtual_destructor"; 1225 case UTT_IsAbstract: return "__is_abstract"; 1226 case UTT_IsClass: return "__is_class"; 1227 case UTT_IsEmpty: return "__is_empty"; 1228 case UTT_IsEnum: return "__is_enum"; 1229 case UTT_IsPOD: return "__is_pod"; 1230 case UTT_IsPolymorphic: return "__is_polymorphic"; 1231 case UTT_IsUnion: return "__is_union"; 1232 } 1233 return ""; 1234} 1235 1236static const char *getTypeTraitName(BinaryTypeTrait BTT) { 1237 switch (BTT) { 1238 case BTT_IsBaseOf: return "__is_base_of"; 1239 case BTT_TypeCompatible: return "__builtin_types_compatible_p"; 1240 case BTT_IsConvertibleTo: return "__is_convertible_to"; 1241 } 1242 return ""; 1243} 1244 1245void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { 1246 OS << getTypeTraitName(E->getTrait()) << "(" 1247 << E->getQueriedType().getAsString(Policy) << ")"; 1248} 1249 1250void StmtPrinter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { 1251 OS << getTypeTraitName(E->getTrait()) << "(" 1252 << E->getLhsType().getAsString(Policy) << "," 1253 << E->getRhsType().getAsString(Policy) << ")"; 1254} 1255 1256void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { 1257 OS << "noexcept("; 1258 PrintExpr(E->getOperand()); 1259 OS << ")"; 1260} 1261 1262void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) { 1263 PrintExpr(E->getPattern()); 1264 OS << "..."; 1265} 1266 1267void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { 1268 OS << "sizeof...(" << E->getPack()->getNameAsString() << ")"; 1269} 1270 1271void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr( 1272 SubstNonTypeTemplateParmPackExpr *Node) { 1273 OS << Node->getParameterPack()->getNameAsString(); 1274} 1275 1276// Obj-C 1277 1278void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 1279 OS << "@"; 1280 VisitStringLiteral(Node->getString()); 1281} 1282 1283void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 1284 OS << "@encode(" << Node->getEncodedType().getAsString(Policy) << ')'; 1285} 1286 1287void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 1288 OS << "@selector(" << Node->getSelector().getAsString() << ')'; 1289} 1290 1291void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 1292 OS << "@protocol(" << Node->getProtocol() << ')'; 1293} 1294 1295void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 1296 OS << "["; 1297 switch (Mess->getReceiverKind()) { 1298 case ObjCMessageExpr::Instance: 1299 PrintExpr(Mess->getInstanceReceiver()); 1300 break; 1301 1302 case ObjCMessageExpr::Class: 1303 OS << Mess->getClassReceiver().getAsString(Policy); 1304 break; 1305 1306 case ObjCMessageExpr::SuperInstance: 1307 case ObjCMessageExpr::SuperClass: 1308 OS << "Super"; 1309 break; 1310 } 1311 1312 OS << ' '; 1313 Selector selector = Mess->getSelector(); 1314 if (selector.isUnarySelector()) { 1315 OS << selector.getIdentifierInfoForSlot(0)->getName(); 1316 } else { 1317 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 1318 if (i < selector.getNumArgs()) { 1319 if (i > 0) OS << ' '; 1320 if (selector.getIdentifierInfoForSlot(i)) 1321 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 1322 else 1323 OS << ":"; 1324 } 1325 else OS << ", "; // Handle variadic methods. 1326 1327 PrintExpr(Mess->getArg(i)); 1328 } 1329 } 1330 OS << "]"; 1331} 1332 1333 1334void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 1335 BlockDecl *BD = Node->getBlockDecl(); 1336 OS << "^"; 1337 1338 const FunctionType *AFT = Node->getFunctionType(); 1339 1340 if (isa<FunctionNoProtoType>(AFT)) { 1341 OS << "()"; 1342 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 1343 OS << '('; 1344 std::string ParamStr; 1345 for (BlockDecl::param_iterator AI = BD->param_begin(), 1346 E = BD->param_end(); AI != E; ++AI) { 1347 if (AI != BD->param_begin()) OS << ", "; 1348 ParamStr = (*AI)->getNameAsString(); 1349 (*AI)->getType().getAsStringInternal(ParamStr, Policy); 1350 OS << ParamStr; 1351 } 1352 1353 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 1354 if (FT->isVariadic()) { 1355 if (!BD->param_empty()) OS << ", "; 1356 OS << "..."; 1357 } 1358 OS << ')'; 1359 } 1360} 1361 1362void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) { 1363 OS << Node->getDecl(); 1364} 1365 1366void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {} 1367 1368//===----------------------------------------------------------------------===// 1369// Stmt method implementations 1370//===----------------------------------------------------------------------===// 1371 1372void Stmt::dumpPretty(ASTContext& Context) const { 1373 printPretty(llvm::errs(), Context, 0, 1374 PrintingPolicy(Context.getLangOptions())); 1375} 1376 1377void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context, 1378 PrinterHelper* Helper, 1379 const PrintingPolicy &Policy, 1380 unsigned Indentation) const { 1381 if (this == 0) { 1382 OS << "<NULL>"; 1383 return; 1384 } 1385 1386 if (Policy.Dump && &Context) { 1387 dump(OS, Context.getSourceManager()); 1388 return; 1389 } 1390 1391 StmtPrinter P(OS, Context, Helper, Policy, Indentation); 1392 P.Visit(const_cast<Stmt*>(this)); 1393} 1394 1395//===----------------------------------------------------------------------===// 1396// PrinterHelper 1397//===----------------------------------------------------------------------===// 1398 1399// Implement virtual destructor. 1400PrinterHelper::~PrinterHelper() {} 1401