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