StmtPrinter.cpp revision 9668033ee4c25efd019e6c7e6dd96aa2e6364a46
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/PrettyPrinter.h" 19#include "llvm/Support/Format.h" 20#include "clang/AST/Expr.h" 21using namespace clang; 22 23//===----------------------------------------------------------------------===// 24// StmtPrinter Visitor 25//===----------------------------------------------------------------------===// 26 27namespace { 28 class StmtPrinter : public StmtVisitor<StmtPrinter> { 29 llvm::raw_ostream &OS; 30 ASTContext &Context; 31 unsigned IndentLevel; 32 clang::PrinterHelper* Helper; 33 PrintingPolicy Policy; 34 35 public: 36 StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper, 37 const PrintingPolicy &Policy, 38 unsigned Indentation = 0) 39 : OS(os), Context(C), IndentLevel(Indentation), Helper(helper), 40 Policy(Policy) {} 41 42 void PrintStmt(Stmt *S) { 43 PrintStmt(S, Policy.Indentation); 44 } 45 46 void PrintStmt(Stmt *S, int SubIndent) { 47 IndentLevel += SubIndent; 48 if (S && isa<Expr>(S)) { 49 // If this is an expr used in a stmt context, indent and newline it. 50 Indent(); 51 Visit(S); 52 OS << ";\n"; 53 } else if (S) { 54 Visit(S); 55 } else { 56 Indent() << "<<<NULL STATEMENT>>>\n"; 57 } 58 IndentLevel -= SubIndent; 59 } 60 61 void PrintRawCompoundStmt(CompoundStmt *S); 62 void PrintRawDecl(Decl *D); 63 void PrintRawDeclStmt(DeclStmt *S); 64 void PrintRawIfStmt(IfStmt *If); 65 void PrintRawCXXCatchStmt(CXXCatchStmt *Catch); 66 67 void PrintExpr(Expr *E) { 68 if (E) 69 Visit(E); 70 else 71 OS << "<null expr>"; 72 } 73 74 llvm::raw_ostream &Indent(int Delta = 0) { 75 for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 76 OS << " "; 77 return OS; 78 } 79 80 bool PrintOffsetOfDesignator(Expr *E); 81 void VisitUnaryOffsetOf(UnaryOperator *Node); 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); 90#define STMT(CLASS, PARENT) \ 91 void Visit##CLASS(CLASS *Node); 92#include "clang/AST/StmtNodes.inc" 93 }; 94} 95 96//===----------------------------------------------------------------------===// 97// Stmt printing methods. 98//===----------------------------------------------------------------------===// 99 100void StmtPrinter::VisitStmt(Stmt *Node) { 101 Indent() << "<<unknown stmt type>>\n"; 102} 103 104/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 105/// with no newline after the }. 106void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 107 OS << "{\n"; 108 for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end(); 109 I != E; ++I) 110 PrintStmt(*I); 111 112 Indent() << "}"; 113} 114 115void StmtPrinter::PrintRawDecl(Decl *D) { 116 D->print(OS, Policy, IndentLevel); 117} 118 119void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) { 120 DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end(); 121 llvm::SmallVector<Decl*, 2> Decls; 122 for ( ; Begin != End; ++Begin) 123 Decls.push_back(*Begin); 124 125 Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel); 126} 127 128void StmtPrinter::VisitNullStmt(NullStmt *Node) { 129 Indent() << ";\n"; 130} 131 132void StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 133 Indent(); 134 PrintRawDeclStmt(Node); 135 OS << ";\n"; 136} 137 138void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 139 Indent(); 140 PrintRawCompoundStmt(Node); 141 OS << "\n"; 142} 143 144void StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 145 Indent(-1) << "case "; 146 PrintExpr(Node->getLHS()); 147 if (Node->getRHS()) { 148 OS << " ... "; 149 PrintExpr(Node->getRHS()); 150 } 151 OS << ":\n"; 152 153 PrintStmt(Node->getSubStmt(), 0); 154} 155 156void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 157 Indent(-1) << "default:\n"; 158 PrintStmt(Node->getSubStmt(), 0); 159} 160 161void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 162 Indent(-1) << Node->getName() << ":\n"; 163 PrintStmt(Node->getSubStmt(), 0); 164} 165 166void StmtPrinter::PrintRawIfStmt(IfStmt *If) { 167 OS << "if ("; 168 PrintExpr(If->getCond()); 169 OS << ')'; 170 171 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) { 172 OS << ' '; 173 PrintRawCompoundStmt(CS); 174 OS << (If->getElse() ? ' ' : '\n'); 175 } else { 176 OS << '\n'; 177 PrintStmt(If->getThen()); 178 if (If->getElse()) Indent(); 179 } 180 181 if (Stmt *Else = If->getElse()) { 182 OS << "else"; 183 184 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) { 185 OS << ' '; 186 PrintRawCompoundStmt(CS); 187 OS << '\n'; 188 } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) { 189 OS << ' '; 190 PrintRawIfStmt(ElseIf); 191 } else { 192 OS << '\n'; 193 PrintStmt(If->getElse()); 194 } 195 } 196} 197 198void StmtPrinter::VisitIfStmt(IfStmt *If) { 199 Indent(); 200 PrintRawIfStmt(If); 201} 202 203void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 204 Indent() << "switch ("; 205 PrintExpr(Node->getCond()); 206 OS << ")"; 207 208 // Pretty print compoundstmt bodies (very common). 209 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 210 OS << " "; 211 PrintRawCompoundStmt(CS); 212 OS << "\n"; 213 } else { 214 OS << "\n"; 215 PrintStmt(Node->getBody()); 216 } 217} 218 219void StmtPrinter::VisitSwitchCase(SwitchCase*) { 220 assert(0 && "SwitchCase is an abstract class"); 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::VisitExpr(Expr *Node) { 469 OS << "<<unknown expr type>>"; 470} 471 472void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { 473 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 474 Qualifier->print(OS, Policy); 475 OS << Node->getDecl(); 476 if (Node->hasExplicitTemplateArgumentList()) 477 OS << TemplateSpecializationType::PrintTemplateArgumentList( 478 Node->getTemplateArgs(), 479 Node->getNumTemplateArgs(), 480 Policy); 481} 482 483void StmtPrinter::VisitDependentScopeDeclRefExpr( 484 DependentScopeDeclRefExpr *Node) { 485 Node->getQualifier()->print(OS, Policy); 486 OS << Node->getDeclName().getAsString(); 487 if (Node->hasExplicitTemplateArgs()) 488 OS << TemplateSpecializationType::PrintTemplateArgumentList( 489 Node->getTemplateArgs(), 490 Node->getNumTemplateArgs(), 491 Policy); 492} 493 494void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 495 if (Node->getQualifier()) 496 Node->getQualifier()->print(OS, Policy); 497 OS << Node->getName().getAsString(); 498 if (Node->hasExplicitTemplateArgs()) 499 OS << TemplateSpecializationType::PrintTemplateArgumentList( 500 Node->getTemplateArgs(), 501 Node->getNumTemplateArgs(), 502 Policy); 503} 504 505void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 506 if (Node->getBase()) { 507 PrintExpr(Node->getBase()); 508 OS << (Node->isArrow() ? "->" : "."); 509 } 510 OS << Node->getDecl(); 511} 512 513void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 514 if (Node->getBase()) { 515 PrintExpr(Node->getBase()); 516 OS << "."; 517 } 518 OS << Node->getProperty()->getNameAsCString(); 519} 520 521void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr( 522 ObjCImplicitSetterGetterRefExpr *Node) { 523 if (Node->getBase()) { 524 PrintExpr(Node->getBase()); 525 OS << "."; 526 } 527 if (Node->getGetterMethod()) 528 OS << Node->getGetterMethod(); 529 530} 531 532void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 533 switch (Node->getIdentType()) { 534 default: 535 assert(0 && "unknown case"); 536 case PredefinedExpr::Func: 537 OS << "__func__"; 538 break; 539 case PredefinedExpr::Function: 540 OS << "__FUNCTION__"; 541 break; 542 case PredefinedExpr::PrettyFunction: 543 OS << "__PRETTY_FUNCTION__"; 544 break; 545 } 546} 547 548void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 549 unsigned value = Node->getValue(); 550 if (Node->isWide()) 551 OS << "L"; 552 switch (value) { 553 case '\\': 554 OS << "'\\\\'"; 555 break; 556 case '\'': 557 OS << "'\\''"; 558 break; 559 case '\a': 560 // TODO: K&R: the meaning of '\\a' is different in traditional C 561 OS << "'\\a'"; 562 break; 563 case '\b': 564 OS << "'\\b'"; 565 break; 566 // Nonstandard escape sequence. 567 /*case '\e': 568 OS << "'\\e'"; 569 break;*/ 570 case '\f': 571 OS << "'\\f'"; 572 break; 573 case '\n': 574 OS << "'\\n'"; 575 break; 576 case '\r': 577 OS << "'\\r'"; 578 break; 579 case '\t': 580 OS << "'\\t'"; 581 break; 582 case '\v': 583 OS << "'\\v'"; 584 break; 585 default: 586 if (value < 256 && isprint(value)) { 587 OS << "'" << (char)value << "'"; 588 } else if (value < 256) { 589 OS << "'\\x" << llvm::format("%x", value) << "'"; 590 } else { 591 // FIXME what to really do here? 592 OS << value; 593 } 594 } 595} 596 597void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 598 bool isSigned = Node->getType()->isSignedIntegerType(); 599 OS << Node->getValue().toString(10, isSigned); 600 601 // Emit suffixes. Integer literals are always a builtin integer type. 602 switch (Node->getType()->getAs<BuiltinType>()->getKind()) { 603 default: assert(0 && "Unexpected type for integer literal!"); 604 case BuiltinType::Int: break; // no suffix. 605 case BuiltinType::UInt: OS << 'U'; break; 606 case BuiltinType::Long: OS << 'L'; break; 607 case BuiltinType::ULong: OS << "UL"; break; 608 case BuiltinType::LongLong: OS << "LL"; break; 609 case BuiltinType::ULongLong: OS << "ULL"; break; 610 } 611} 612void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 613 // FIXME: print value more precisely. 614 OS << Node->getValueAsApproximateDouble(); 615} 616 617void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 618 PrintExpr(Node->getSubExpr()); 619 OS << "i"; 620} 621 622void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 623 if (Str->isWide()) OS << 'L'; 624 OS << '"'; 625 626 // FIXME: this doesn't print wstrings right. 627 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) { 628 unsigned char Char = Str->getStrData()[i]; 629 630 switch (Char) { 631 default: 632 if (isprint(Char)) 633 OS << (char)Char; 634 else // Output anything hard as an octal escape. 635 OS << '\\' 636 << (char)('0'+ ((Char >> 6) & 7)) 637 << (char)('0'+ ((Char >> 3) & 7)) 638 << (char)('0'+ ((Char >> 0) & 7)); 639 break; 640 // Handle some common non-printable cases to make dumps prettier. 641 case '\\': OS << "\\\\"; break; 642 case '"': OS << "\\\""; break; 643 case '\n': OS << "\\n"; break; 644 case '\t': OS << "\\t"; break; 645 case '\a': OS << "\\a"; break; 646 case '\b': OS << "\\b"; break; 647 } 648 } 649 OS << '"'; 650} 651void StmtPrinter::VisitParenExpr(ParenExpr *Node) { 652 OS << "("; 653 PrintExpr(Node->getSubExpr()); 654 OS << ")"; 655} 656void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 657 if (!Node->isPostfix()) { 658 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 659 660 // Print a space if this is an "identifier operator" like __real, or if 661 // it might be concatenated incorrectly like '+'. 662 switch (Node->getOpcode()) { 663 default: break; 664 case UnaryOperator::Real: 665 case UnaryOperator::Imag: 666 case UnaryOperator::Extension: 667 OS << ' '; 668 break; 669 case UnaryOperator::Plus: 670 case UnaryOperator::Minus: 671 if (isa<UnaryOperator>(Node->getSubExpr())) 672 OS << ' '; 673 break; 674 } 675 } 676 PrintExpr(Node->getSubExpr()); 677 678 if (Node->isPostfix()) 679 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 680} 681 682bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) { 683 if (isa<UnaryOperator>(E)) { 684 // Base case, print the type and comma. 685 OS << E->getType().getAsString(Policy) << ", "; 686 return true; 687 } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) { 688 PrintOffsetOfDesignator(ASE->getLHS()); 689 OS << "["; 690 PrintExpr(ASE->getRHS()); 691 OS << "]"; 692 return false; 693 } else { 694 MemberExpr *ME = cast<MemberExpr>(E); 695 bool IsFirst = PrintOffsetOfDesignator(ME->getBase()); 696 OS << (IsFirst ? "" : ".") << ME->getMemberDecl(); 697 return false; 698 } 699} 700 701void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) { 702 OS << "__builtin_offsetof("; 703 PrintOffsetOfDesignator(Node->getSubExpr()); 704 OS << ")"; 705} 706 707void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) { 708 OS << "__builtin_offsetof("; 709 OS << Node->getTypeSourceInfo()->getType().getAsString(Policy) << ", "; 710 bool PrintedSomething = false; 711 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) { 712 OffsetOfExpr::OffsetOfNode ON = Node->getComponent(i); 713 if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Array) { 714 // Array node 715 OS << "["; 716 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex())); 717 OS << "]"; 718 PrintedSomething = true; 719 continue; 720 } 721 722 // Skip implicit base indirections. 723 if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Base) 724 continue; 725 726 // Field or identifier node. 727 IdentifierInfo *Id = ON.getFieldName(); 728 if (!Id) 729 continue; 730 731 if (PrintedSomething) 732 OS << "."; 733 else 734 PrintedSomething = true; 735 OS << Id->getName(); 736 } 737 OS << ")"; 738} 739 740void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { 741 OS << (Node->isSizeOf() ? "sizeof" : "__alignof"); 742 if (Node->isArgumentType()) 743 OS << "(" << Node->getArgumentType().getAsString(Policy) << ")"; 744 else { 745 OS << " "; 746 PrintExpr(Node->getArgumentExpr()); 747 } 748} 749void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 750 PrintExpr(Node->getLHS()); 751 OS << "["; 752 PrintExpr(Node->getRHS()); 753 OS << "]"; 754} 755 756void StmtPrinter::VisitCallExpr(CallExpr *Call) { 757 PrintExpr(Call->getCallee()); 758 OS << "("; 759 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 760 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 761 // Don't print any defaulted arguments 762 break; 763 } 764 765 if (i) OS << ", "; 766 PrintExpr(Call->getArg(i)); 767 } 768 OS << ")"; 769} 770void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 771 // FIXME: Suppress printing implicit bases (like "this") 772 PrintExpr(Node->getBase()); 773 if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl())) 774 if (FD->isAnonymousStructOrUnion()) 775 return; 776 OS << (Node->isArrow() ? "->" : "."); 777 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 778 Qualifier->print(OS, Policy); 779 780 OS << Node->getMemberDecl(); 781 782 if (Node->hasExplicitTemplateArgumentList()) 783 OS << TemplateSpecializationType::PrintTemplateArgumentList( 784 Node->getTemplateArgs(), 785 Node->getNumTemplateArgs(), 786 Policy); 787} 788void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) { 789 PrintExpr(Node->getBase()); 790 OS << (Node->isArrow() ? "->isa" : ".isa"); 791} 792 793void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 794 PrintExpr(Node->getBase()); 795 OS << "."; 796 OS << Node->getAccessor().getName(); 797} 798void StmtPrinter::VisitCastExpr(CastExpr *) { 799 assert(0 && "CastExpr is an abstract class"); 800} 801void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) { 802 assert(0 && "ExplicitCastExpr is an abstract class"); 803} 804void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) { 805 OS << "(" << Node->getType().getAsString(Policy) << ")"; 806 PrintExpr(Node->getSubExpr()); 807} 808void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 809 OS << "(" << Node->getType().getAsString(Policy) << ")"; 810 PrintExpr(Node->getInitializer()); 811} 812void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 813 // No need to print anything, simply forward to the sub expression. 814 PrintExpr(Node->getSubExpr()); 815} 816void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 817 PrintExpr(Node->getLHS()); 818 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 819 PrintExpr(Node->getRHS()); 820} 821void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 822 PrintExpr(Node->getLHS()); 823 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 824 PrintExpr(Node->getRHS()); 825} 826void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 827 PrintExpr(Node->getCond()); 828 829 if (Node->getLHS()) { 830 OS << " ? "; 831 PrintExpr(Node->getLHS()); 832 OS << " : "; 833 } 834 else { // Handle GCC extension where LHS can be NULL. 835 OS << " ?: "; 836 } 837 838 PrintExpr(Node->getRHS()); 839} 840 841// GNU extensions. 842 843void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 844 OS << "&&" << Node->getLabel()->getName(); 845} 846 847void StmtPrinter::VisitStmtExpr(StmtExpr *E) { 848 OS << "("; 849 PrintRawCompoundStmt(E->getSubStmt()); 850 OS << ")"; 851} 852 853void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) { 854 OS << "__builtin_types_compatible_p("; 855 OS << Node->getArgType1().getAsString(Policy) << ","; 856 OS << Node->getArgType2().getAsString(Policy) << ")"; 857} 858 859void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 860 OS << "__builtin_choose_expr("; 861 PrintExpr(Node->getCond()); 862 OS << ", "; 863 PrintExpr(Node->getLHS()); 864 OS << ", "; 865 PrintExpr(Node->getRHS()); 866 OS << ")"; 867} 868 869void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 870 OS << "__null"; 871} 872 873void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 874 OS << "__builtin_shufflevector("; 875 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 876 if (i) OS << ", "; 877 PrintExpr(Node->getExpr(i)); 878 } 879 OS << ")"; 880} 881 882void StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 883 if (Node->getSyntacticForm()) { 884 Visit(Node->getSyntacticForm()); 885 return; 886 } 887 888 OS << "{ "; 889 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 890 if (i) OS << ", "; 891 if (Node->getInit(i)) 892 PrintExpr(Node->getInit(i)); 893 else 894 OS << "0"; 895 } 896 OS << " }"; 897} 898 899void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { 900 OS << "( "; 901 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) { 902 if (i) OS << ", "; 903 PrintExpr(Node->getExpr(i)); 904 } 905 OS << " )"; 906} 907 908void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { 909 for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(), 910 DEnd = Node->designators_end(); 911 D != DEnd; ++D) { 912 if (D->isFieldDesignator()) { 913 if (D->getDotLoc().isInvalid()) 914 OS << D->getFieldName()->getName() << ":"; 915 else 916 OS << "." << D->getFieldName()->getName(); 917 } else { 918 OS << "["; 919 if (D->isArrayDesignator()) { 920 PrintExpr(Node->getArrayIndex(*D)); 921 } else { 922 PrintExpr(Node->getArrayRangeStart(*D)); 923 OS << " ... "; 924 PrintExpr(Node->getArrayRangeEnd(*D)); 925 } 926 OS << "]"; 927 } 928 } 929 930 OS << " = "; 931 PrintExpr(Node->getInit()); 932} 933 934void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { 935 if (Policy.LangOpts.CPlusPlus) 936 OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()"; 937 else { 938 OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")"; 939 if (Node->getType()->isRecordType()) 940 OS << "{}"; 941 else 942 OS << 0; 943 } 944} 945 946void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 947 OS << "__builtin_va_arg("; 948 PrintExpr(Node->getSubExpr()); 949 OS << ", "; 950 OS << Node->getType().getAsString(Policy); 951 OS << ")"; 952} 953 954// C++ 955void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 956 const char *OpStrings[NUM_OVERLOADED_OPERATORS] = { 957 "", 958#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 959 Spelling, 960#include "clang/Basic/OperatorKinds.def" 961 }; 962 963 OverloadedOperatorKind Kind = Node->getOperator(); 964 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 965 if (Node->getNumArgs() == 1) { 966 OS << OpStrings[Kind] << ' '; 967 PrintExpr(Node->getArg(0)); 968 } else { 969 PrintExpr(Node->getArg(0)); 970 OS << ' ' << OpStrings[Kind]; 971 } 972 } else if (Kind == OO_Call) { 973 PrintExpr(Node->getArg(0)); 974 OS << '('; 975 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 976 if (ArgIdx > 1) 977 OS << ", "; 978 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 979 PrintExpr(Node->getArg(ArgIdx)); 980 } 981 OS << ')'; 982 } else if (Kind == OO_Subscript) { 983 PrintExpr(Node->getArg(0)); 984 OS << '['; 985 PrintExpr(Node->getArg(1)); 986 OS << ']'; 987 } else if (Node->getNumArgs() == 1) { 988 OS << OpStrings[Kind] << ' '; 989 PrintExpr(Node->getArg(0)); 990 } else if (Node->getNumArgs() == 2) { 991 PrintExpr(Node->getArg(0)); 992 OS << ' ' << OpStrings[Kind] << ' '; 993 PrintExpr(Node->getArg(1)); 994 } else { 995 assert(false && "unknown overloaded operator"); 996 } 997} 998 999void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 1000 VisitCallExpr(cast<CallExpr>(Node)); 1001} 1002 1003void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 1004 OS << Node->getCastName() << '<'; 1005 OS << Node->getTypeAsWritten().getAsString(Policy) << ">("; 1006 PrintExpr(Node->getSubExpr()); 1007 OS << ")"; 1008} 1009 1010void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 1011 VisitCXXNamedCastExpr(Node); 1012} 1013 1014void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 1015 VisitCXXNamedCastExpr(Node); 1016} 1017 1018void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 1019 VisitCXXNamedCastExpr(Node); 1020} 1021 1022void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 1023 VisitCXXNamedCastExpr(Node); 1024} 1025 1026void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 1027 OS << "typeid("; 1028 if (Node->isTypeOperand()) { 1029 OS << Node->getTypeOperand().getAsString(Policy); 1030 } else { 1031 PrintExpr(Node->getExprOperand()); 1032 } 1033 OS << ")"; 1034} 1035 1036void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 1037 OS << (Node->getValue() ? "true" : "false"); 1038} 1039 1040void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 1041 OS << "nullptr"; 1042} 1043 1044void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 1045 OS << "this"; 1046} 1047 1048void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 1049 if (Node->getSubExpr() == 0) 1050 OS << "throw"; 1051 else { 1052 OS << "throw "; 1053 PrintExpr(Node->getSubExpr()); 1054 } 1055} 1056 1057void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 1058 // Nothing to print: we picked up the default argument 1059} 1060 1061void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 1062 OS << Node->getType().getAsString(Policy); 1063 OS << "("; 1064 PrintExpr(Node->getSubExpr()); 1065 OS << ")"; 1066} 1067 1068void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 1069 PrintExpr(Node->getSubExpr()); 1070} 1071 1072void StmtPrinter::VisitCXXBindReferenceExpr(CXXBindReferenceExpr *Node) { 1073 PrintExpr(Node->getSubExpr()); 1074} 1075 1076void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 1077 OS << Node->getType().getAsString(Policy); 1078 OS << "("; 1079 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 1080 ArgEnd = Node->arg_end(); 1081 Arg != ArgEnd; ++Arg) { 1082 if (Arg != Node->arg_begin()) 1083 OS << ", "; 1084 PrintExpr(*Arg); 1085 } 1086 OS << ")"; 1087} 1088 1089void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { 1090 OS << Node->getType().getAsString(Policy) << "()"; 1091} 1092 1093void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 1094 if (E->isGlobalNew()) 1095 OS << "::"; 1096 OS << "new "; 1097 unsigned NumPlace = E->getNumPlacementArgs(); 1098 if (NumPlace > 0) { 1099 OS << "("; 1100 PrintExpr(E->getPlacementArg(0)); 1101 for (unsigned i = 1; i < NumPlace; ++i) { 1102 OS << ", "; 1103 PrintExpr(E->getPlacementArg(i)); 1104 } 1105 OS << ") "; 1106 } 1107 if (E->isParenTypeId()) 1108 OS << "("; 1109 std::string TypeS; 1110 if (Expr *Size = E->getArraySize()) { 1111 llvm::raw_string_ostream s(TypeS); 1112 Size->printPretty(s, Context, Helper, Policy); 1113 s.flush(); 1114 TypeS = "[" + TypeS + "]"; 1115 } 1116 E->getAllocatedType().getAsStringInternal(TypeS, Policy); 1117 OS << TypeS; 1118 if (E->isParenTypeId()) 1119 OS << ")"; 1120 1121 if (E->hasInitializer()) { 1122 OS << "("; 1123 unsigned NumCons = E->getNumConstructorArgs(); 1124 if (NumCons > 0) { 1125 PrintExpr(E->getConstructorArg(0)); 1126 for (unsigned i = 1; i < NumCons; ++i) { 1127 OS << ", "; 1128 PrintExpr(E->getConstructorArg(i)); 1129 } 1130 } 1131 OS << ")"; 1132 } 1133} 1134 1135void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 1136 if (E->isGlobalDelete()) 1137 OS << "::"; 1138 OS << "delete "; 1139 if (E->isArrayForm()) 1140 OS << "[] "; 1141 PrintExpr(E->getArgument()); 1142} 1143 1144void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 1145 PrintExpr(E->getBase()); 1146 if (E->isArrow()) 1147 OS << "->"; 1148 else 1149 OS << '.'; 1150 if (E->getQualifier()) 1151 E->getQualifier()->print(OS, Policy); 1152 1153 std::string TypeS; 1154 if (IdentifierInfo *II = E->getDestroyedTypeIdentifier()) 1155 OS << II->getName(); 1156 else 1157 E->getDestroyedType().getAsStringInternal(TypeS, Policy); 1158 OS << TypeS; 1159} 1160 1161void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 1162 // FIXME. For now we just print a trivial constructor call expression, 1163 // constructing its first argument object. 1164 if (E->getNumArgs() == 1) { 1165 CXXConstructorDecl *CD = E->getConstructor(); 1166 if (CD->isTrivial()) 1167 PrintExpr(E->getArg(0)); 1168 } 1169 // Nothing to print. 1170} 1171 1172void StmtPrinter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) { 1173 // Just forward to the sub expression. 1174 PrintExpr(E->getSubExpr()); 1175} 1176 1177void 1178StmtPrinter::VisitCXXUnresolvedConstructExpr( 1179 CXXUnresolvedConstructExpr *Node) { 1180 OS << Node->getTypeAsWritten().getAsString(Policy); 1181 OS << "("; 1182 for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(), 1183 ArgEnd = Node->arg_end(); 1184 Arg != ArgEnd; ++Arg) { 1185 if (Arg != Node->arg_begin()) 1186 OS << ", "; 1187 PrintExpr(*Arg); 1188 } 1189 OS << ")"; 1190} 1191 1192void StmtPrinter::VisitCXXDependentScopeMemberExpr( 1193 CXXDependentScopeMemberExpr *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 else if (Node->hasExplicitTemplateArgs()) 1201 // FIXME: Track use of "template" keyword explicitly? 1202 OS << "template "; 1203 1204 OS << Node->getMember().getAsString(); 1205 1206 if (Node->hasExplicitTemplateArgs()) { 1207 OS << TemplateSpecializationType::PrintTemplateArgumentList( 1208 Node->getTemplateArgs(), 1209 Node->getNumTemplateArgs(), 1210 Policy); 1211 } 1212} 1213 1214void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 1215 if (!Node->isImplicitAccess()) { 1216 PrintExpr(Node->getBase()); 1217 OS << (Node->isArrow() ? "->" : "."); 1218 } 1219 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1220 Qualifier->print(OS, Policy); 1221 1222 // FIXME: this might originally have been written with 'template' 1223 1224 OS << Node->getMemberName().getAsString(); 1225 1226 if (Node->hasExplicitTemplateArgs()) { 1227 OS << TemplateSpecializationType::PrintTemplateArgumentList( 1228 Node->getTemplateArgs(), 1229 Node->getNumTemplateArgs(), 1230 Policy); 1231 } 1232} 1233 1234static const char *getTypeTraitName(UnaryTypeTrait UTT) { 1235 switch (UTT) { 1236 default: assert(false && "Unknown type trait"); 1237 case UTT_HasNothrowAssign: return "__has_nothrow_assign"; 1238 case UTT_HasNothrowCopy: return "__has_nothrow_copy"; 1239 case UTT_HasNothrowConstructor: return "__has_nothrow_constructor"; 1240 case UTT_HasTrivialAssign: return "__has_trivial_assign"; 1241 case UTT_HasTrivialCopy: return "__has_trivial_copy"; 1242 case UTT_HasTrivialConstructor: return "__has_trivial_constructor"; 1243 case UTT_HasTrivialDestructor: return "__has_trivial_destructor"; 1244 case UTT_HasVirtualDestructor: return "__has_virtual_destructor"; 1245 case UTT_IsAbstract: return "__is_abstract"; 1246 case UTT_IsClass: return "__is_class"; 1247 case UTT_IsEmpty: return "__is_empty"; 1248 case UTT_IsEnum: return "__is_enum"; 1249 case UTT_IsPOD: return "__is_pod"; 1250 case UTT_IsPolymorphic: return "__is_polymorphic"; 1251 case UTT_IsUnion: return "__is_union"; 1252 } 1253} 1254 1255void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { 1256 OS << getTypeTraitName(E->getTrait()) << "(" 1257 << E->getQueriedType().getAsString(Policy) << ")"; 1258} 1259 1260// Obj-C 1261 1262void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 1263 OS << "@"; 1264 VisitStringLiteral(Node->getString()); 1265} 1266 1267void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 1268 OS << "@encode(" << Node->getEncodedType().getAsString(Policy) << ')'; 1269} 1270 1271void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 1272 OS << "@selector(" << Node->getSelector().getAsString() << ')'; 1273} 1274 1275void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 1276 OS << "@protocol(" << Node->getProtocol() << ')'; 1277} 1278 1279void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 1280 OS << "["; 1281 switch (Mess->getReceiverKind()) { 1282 case ObjCMessageExpr::Instance: 1283 PrintExpr(Mess->getInstanceReceiver()); 1284 break; 1285 1286 case ObjCMessageExpr::Class: 1287 OS << Mess->getClassReceiver().getAsString(Policy); 1288 break; 1289 1290 case ObjCMessageExpr::SuperInstance: 1291 case ObjCMessageExpr::SuperClass: 1292 OS << "Super"; 1293 break; 1294 } 1295 1296 OS << ' '; 1297 Selector selector = Mess->getSelector(); 1298 if (selector.isUnarySelector()) { 1299 OS << selector.getIdentifierInfoForSlot(0)->getName(); 1300 } else { 1301 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 1302 if (i < selector.getNumArgs()) { 1303 if (i > 0) OS << ' '; 1304 if (selector.getIdentifierInfoForSlot(i)) 1305 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 1306 else 1307 OS << ":"; 1308 } 1309 else OS << ", "; // Handle variadic methods. 1310 1311 PrintExpr(Mess->getArg(i)); 1312 } 1313 } 1314 OS << "]"; 1315} 1316 1317void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) { 1318 OS << "super"; 1319} 1320 1321void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 1322 BlockDecl *BD = Node->getBlockDecl(); 1323 OS << "^"; 1324 1325 const FunctionType *AFT = Node->getFunctionType(); 1326 1327 if (isa<FunctionNoProtoType>(AFT)) { 1328 OS << "()"; 1329 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 1330 OS << '('; 1331 std::string ParamStr; 1332 for (BlockDecl::param_iterator AI = BD->param_begin(), 1333 E = BD->param_end(); AI != E; ++AI) { 1334 if (AI != BD->param_begin()) OS << ", "; 1335 ParamStr = (*AI)->getNameAsString(); 1336 (*AI)->getType().getAsStringInternal(ParamStr, Policy); 1337 OS << ParamStr; 1338 } 1339 1340 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 1341 if (FT->isVariadic()) { 1342 if (!BD->param_empty()) OS << ", "; 1343 OS << "..."; 1344 } 1345 OS << ')'; 1346 } 1347} 1348 1349void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) { 1350 OS << Node->getDecl(); 1351} 1352//===----------------------------------------------------------------------===// 1353// Stmt method implementations 1354//===----------------------------------------------------------------------===// 1355 1356void Stmt::dumpPretty(ASTContext& Context) const { 1357 printPretty(llvm::errs(), Context, 0, 1358 PrintingPolicy(Context.getLangOptions())); 1359} 1360 1361void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context, 1362 PrinterHelper* Helper, 1363 const PrintingPolicy &Policy, 1364 unsigned Indentation) const { 1365 if (this == 0) { 1366 OS << "<NULL>"; 1367 return; 1368 } 1369 1370 if (Policy.Dump && &Context) { 1371 dump(OS, Context.getSourceManager()); 1372 return; 1373 } 1374 1375 StmtPrinter P(OS, Context, Helper, Policy, Indentation); 1376 P.Visit(const_cast<Stmt*>(this)); 1377} 1378 1379//===----------------------------------------------------------------------===// 1380// PrinterHelper 1381//===----------------------------------------------------------------------===// 1382 1383// Implement virtual destructor. 1384PrinterHelper::~PrinterHelper() {} 1385