StmtPrinter.cpp revision 63c00d7f35fa060c0a446c9df3a4402d9c7757fe
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::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 965 OS << Node->getCastName() << '<'; 966 OS << Node->getTypeAsWritten().getAsString(Policy) << ">("; 967 PrintExpr(Node->getSubExpr()); 968 OS << ")"; 969} 970 971void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 972 VisitCXXNamedCastExpr(Node); 973} 974 975void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 976 VisitCXXNamedCastExpr(Node); 977} 978 979void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 980 VisitCXXNamedCastExpr(Node); 981} 982 983void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 984 VisitCXXNamedCastExpr(Node); 985} 986 987void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 988 OS << "typeid("; 989 if (Node->isTypeOperand()) { 990 OS << Node->getTypeOperand().getAsString(Policy); 991 } else { 992 PrintExpr(Node->getExprOperand()); 993 } 994 OS << ")"; 995} 996 997void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) { 998 OS << "__uuidof("; 999 if (Node->isTypeOperand()) { 1000 OS << Node->getTypeOperand().getAsString(Policy); 1001 } else { 1002 PrintExpr(Node->getExprOperand()); 1003 } 1004 OS << ")"; 1005} 1006 1007void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 1008 OS << (Node->getValue() ? "true" : "false"); 1009} 1010 1011void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 1012 OS << "nullptr"; 1013} 1014 1015void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 1016 OS << "this"; 1017} 1018 1019void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 1020 if (Node->getSubExpr() == 0) 1021 OS << "throw"; 1022 else { 1023 OS << "throw "; 1024 PrintExpr(Node->getSubExpr()); 1025 } 1026} 1027 1028void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 1029 // Nothing to print: we picked up the default argument 1030} 1031 1032void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 1033 OS << Node->getType().getAsString(Policy); 1034 OS << "("; 1035 PrintExpr(Node->getSubExpr()); 1036 OS << ")"; 1037} 1038 1039void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 1040 PrintExpr(Node->getSubExpr()); 1041} 1042 1043void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 1044 OS << Node->getType().getAsString(Policy); 1045 OS << "("; 1046 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 1047 ArgEnd = Node->arg_end(); 1048 Arg != ArgEnd; ++Arg) { 1049 if (Arg != Node->arg_begin()) 1050 OS << ", "; 1051 PrintExpr(*Arg); 1052 } 1053 OS << ")"; 1054} 1055 1056void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { 1057 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo()) 1058 OS << TSInfo->getType().getAsString(Policy) << "()"; 1059 else 1060 OS << Node->getType().getAsString(Policy) << "()"; 1061} 1062 1063void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 1064 if (E->isGlobalNew()) 1065 OS << "::"; 1066 OS << "new "; 1067 unsigned NumPlace = E->getNumPlacementArgs(); 1068 if (NumPlace > 0) { 1069 OS << "("; 1070 PrintExpr(E->getPlacementArg(0)); 1071 for (unsigned i = 1; i < NumPlace; ++i) { 1072 OS << ", "; 1073 PrintExpr(E->getPlacementArg(i)); 1074 } 1075 OS << ") "; 1076 } 1077 if (E->isParenTypeId()) 1078 OS << "("; 1079 std::string TypeS; 1080 if (Expr *Size = E->getArraySize()) { 1081 llvm::raw_string_ostream s(TypeS); 1082 Size->printPretty(s, Context, Helper, Policy); 1083 s.flush(); 1084 TypeS = "[" + TypeS + "]"; 1085 } 1086 E->getAllocatedType().getAsStringInternal(TypeS, Policy); 1087 OS << TypeS; 1088 if (E->isParenTypeId()) 1089 OS << ")"; 1090 1091 if (E->hasInitializer()) { 1092 OS << "("; 1093 unsigned NumCons = E->getNumConstructorArgs(); 1094 if (NumCons > 0) { 1095 PrintExpr(E->getConstructorArg(0)); 1096 for (unsigned i = 1; i < NumCons; ++i) { 1097 OS << ", "; 1098 PrintExpr(E->getConstructorArg(i)); 1099 } 1100 } 1101 OS << ")"; 1102 } 1103} 1104 1105void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 1106 if (E->isGlobalDelete()) 1107 OS << "::"; 1108 OS << "delete "; 1109 if (E->isArrayForm()) 1110 OS << "[] "; 1111 PrintExpr(E->getArgument()); 1112} 1113 1114void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 1115 PrintExpr(E->getBase()); 1116 if (E->isArrow()) 1117 OS << "->"; 1118 else 1119 OS << '.'; 1120 if (E->getQualifier()) 1121 E->getQualifier()->print(OS, Policy); 1122 1123 std::string TypeS; 1124 if (IdentifierInfo *II = E->getDestroyedTypeIdentifier()) 1125 OS << II->getName(); 1126 else 1127 E->getDestroyedType().getAsStringInternal(TypeS, Policy); 1128 OS << TypeS; 1129} 1130 1131void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 1132 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 1133 if (isa<CXXDefaultArgExpr>(E->getArg(i))) { 1134 // Don't print any defaulted arguments 1135 break; 1136 } 1137 1138 if (i) OS << ", "; 1139 PrintExpr(E->getArg(i)); 1140 } 1141} 1142 1143void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) { 1144 // Just forward to the sub expression. 1145 PrintExpr(E->getSubExpr()); 1146} 1147 1148void 1149StmtPrinter::VisitCXXUnresolvedConstructExpr( 1150 CXXUnresolvedConstructExpr *Node) { 1151 OS << Node->getTypeAsWritten().getAsString(Policy); 1152 OS << "("; 1153 for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(), 1154 ArgEnd = Node->arg_end(); 1155 Arg != ArgEnd; ++Arg) { 1156 if (Arg != Node->arg_begin()) 1157 OS << ", "; 1158 PrintExpr(*Arg); 1159 } 1160 OS << ")"; 1161} 1162 1163void StmtPrinter::VisitCXXDependentScopeMemberExpr( 1164 CXXDependentScopeMemberExpr *Node) { 1165 if (!Node->isImplicitAccess()) { 1166 PrintExpr(Node->getBase()); 1167 OS << (Node->isArrow() ? "->" : "."); 1168 } 1169 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1170 Qualifier->print(OS, Policy); 1171 else if (Node->hasExplicitTemplateArgs()) 1172 // FIXME: Track use of "template" keyword explicitly? 1173 OS << "template "; 1174 1175 OS << Node->getMemberNameInfo(); 1176 1177 if (Node->hasExplicitTemplateArgs()) { 1178 OS << TemplateSpecializationType::PrintTemplateArgumentList( 1179 Node->getTemplateArgs(), 1180 Node->getNumTemplateArgs(), 1181 Policy); 1182 } 1183} 1184 1185void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 1186 if (!Node->isImplicitAccess()) { 1187 PrintExpr(Node->getBase()); 1188 OS << (Node->isArrow() ? "->" : "."); 1189 } 1190 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1191 Qualifier->print(OS, Policy); 1192 1193 // FIXME: this might originally have been written with 'template' 1194 1195 OS << Node->getMemberNameInfo(); 1196 1197 if (Node->hasExplicitTemplateArgs()) { 1198 OS << TemplateSpecializationType::PrintTemplateArgumentList( 1199 Node->getTemplateArgs(), 1200 Node->getNumTemplateArgs(), 1201 Policy); 1202 } 1203} 1204 1205static const char *getTypeTraitName(UnaryTypeTrait UTT) { 1206 switch (UTT) { 1207 default: llvm_unreachable("Unknown unary type trait"); 1208 case UTT_HasNothrowAssign: return "__has_nothrow_assign"; 1209 case UTT_HasNothrowCopy: return "__has_nothrow_copy"; 1210 case UTT_HasNothrowConstructor: return "__has_nothrow_constructor"; 1211 case UTT_HasTrivialAssign: return "__has_trivial_assign"; 1212 case UTT_HasTrivialCopy: return "__has_trivial_copy"; 1213 case UTT_HasTrivialConstructor: return "__has_trivial_constructor"; 1214 case UTT_HasTrivialDestructor: return "__has_trivial_destructor"; 1215 case UTT_HasVirtualDestructor: return "__has_virtual_destructor"; 1216 case UTT_IsAbstract: return "__is_abstract"; 1217 case UTT_IsClass: return "__is_class"; 1218 case UTT_IsEmpty: return "__is_empty"; 1219 case UTT_IsEnum: return "__is_enum"; 1220 case UTT_IsPOD: return "__is_pod"; 1221 case UTT_IsPolymorphic: return "__is_polymorphic"; 1222 case UTT_IsUnion: return "__is_union"; 1223 } 1224 return ""; 1225} 1226 1227static const char *getTypeTraitName(BinaryTypeTrait BTT) { 1228 switch (BTT) { 1229 case BTT_IsBaseOf: return "__is_base_of"; 1230 case BTT_TypeCompatible: return "__builtin_types_compatible_p"; 1231 case BTT_IsConvertibleTo: return "__is_convertible_to"; 1232 } 1233 return ""; 1234} 1235 1236void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { 1237 OS << getTypeTraitName(E->getTrait()) << "(" 1238 << E->getQueriedType().getAsString(Policy) << ")"; 1239} 1240 1241void StmtPrinter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { 1242 OS << getTypeTraitName(E->getTrait()) << "(" 1243 << E->getLhsType().getAsString(Policy) << "," 1244 << E->getRhsType().getAsString(Policy) << ")"; 1245} 1246 1247void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { 1248 OS << "noexcept("; 1249 PrintExpr(E->getOperand()); 1250 OS << ")"; 1251} 1252 1253void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) { 1254 PrintExpr(E->getPattern()); 1255 OS << "..."; 1256} 1257 1258void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { 1259 OS << "sizeof...(" << E->getPack()->getNameAsString() << ")"; 1260} 1261 1262void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr( 1263 SubstNonTypeTemplateParmPackExpr *Node) { 1264 OS << Node->getParameterPack()->getNameAsString(); 1265} 1266 1267// Obj-C 1268 1269void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 1270 OS << "@"; 1271 VisitStringLiteral(Node->getString()); 1272} 1273 1274void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 1275 OS << "@encode(" << Node->getEncodedType().getAsString(Policy) << ')'; 1276} 1277 1278void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 1279 OS << "@selector(" << Node->getSelector().getAsString() << ')'; 1280} 1281 1282void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 1283 OS << "@protocol(" << Node->getProtocol() << ')'; 1284} 1285 1286void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 1287 OS << "["; 1288 switch (Mess->getReceiverKind()) { 1289 case ObjCMessageExpr::Instance: 1290 PrintExpr(Mess->getInstanceReceiver()); 1291 break; 1292 1293 case ObjCMessageExpr::Class: 1294 OS << Mess->getClassReceiver().getAsString(Policy); 1295 break; 1296 1297 case ObjCMessageExpr::SuperInstance: 1298 case ObjCMessageExpr::SuperClass: 1299 OS << "Super"; 1300 break; 1301 } 1302 1303 OS << ' '; 1304 Selector selector = Mess->getSelector(); 1305 if (selector.isUnarySelector()) { 1306 OS << selector.getIdentifierInfoForSlot(0)->getName(); 1307 } else { 1308 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 1309 if (i < selector.getNumArgs()) { 1310 if (i > 0) OS << ' '; 1311 if (selector.getIdentifierInfoForSlot(i)) 1312 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 1313 else 1314 OS << ":"; 1315 } 1316 else OS << ", "; // Handle variadic methods. 1317 1318 PrintExpr(Mess->getArg(i)); 1319 } 1320 } 1321 OS << "]"; 1322} 1323 1324 1325void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 1326 BlockDecl *BD = Node->getBlockDecl(); 1327 OS << "^"; 1328 1329 const FunctionType *AFT = Node->getFunctionType(); 1330 1331 if (isa<FunctionNoProtoType>(AFT)) { 1332 OS << "()"; 1333 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 1334 OS << '('; 1335 std::string ParamStr; 1336 for (BlockDecl::param_iterator AI = BD->param_begin(), 1337 E = BD->param_end(); AI != E; ++AI) { 1338 if (AI != BD->param_begin()) OS << ", "; 1339 ParamStr = (*AI)->getNameAsString(); 1340 (*AI)->getType().getAsStringInternal(ParamStr, Policy); 1341 OS << ParamStr; 1342 } 1343 1344 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 1345 if (FT->isVariadic()) { 1346 if (!BD->param_empty()) OS << ", "; 1347 OS << "..."; 1348 } 1349 OS << ')'; 1350 } 1351} 1352 1353void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) { 1354 OS << Node->getDecl(); 1355} 1356 1357void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {} 1358 1359//===----------------------------------------------------------------------===// 1360// Stmt method implementations 1361//===----------------------------------------------------------------------===// 1362 1363void Stmt::dumpPretty(ASTContext& Context) const { 1364 printPretty(llvm::errs(), Context, 0, 1365 PrintingPolicy(Context.getLangOptions())); 1366} 1367 1368void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context, 1369 PrinterHelper* Helper, 1370 const PrintingPolicy &Policy, 1371 unsigned Indentation) const { 1372 if (this == 0) { 1373 OS << "<NULL>"; 1374 return; 1375 } 1376 1377 if (Policy.Dump && &Context) { 1378 dump(OS, Context.getSourceManager()); 1379 return; 1380 } 1381 1382 StmtPrinter P(OS, Context, Helper, Policy, Indentation); 1383 P.Visit(const_cast<Stmt*>(this)); 1384} 1385 1386//===----------------------------------------------------------------------===// 1387// PrinterHelper 1388//===----------------------------------------------------------------------===// 1389 1390// Implement virtual destructor. 1391PrinterHelper::~PrinterHelper() {} 1392