StmtPrinter.cpp revision 56ca35d396d8692c384c785f9aeebcf22563fe1e
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 OS << " ? "; 796 PrintExpr(Node->getLHS()); 797 OS << " : "; 798 PrintExpr(Node->getRHS()); 799} 800 801// GNU extensions. 802 803void 804StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) { 805 PrintExpr(Node->getCommon()); 806 OS << " ?: "; 807 PrintExpr(Node->getFalseExpr()); 808} 809void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 810 OS << "&&" << Node->getLabel()->getName(); 811} 812 813void StmtPrinter::VisitStmtExpr(StmtExpr *E) { 814 OS << "("; 815 PrintRawCompoundStmt(E->getSubStmt()); 816 OS << ")"; 817} 818 819void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 820 OS << "__builtin_choose_expr("; 821 PrintExpr(Node->getCond()); 822 OS << ", "; 823 PrintExpr(Node->getLHS()); 824 OS << ", "; 825 PrintExpr(Node->getRHS()); 826 OS << ")"; 827} 828 829void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 830 OS << "__null"; 831} 832 833void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 834 OS << "__builtin_shufflevector("; 835 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 836 if (i) OS << ", "; 837 PrintExpr(Node->getExpr(i)); 838 } 839 OS << ")"; 840} 841 842void StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 843 if (Node->getSyntacticForm()) { 844 Visit(Node->getSyntacticForm()); 845 return; 846 } 847 848 OS << "{ "; 849 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 850 if (i) OS << ", "; 851 if (Node->getInit(i)) 852 PrintExpr(Node->getInit(i)); 853 else 854 OS << "0"; 855 } 856 OS << " }"; 857} 858 859void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { 860 OS << "( "; 861 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) { 862 if (i) OS << ", "; 863 PrintExpr(Node->getExpr(i)); 864 } 865 OS << " )"; 866} 867 868void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { 869 for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(), 870 DEnd = Node->designators_end(); 871 D != DEnd; ++D) { 872 if (D->isFieldDesignator()) { 873 if (D->getDotLoc().isInvalid()) 874 OS << D->getFieldName()->getName() << ":"; 875 else 876 OS << "." << D->getFieldName()->getName(); 877 } else { 878 OS << "["; 879 if (D->isArrayDesignator()) { 880 PrintExpr(Node->getArrayIndex(*D)); 881 } else { 882 PrintExpr(Node->getArrayRangeStart(*D)); 883 OS << " ... "; 884 PrintExpr(Node->getArrayRangeEnd(*D)); 885 } 886 OS << "]"; 887 } 888 } 889 890 OS << " = "; 891 PrintExpr(Node->getInit()); 892} 893 894void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { 895 if (Policy.LangOpts.CPlusPlus) 896 OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()"; 897 else { 898 OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")"; 899 if (Node->getType()->isRecordType()) 900 OS << "{}"; 901 else 902 OS << 0; 903 } 904} 905 906void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 907 OS << "__builtin_va_arg("; 908 PrintExpr(Node->getSubExpr()); 909 OS << ", "; 910 OS << Node->getType().getAsString(Policy); 911 OS << ")"; 912} 913 914// C++ 915void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 916 const char *OpStrings[NUM_OVERLOADED_OPERATORS] = { 917 "", 918#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 919 Spelling, 920#include "clang/Basic/OperatorKinds.def" 921 }; 922 923 OverloadedOperatorKind Kind = Node->getOperator(); 924 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 925 if (Node->getNumArgs() == 1) { 926 OS << OpStrings[Kind] << ' '; 927 PrintExpr(Node->getArg(0)); 928 } else { 929 PrintExpr(Node->getArg(0)); 930 OS << ' ' << OpStrings[Kind]; 931 } 932 } else if (Kind == OO_Call) { 933 PrintExpr(Node->getArg(0)); 934 OS << '('; 935 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 936 if (ArgIdx > 1) 937 OS << ", "; 938 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 939 PrintExpr(Node->getArg(ArgIdx)); 940 } 941 OS << ')'; 942 } else if (Kind == OO_Subscript) { 943 PrintExpr(Node->getArg(0)); 944 OS << '['; 945 PrintExpr(Node->getArg(1)); 946 OS << ']'; 947 } else if (Node->getNumArgs() == 1) { 948 OS << OpStrings[Kind] << ' '; 949 PrintExpr(Node->getArg(0)); 950 } else if (Node->getNumArgs() == 2) { 951 PrintExpr(Node->getArg(0)); 952 OS << ' ' << OpStrings[Kind] << ' '; 953 PrintExpr(Node->getArg(1)); 954 } else { 955 assert(false && "unknown overloaded operator"); 956 } 957} 958 959void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 960 VisitCallExpr(cast<CallExpr>(Node)); 961} 962 963void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) { 964 PrintExpr(Node->getCallee()); 965 OS << "<<<"; 966 PrintCallArgs(Node->getConfig()); 967 OS << ">>>("; 968 PrintCallArgs(Node); 969 OS << ")"; 970} 971 972void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 973 OS << Node->getCastName() << '<'; 974 OS << Node->getTypeAsWritten().getAsString(Policy) << ">("; 975 PrintExpr(Node->getSubExpr()); 976 OS << ")"; 977} 978 979void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 980 VisitCXXNamedCastExpr(Node); 981} 982 983void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 984 VisitCXXNamedCastExpr(Node); 985} 986 987void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 988 VisitCXXNamedCastExpr(Node); 989} 990 991void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 992 VisitCXXNamedCastExpr(Node); 993} 994 995void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 996 OS << "typeid("; 997 if (Node->isTypeOperand()) { 998 OS << Node->getTypeOperand().getAsString(Policy); 999 } else { 1000 PrintExpr(Node->getExprOperand()); 1001 } 1002 OS << ")"; 1003} 1004 1005void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) { 1006 OS << "__uuidof("; 1007 if (Node->isTypeOperand()) { 1008 OS << Node->getTypeOperand().getAsString(Policy); 1009 } else { 1010 PrintExpr(Node->getExprOperand()); 1011 } 1012 OS << ")"; 1013} 1014 1015void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 1016 OS << (Node->getValue() ? "true" : "false"); 1017} 1018 1019void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 1020 OS << "nullptr"; 1021} 1022 1023void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 1024 OS << "this"; 1025} 1026 1027void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 1028 if (Node->getSubExpr() == 0) 1029 OS << "throw"; 1030 else { 1031 OS << "throw "; 1032 PrintExpr(Node->getSubExpr()); 1033 } 1034} 1035 1036void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 1037 // Nothing to print: we picked up the default argument 1038} 1039 1040void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 1041 OS << Node->getType().getAsString(Policy); 1042 OS << "("; 1043 PrintExpr(Node->getSubExpr()); 1044 OS << ")"; 1045} 1046 1047void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 1048 PrintExpr(Node->getSubExpr()); 1049} 1050 1051void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 1052 OS << Node->getType().getAsString(Policy); 1053 OS << "("; 1054 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 1055 ArgEnd = Node->arg_end(); 1056 Arg != ArgEnd; ++Arg) { 1057 if (Arg != Node->arg_begin()) 1058 OS << ", "; 1059 PrintExpr(*Arg); 1060 } 1061 OS << ")"; 1062} 1063 1064void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { 1065 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo()) 1066 OS << TSInfo->getType().getAsString(Policy) << "()"; 1067 else 1068 OS << Node->getType().getAsString(Policy) << "()"; 1069} 1070 1071void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 1072 if (E->isGlobalNew()) 1073 OS << "::"; 1074 OS << "new "; 1075 unsigned NumPlace = E->getNumPlacementArgs(); 1076 if (NumPlace > 0) { 1077 OS << "("; 1078 PrintExpr(E->getPlacementArg(0)); 1079 for (unsigned i = 1; i < NumPlace; ++i) { 1080 OS << ", "; 1081 PrintExpr(E->getPlacementArg(i)); 1082 } 1083 OS << ") "; 1084 } 1085 if (E->isParenTypeId()) 1086 OS << "("; 1087 std::string TypeS; 1088 if (Expr *Size = E->getArraySize()) { 1089 llvm::raw_string_ostream s(TypeS); 1090 Size->printPretty(s, Context, Helper, Policy); 1091 s.flush(); 1092 TypeS = "[" + TypeS + "]"; 1093 } 1094 E->getAllocatedType().getAsStringInternal(TypeS, Policy); 1095 OS << TypeS; 1096 if (E->isParenTypeId()) 1097 OS << ")"; 1098 1099 if (E->hasInitializer()) { 1100 OS << "("; 1101 unsigned NumCons = E->getNumConstructorArgs(); 1102 if (NumCons > 0) { 1103 PrintExpr(E->getConstructorArg(0)); 1104 for (unsigned i = 1; i < NumCons; ++i) { 1105 OS << ", "; 1106 PrintExpr(E->getConstructorArg(i)); 1107 } 1108 } 1109 OS << ")"; 1110 } 1111} 1112 1113void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 1114 if (E->isGlobalDelete()) 1115 OS << "::"; 1116 OS << "delete "; 1117 if (E->isArrayForm()) 1118 OS << "[] "; 1119 PrintExpr(E->getArgument()); 1120} 1121 1122void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 1123 PrintExpr(E->getBase()); 1124 if (E->isArrow()) 1125 OS << "->"; 1126 else 1127 OS << '.'; 1128 if (E->getQualifier()) 1129 E->getQualifier()->print(OS, Policy); 1130 1131 std::string TypeS; 1132 if (IdentifierInfo *II = E->getDestroyedTypeIdentifier()) 1133 OS << II->getName(); 1134 else 1135 E->getDestroyedType().getAsStringInternal(TypeS, Policy); 1136 OS << TypeS; 1137} 1138 1139void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 1140 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 1141 if (isa<CXXDefaultArgExpr>(E->getArg(i))) { 1142 // Don't print any defaulted arguments 1143 break; 1144 } 1145 1146 if (i) OS << ", "; 1147 PrintExpr(E->getArg(i)); 1148 } 1149} 1150 1151void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) { 1152 // Just forward to the sub expression. 1153 PrintExpr(E->getSubExpr()); 1154} 1155 1156void 1157StmtPrinter::VisitCXXUnresolvedConstructExpr( 1158 CXXUnresolvedConstructExpr *Node) { 1159 OS << Node->getTypeAsWritten().getAsString(Policy); 1160 OS << "("; 1161 for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(), 1162 ArgEnd = Node->arg_end(); 1163 Arg != ArgEnd; ++Arg) { 1164 if (Arg != Node->arg_begin()) 1165 OS << ", "; 1166 PrintExpr(*Arg); 1167 } 1168 OS << ")"; 1169} 1170 1171void StmtPrinter::VisitCXXDependentScopeMemberExpr( 1172 CXXDependentScopeMemberExpr *Node) { 1173 if (!Node->isImplicitAccess()) { 1174 PrintExpr(Node->getBase()); 1175 OS << (Node->isArrow() ? "->" : "."); 1176 } 1177 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1178 Qualifier->print(OS, Policy); 1179 else if (Node->hasExplicitTemplateArgs()) 1180 // FIXME: Track use of "template" keyword explicitly? 1181 OS << "template "; 1182 1183 OS << Node->getMemberNameInfo(); 1184 1185 if (Node->hasExplicitTemplateArgs()) { 1186 OS << TemplateSpecializationType::PrintTemplateArgumentList( 1187 Node->getTemplateArgs(), 1188 Node->getNumTemplateArgs(), 1189 Policy); 1190 } 1191} 1192 1193void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 1194 if (!Node->isImplicitAccess()) { 1195 PrintExpr(Node->getBase()); 1196 OS << (Node->isArrow() ? "->" : "."); 1197 } 1198 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1199 Qualifier->print(OS, Policy); 1200 1201 // FIXME: this might originally have been written with 'template' 1202 1203 OS << Node->getMemberNameInfo(); 1204 1205 if (Node->hasExplicitTemplateArgs()) { 1206 OS << TemplateSpecializationType::PrintTemplateArgumentList( 1207 Node->getTemplateArgs(), 1208 Node->getNumTemplateArgs(), 1209 Policy); 1210 } 1211} 1212 1213static const char *getTypeTraitName(UnaryTypeTrait UTT) { 1214 switch (UTT) { 1215 default: llvm_unreachable("Unknown unary type trait"); 1216 case UTT_HasNothrowAssign: return "__has_nothrow_assign"; 1217 case UTT_HasNothrowCopy: return "__has_nothrow_copy"; 1218 case UTT_HasNothrowConstructor: return "__has_nothrow_constructor"; 1219 case UTT_HasTrivialAssign: return "__has_trivial_assign"; 1220 case UTT_HasTrivialCopy: return "__has_trivial_copy"; 1221 case UTT_HasTrivialConstructor: return "__has_trivial_constructor"; 1222 case UTT_HasTrivialDestructor: return "__has_trivial_destructor"; 1223 case UTT_HasVirtualDestructor: return "__has_virtual_destructor"; 1224 case UTT_IsAbstract: return "__is_abstract"; 1225 case UTT_IsClass: return "__is_class"; 1226 case UTT_IsEmpty: return "__is_empty"; 1227 case UTT_IsEnum: return "__is_enum"; 1228 case UTT_IsPOD: return "__is_pod"; 1229 case UTT_IsPolymorphic: return "__is_polymorphic"; 1230 case UTT_IsUnion: return "__is_union"; 1231 } 1232 return ""; 1233} 1234 1235static const char *getTypeTraitName(BinaryTypeTrait BTT) { 1236 switch (BTT) { 1237 case BTT_IsBaseOf: return "__is_base_of"; 1238 case BTT_TypeCompatible: return "__builtin_types_compatible_p"; 1239 case BTT_IsConvertibleTo: return "__is_convertible_to"; 1240 } 1241 return ""; 1242} 1243 1244void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { 1245 OS << getTypeTraitName(E->getTrait()) << "(" 1246 << E->getQueriedType().getAsString(Policy) << ")"; 1247} 1248 1249void StmtPrinter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { 1250 OS << getTypeTraitName(E->getTrait()) << "(" 1251 << E->getLhsType().getAsString(Policy) << "," 1252 << E->getRhsType().getAsString(Policy) << ")"; 1253} 1254 1255void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { 1256 OS << "noexcept("; 1257 PrintExpr(E->getOperand()); 1258 OS << ")"; 1259} 1260 1261void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) { 1262 PrintExpr(E->getPattern()); 1263 OS << "..."; 1264} 1265 1266void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { 1267 OS << "sizeof...(" << E->getPack()->getNameAsString() << ")"; 1268} 1269 1270void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr( 1271 SubstNonTypeTemplateParmPackExpr *Node) { 1272 OS << Node->getParameterPack()->getNameAsString(); 1273} 1274 1275// Obj-C 1276 1277void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 1278 OS << "@"; 1279 VisitStringLiteral(Node->getString()); 1280} 1281 1282void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 1283 OS << "@encode(" << Node->getEncodedType().getAsString(Policy) << ')'; 1284} 1285 1286void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 1287 OS << "@selector(" << Node->getSelector().getAsString() << ')'; 1288} 1289 1290void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 1291 OS << "@protocol(" << Node->getProtocol() << ')'; 1292} 1293 1294void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 1295 OS << "["; 1296 switch (Mess->getReceiverKind()) { 1297 case ObjCMessageExpr::Instance: 1298 PrintExpr(Mess->getInstanceReceiver()); 1299 break; 1300 1301 case ObjCMessageExpr::Class: 1302 OS << Mess->getClassReceiver().getAsString(Policy); 1303 break; 1304 1305 case ObjCMessageExpr::SuperInstance: 1306 case ObjCMessageExpr::SuperClass: 1307 OS << "Super"; 1308 break; 1309 } 1310 1311 OS << ' '; 1312 Selector selector = Mess->getSelector(); 1313 if (selector.isUnarySelector()) { 1314 OS << selector.getIdentifierInfoForSlot(0)->getName(); 1315 } else { 1316 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 1317 if (i < selector.getNumArgs()) { 1318 if (i > 0) OS << ' '; 1319 if (selector.getIdentifierInfoForSlot(i)) 1320 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 1321 else 1322 OS << ":"; 1323 } 1324 else OS << ", "; // Handle variadic methods. 1325 1326 PrintExpr(Mess->getArg(i)); 1327 } 1328 } 1329 OS << "]"; 1330} 1331 1332 1333void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 1334 BlockDecl *BD = Node->getBlockDecl(); 1335 OS << "^"; 1336 1337 const FunctionType *AFT = Node->getFunctionType(); 1338 1339 if (isa<FunctionNoProtoType>(AFT)) { 1340 OS << "()"; 1341 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 1342 OS << '('; 1343 std::string ParamStr; 1344 for (BlockDecl::param_iterator AI = BD->param_begin(), 1345 E = BD->param_end(); AI != E; ++AI) { 1346 if (AI != BD->param_begin()) OS << ", "; 1347 ParamStr = (*AI)->getNameAsString(); 1348 (*AI)->getType().getAsStringInternal(ParamStr, Policy); 1349 OS << ParamStr; 1350 } 1351 1352 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 1353 if (FT->isVariadic()) { 1354 if (!BD->param_empty()) OS << ", "; 1355 OS << "..."; 1356 } 1357 OS << ')'; 1358 } 1359} 1360 1361void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) { 1362 OS << Node->getDecl(); 1363} 1364 1365void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {} 1366 1367//===----------------------------------------------------------------------===// 1368// Stmt method implementations 1369//===----------------------------------------------------------------------===// 1370 1371void Stmt::dumpPretty(ASTContext& Context) const { 1372 printPretty(llvm::errs(), Context, 0, 1373 PrintingPolicy(Context.getLangOptions())); 1374} 1375 1376void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context, 1377 PrinterHelper* Helper, 1378 const PrintingPolicy &Policy, 1379 unsigned Indentation) const { 1380 if (this == 0) { 1381 OS << "<NULL>"; 1382 return; 1383 } 1384 1385 if (Policy.Dump && &Context) { 1386 dump(OS, Context.getSourceManager()); 1387 return; 1388 } 1389 1390 StmtPrinter P(OS, Context, Helper, Policy, Indentation); 1391 P.Visit(const_cast<Stmt*>(this)); 1392} 1393 1394//===----------------------------------------------------------------------===// 1395// PrinterHelper 1396//===----------------------------------------------------------------------===// 1397 1398// Implement virtual destructor. 1399PrinterHelper::~PrinterHelper() {} 1400