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