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