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