StmtPrinter.cpp revision d9f6910f4ef37c0e8eeee2a01287d9572c3176ef
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/Decl.h" 17#include "clang/AST/DeclObjC.h" 18#include "clang/AST/ExprCXX.h" 19#include "clang/AST/ExprObjC.h" 20#include "clang/AST/PrettyPrinter.h" 21#include "clang/Basic/IdentifierTable.h" 22#include "llvm/Support/Compiler.h" 23#include "llvm/Support/Streams.h" 24#include <iomanip> 25using namespace clang; 26 27//===----------------------------------------------------------------------===// 28// StmtPrinter Visitor 29//===----------------------------------------------------------------------===// 30 31namespace { 32 class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> { 33 std::ostream &OS; 34 unsigned IndentLevel; 35 clang::PrinterHelper* Helper; 36 public: 37 StmtPrinter(std::ostream &os, PrinterHelper* helper) : 38 OS(os), IndentLevel(0), Helper(helper) {} 39 40 void PrintStmt(Stmt *S, int SubIndent = 1) { 41 IndentLevel += SubIndent; 42 if (S && isa<Expr>(S)) { 43 // If this is an expr used in a stmt context, indent and newline it. 44 Indent(); 45 Visit(S); 46 OS << ";\n"; 47 } else if (S) { 48 Visit(S); 49 } else { 50 Indent() << "<<<NULL STATEMENT>>>\n"; 51 } 52 IndentLevel -= SubIndent; 53 } 54 55 void PrintRawCompoundStmt(CompoundStmt *S); 56 void PrintRawDecl(Decl *D); 57 void PrintRawIfStmt(IfStmt *If); 58 59 void PrintExpr(Expr *E) { 60 if (E) 61 Visit(E); 62 else 63 OS << "<null expr>"; 64 } 65 66 std::ostream &Indent(int Delta = 0) const { 67 for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 68 OS << " "; 69 return OS; 70 } 71 72 bool PrintOffsetOfDesignator(Expr *E); 73 void VisitUnaryOffsetOf(UnaryOperator *Node); 74 75 void Visit(Stmt* S) { 76 if (Helper && Helper->handledStmt(S,OS)) 77 return; 78 else StmtVisitor<StmtPrinter>::Visit(S); 79 } 80 81 void VisitStmt(Stmt *Node); 82#define STMT(N, CLASS, PARENT) \ 83 void Visit##CLASS(CLASS *Node); 84#include "clang/AST/StmtNodes.def" 85 }; 86} 87 88//===----------------------------------------------------------------------===// 89// Stmt printing methods. 90//===----------------------------------------------------------------------===// 91 92void StmtPrinter::VisitStmt(Stmt *Node) { 93 Indent() << "<<unknown stmt type>>\n"; 94} 95 96/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 97/// with no newline after the }. 98void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 99 OS << "{\n"; 100 for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end(); 101 I != E; ++I) 102 PrintStmt(*I); 103 104 Indent() << "}"; 105} 106 107void StmtPrinter::PrintRawDecl(Decl *D) { 108 // FIXME: Need to complete/beautify this... this code simply shows the 109 // nodes are where they need to be. 110 if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) { 111 OS << "typedef " << localType->getUnderlyingType().getAsString(); 112 OS << " " << localType->getName(); 113 } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 114 // Emit storage class for vardecls. 115 if (VarDecl *V = dyn_cast<VarDecl>(VD)) { 116 switch (V->getStorageClass()) { 117 default: assert(0 && "Unknown storage class!"); 118 case VarDecl::None: break; 119 case VarDecl::Extern: OS << "extern "; break; 120 case VarDecl::Static: OS << "static "; break; 121 case VarDecl::Auto: OS << "auto "; break; 122 case VarDecl::Register: OS << "register "; break; 123 } 124 } 125 126 std::string Name = VD->getName(); 127 VD->getType().getAsStringInternal(Name); 128 OS << Name; 129 130 // If this is a vardecl with an initializer, emit it. 131 if (VarDecl *V = dyn_cast<VarDecl>(VD)) { 132 if (V->getInit()) { 133 OS << " = "; 134 PrintExpr(V->getInit()); 135 } 136 } 137 } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) { 138 // print a free standing tag decl (e.g. "struct x;"). 139 OS << TD->getKindName(); 140 OS << " "; 141 if (const IdentifierInfo *II = TD->getIdentifier()) 142 OS << II->getName(); 143 else 144 OS << "<anonymous>"; 145 // FIXME: print tag bodies. 146 } else { 147 assert(0 && "Unexpected decl"); 148 } 149} 150 151 152void StmtPrinter::VisitNullStmt(NullStmt *Node) { 153 Indent() << ";\n"; 154} 155 156void StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 157 for (ScopedDecl *D = Node->getDecl(); D; D = D->getNextDeclarator()) { 158 Indent(); 159 PrintRawDecl(D); 160 OS << ";\n"; 161 } 162} 163 164void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 165 Indent(); 166 PrintRawCompoundStmt(Node); 167 OS << "\n"; 168} 169 170void StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 171 Indent(-1) << "case "; 172 PrintExpr(Node->getLHS()); 173 if (Node->getRHS()) { 174 OS << " ... "; 175 PrintExpr(Node->getRHS()); 176 } 177 OS << ":\n"; 178 179 PrintStmt(Node->getSubStmt(), 0); 180} 181 182void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 183 Indent(-1) << "default:\n"; 184 PrintStmt(Node->getSubStmt(), 0); 185} 186 187void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 188 Indent(-1) << Node->getName() << ":\n"; 189 PrintStmt(Node->getSubStmt(), 0); 190} 191 192void StmtPrinter::PrintRawIfStmt(IfStmt *If) { 193 OS << "if "; 194 PrintExpr(If->getCond()); 195 196 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) { 197 OS << ' '; 198 PrintRawCompoundStmt(CS); 199 OS << (If->getElse() ? ' ' : '\n'); 200 } else { 201 OS << '\n'; 202 PrintStmt(If->getThen()); 203 if (If->getElse()) Indent(); 204 } 205 206 if (Stmt *Else = If->getElse()) { 207 OS << "else"; 208 209 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) { 210 OS << ' '; 211 PrintRawCompoundStmt(CS); 212 OS << '\n'; 213 } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) { 214 OS << ' '; 215 PrintRawIfStmt(ElseIf); 216 } else { 217 OS << '\n'; 218 PrintStmt(If->getElse()); 219 } 220 } 221} 222 223void StmtPrinter::VisitIfStmt(IfStmt *If) { 224 Indent(); 225 PrintRawIfStmt(If); 226} 227 228void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 229 Indent() << "switch ("; 230 PrintExpr(Node->getCond()); 231 OS << ")"; 232 233 // Pretty print compoundstmt bodies (very common). 234 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 235 OS << " "; 236 PrintRawCompoundStmt(CS); 237 OS << "\n"; 238 } else { 239 OS << "\n"; 240 PrintStmt(Node->getBody()); 241 } 242} 243 244void StmtPrinter::VisitSwitchCase(SwitchCase*) { 245 assert(0 && "SwitchCase is an abstract class"); 246} 247 248void StmtPrinter::VisitWhileStmt(WhileStmt *Node) { 249 Indent() << "while ("; 250 PrintExpr(Node->getCond()); 251 OS << ")\n"; 252 PrintStmt(Node->getBody()); 253} 254 255void StmtPrinter::VisitDoStmt(DoStmt *Node) { 256 Indent() << "do "; 257 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 258 PrintRawCompoundStmt(CS); 259 OS << " "; 260 } else { 261 OS << "\n"; 262 PrintStmt(Node->getBody()); 263 Indent(); 264 } 265 266 OS << "while "; 267 PrintExpr(Node->getCond()); 268 OS << ";\n"; 269} 270 271void StmtPrinter::VisitForStmt(ForStmt *Node) { 272 Indent() << "for ("; 273 if (Node->getInit()) { 274 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit())) 275 PrintRawDecl(DS->getDecl()); 276 else 277 PrintExpr(cast<Expr>(Node->getInit())); 278 } 279 OS << ";"; 280 if (Node->getCond()) { 281 OS << " "; 282 PrintExpr(Node->getCond()); 283 } 284 OS << ";"; 285 if (Node->getInc()) { 286 OS << " "; 287 PrintExpr(Node->getInc()); 288 } 289 OS << ") "; 290 291 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 292 PrintRawCompoundStmt(CS); 293 OS << "\n"; 294 } else { 295 OS << "\n"; 296 PrintStmt(Node->getBody()); 297 } 298} 299 300void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) { 301 Indent() << "for ("; 302 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement())) 303 PrintRawDecl(DS->getDecl()); 304 else 305 PrintExpr(cast<Expr>(Node->getElement())); 306 OS << " in "; 307 PrintExpr(Node->getCollection()); 308 OS << ") "; 309 310 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 311 PrintRawCompoundStmt(CS); 312 OS << "\n"; 313 } else { 314 OS << "\n"; 315 PrintStmt(Node->getBody()); 316 } 317} 318 319void StmtPrinter::VisitGotoStmt(GotoStmt *Node) { 320 Indent() << "goto " << Node->getLabel()->getName() << ";\n"; 321} 322 323void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) { 324 Indent() << "goto *"; 325 PrintExpr(Node->getTarget()); 326 OS << ";\n"; 327} 328 329void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) { 330 Indent() << "continue;\n"; 331} 332 333void StmtPrinter::VisitBreakStmt(BreakStmt *Node) { 334 Indent() << "break;\n"; 335} 336 337 338void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) { 339 Indent() << "return"; 340 if (Node->getRetValue()) { 341 OS << " "; 342 PrintExpr(Node->getRetValue()); 343 } 344 OS << ";\n"; 345} 346 347 348void StmtPrinter::VisitAsmStmt(AsmStmt *Node) { 349 Indent() << "asm "; 350 351 if (Node->isVolatile()) 352 OS << "volatile "; 353 354 OS << "("; 355 VisitStringLiteral(Node->getAsmString()); 356 357 // Outputs 358 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 || 359 Node->getNumClobbers() != 0) 360 OS << " : "; 361 362 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) { 363 if (i != 0) 364 OS << ", "; 365 366 if (!Node->getOutputName(i).empty()) { 367 OS << '['; 368 OS << Node->getOutputName(i); 369 OS << "] "; 370 } 371 372 VisitStringLiteral(Node->getOutputConstraint(i)); 373 OS << " "; 374 Visit(Node->getOutputExpr(i)); 375 } 376 377 // Inputs 378 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0) 379 OS << " : "; 380 381 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) { 382 if (i != 0) 383 OS << ", "; 384 385 if (!Node->getInputName(i).empty()) { 386 OS << '['; 387 OS << Node->getInputName(i); 388 OS << "] "; 389 } 390 391 VisitStringLiteral(Node->getInputConstraint(i)); 392 OS << " "; 393 Visit(Node->getInputExpr(i)); 394 } 395 396 // Clobbers 397 if (Node->getNumClobbers() != 0) 398 OS << " : "; 399 400 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) { 401 if (i != 0) 402 OS << ", "; 403 404 VisitStringLiteral(Node->getClobber(i)); 405 } 406 407 OS << ");\n"; 408} 409 410void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) { 411 Indent() << "@try"; 412 if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) { 413 PrintRawCompoundStmt(TS); 414 OS << "\n"; 415 } 416 417 for (ObjCAtCatchStmt *catchStmt = 418 static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts()); 419 catchStmt; 420 catchStmt = 421 static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) { 422 Indent() << "@catch("; 423 if (catchStmt->getCatchParamStmt()) { 424 if (DeclStmt *DS = dyn_cast<DeclStmt>(catchStmt->getCatchParamStmt())) 425 PrintRawDecl(DS->getDecl()); 426 } 427 OS << ")"; 428 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) 429 { 430 PrintRawCompoundStmt(CS); 431 OS << "\n"; 432 } 433 } 434 435 if (ObjCAtFinallyStmt *FS =static_cast<ObjCAtFinallyStmt *>( 436 Node->getFinallyStmt())) { 437 Indent() << "@finally"; 438 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody())); 439 OS << "\n"; 440 } 441} 442 443void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) { 444} 445 446void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) { 447 Indent() << "@catch (...) { /* todo */ } \n"; 448} 449 450void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) { 451 Indent() << "@throw"; 452 if (Node->getThrowExpr()) { 453 OS << " "; 454 PrintExpr(Node->getThrowExpr()); 455 } 456 OS << ";\n"; 457} 458 459void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) { 460 Indent() << "@synchronized ("; 461 PrintExpr(Node->getSynchExpr()); 462 OS << ")"; 463 PrintRawCompoundStmt(Node->getSynchBody()); 464 OS << "\n"; 465} 466 467//===----------------------------------------------------------------------===// 468// Expr printing methods. 469//===----------------------------------------------------------------------===// 470 471void StmtPrinter::VisitExpr(Expr *Node) { 472 OS << "<<unknown expr type>>"; 473} 474 475void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { 476 OS << Node->getDecl()->getName(); 477} 478 479void StmtPrinter::VisitObjCSuperRefExpr(ObjCSuperRefExpr *Node) { 480 OS << "super"; 481} 482 483void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 484 if (Node->getBase()) { 485 PrintExpr(Node->getBase()); 486 OS << (Node->isArrow() ? "->" : "."); 487 } 488 OS << Node->getDecl()->getName(); 489} 490 491void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 492 if (Node->getBase()) { 493 PrintExpr(Node->getBase()); 494 OS << "."; 495 } 496 // FIXME: OS << Node->getDecl()->getName(); 497} 498 499void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 500 switch (Node->getIdentType()) { 501 default: 502 assert(0 && "unknown case"); 503 case PredefinedExpr::Func: 504 OS << "__func__"; 505 break; 506 case PredefinedExpr::Function: 507 OS << "__FUNCTION__"; 508 break; 509 case PredefinedExpr::PrettyFunction: 510 OS << "__PRETTY_FUNCTION__"; 511 break; 512 case PredefinedExpr::ObjCSuper: 513 OS << "super"; 514 break; 515 } 516} 517 518void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 519 unsigned value = Node->getValue(); 520 if (Node->isWide()) 521 OS << "L"; 522 switch (value) { 523 case '\\': 524 OS << "'\\\\'"; 525 break; 526 case '\'': 527 OS << "'\\''"; 528 break; 529 case '\a': 530 // TODO: K&R: the meaning of '\\a' is different in traditional C 531 OS << "'\\a'"; 532 break; 533 case '\b': 534 OS << "'\\b'"; 535 break; 536 // Nonstandard escape sequence. 537 /*case '\e': 538 OS << "'\\e'"; 539 break;*/ 540 case '\f': 541 OS << "'\\f'"; 542 break; 543 case '\n': 544 OS << "'\\n'"; 545 break; 546 case '\r': 547 OS << "'\\r'"; 548 break; 549 case '\t': 550 OS << "'\\t'"; 551 break; 552 case '\v': 553 OS << "'\\v'"; 554 break; 555 default: 556 if (value < 256 && isprint(value)) { 557 OS << "'" << (char)value << "'"; 558 } else if (value < 256) { 559 OS << "'\\x" << std::hex << value << std::dec << "'"; 560 } else { 561 // FIXME what to really do here? 562 OS << value; 563 } 564 } 565} 566 567void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 568 bool isSigned = Node->getType()->isSignedIntegerType(); 569 OS << Node->getValue().toString(10, isSigned); 570 571 // Emit suffixes. Integer literals are always a builtin integer type. 572 switch (Node->getType()->getAsBuiltinType()->getKind()) { 573 default: assert(0 && "Unexpected type for integer literal!"); 574 case BuiltinType::Int: break; // no suffix. 575 case BuiltinType::UInt: OS << 'U'; break; 576 case BuiltinType::Long: OS << 'L'; break; 577 case BuiltinType::ULong: OS << "UL"; break; 578 case BuiltinType::LongLong: OS << "LL"; break; 579 case BuiltinType::ULongLong: OS << "ULL"; break; 580 } 581} 582void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 583 // FIXME: print value more precisely. 584 OS << Node->getValueAsApproximateDouble(); 585} 586 587void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 588 PrintExpr(Node->getSubExpr()); 589 OS << "i"; 590} 591 592void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 593 if (Str->isWide()) OS << 'L'; 594 OS << '"'; 595 596 // FIXME: this doesn't print wstrings right. 597 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) { 598 switch (Str->getStrData()[i]) { 599 default: OS << Str->getStrData()[i]; break; 600 // Handle some common ones to make dumps prettier. 601 case '\\': OS << "\\\\"; break; 602 case '"': OS << "\\\""; break; 603 case '\n': OS << "\\n"; break; 604 case '\t': OS << "\\t"; break; 605 case '\a': OS << "\\a"; break; 606 case '\b': OS << "\\b"; break; 607 } 608 } 609 OS << '"'; 610} 611void StmtPrinter::VisitParenExpr(ParenExpr *Node) { 612 OS << "("; 613 PrintExpr(Node->getSubExpr()); 614 OS << ")"; 615} 616void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 617 if (!Node->isPostfix()) { 618 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 619 620 // Print a space if this is an "identifier operator" like sizeof or __real. 621 switch (Node->getOpcode()) { 622 default: break; 623 case UnaryOperator::SizeOf: 624 case UnaryOperator::AlignOf: 625 case UnaryOperator::Real: 626 case UnaryOperator::Imag: 627 case UnaryOperator::Extension: 628 OS << ' '; 629 break; 630 } 631 } 632 PrintExpr(Node->getSubExpr()); 633 634 if (Node->isPostfix()) 635 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 636} 637 638bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) { 639 if (isa<CompoundLiteralExpr>(E)) { 640 // Base case, print the type and comma. 641 OS << E->getType().getAsString() << ", "; 642 return true; 643 } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) { 644 PrintOffsetOfDesignator(ASE->getLHS()); 645 OS << "["; 646 PrintExpr(ASE->getRHS()); 647 OS << "]"; 648 return false; 649 } else { 650 MemberExpr *ME = cast<MemberExpr>(E); 651 bool IsFirst = PrintOffsetOfDesignator(ME->getBase()); 652 OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getName(); 653 return false; 654 } 655} 656 657void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) { 658 OS << "__builtin_offsetof("; 659 PrintOffsetOfDesignator(Node->getSubExpr()); 660 OS << ")"; 661} 662 663void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) { 664 OS << (Node->isSizeOf() ? "sizeof(" : "__alignof("); 665 OS << Node->getArgumentType().getAsString() << ")"; 666} 667void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 668 PrintExpr(Node->getLHS()); 669 OS << "["; 670 PrintExpr(Node->getRHS()); 671 OS << "]"; 672} 673 674void StmtPrinter::VisitCallExpr(CallExpr *Call) { 675 PrintExpr(Call->getCallee()); 676 OS << "("; 677 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 678 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 679 // Don't print any defaulted arguments 680 break; 681 } 682 683 if (i) OS << ", "; 684 PrintExpr(Call->getArg(i)); 685 } 686 OS << ")"; 687} 688void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 689 PrintExpr(Node->getBase()); 690 OS << (Node->isArrow() ? "->" : "."); 691 692 FieldDecl *Field = Node->getMemberDecl(); 693 assert(Field && "MemberExpr should alway reference a field!"); 694 OS << Field->getName(); 695} 696void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 697 PrintExpr(Node->getBase()); 698 OS << "."; 699 OS << Node->getAccessor().getName(); 700} 701void StmtPrinter::VisitCastExpr(CastExpr *Node) { 702 OS << "(" << Node->getType().getAsString() << ")"; 703 PrintExpr(Node->getSubExpr()); 704} 705void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 706 OS << "(" << Node->getType().getAsString() << ")"; 707 PrintExpr(Node->getInitializer()); 708} 709void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 710 // No need to print anything, simply forward to the sub expression. 711 PrintExpr(Node->getSubExpr()); 712} 713void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 714 PrintExpr(Node->getLHS()); 715 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 716 PrintExpr(Node->getRHS()); 717} 718void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 719 PrintExpr(Node->getLHS()); 720 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 721 PrintExpr(Node->getRHS()); 722} 723void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 724 PrintExpr(Node->getCond()); 725 726 if (Node->getLHS()) { 727 OS << " ? "; 728 PrintExpr(Node->getLHS()); 729 OS << " : "; 730 } 731 else { // Handle GCC extention where LHS can be NULL. 732 OS << " ?: "; 733 } 734 735 PrintExpr(Node->getRHS()); 736} 737 738// GNU extensions. 739 740void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 741 OS << "&&" << Node->getLabel()->getName(); 742} 743 744void StmtPrinter::VisitStmtExpr(StmtExpr *E) { 745 OS << "("; 746 PrintRawCompoundStmt(E->getSubStmt()); 747 OS << ")"; 748} 749 750void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) { 751 OS << "__builtin_types_compatible_p("; 752 OS << Node->getArgType1().getAsString() << ","; 753 OS << Node->getArgType2().getAsString() << ")"; 754} 755 756void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 757 OS << "__builtin_choose_expr("; 758 PrintExpr(Node->getCond()); 759 OS << ", "; 760 PrintExpr(Node->getLHS()); 761 OS << ", "; 762 PrintExpr(Node->getRHS()); 763 OS << ")"; 764} 765 766void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) { 767 OS << "__builtin_overload("; 768 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 769 if (i) OS << ", "; 770 PrintExpr(Node->getExpr(i)); 771 } 772 OS << ")"; 773} 774 775void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 776 OS << "__builtin_shufflevector("; 777 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 778 if (i) OS << ", "; 779 PrintExpr(Node->getExpr(i)); 780 } 781 OS << ")"; 782} 783 784void StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 785 OS << "{ "; 786 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 787 if (i) OS << ", "; 788 PrintExpr(Node->getInit(i)); 789 } 790 OS << " }"; 791} 792 793void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 794 OS << "va_arg("; 795 PrintExpr(Node->getSubExpr()); 796 OS << ", "; 797 OS << Node->getType().getAsString(); 798 OS << ")"; 799} 800 801// C++ 802 803void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) { 804 OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<'; 805 OS << Node->getDestType().getAsString() << ">("; 806 PrintExpr(Node->getSubExpr()); 807 OS << ")"; 808} 809 810void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 811 OS << (Node->getValue() ? "true" : "false"); 812} 813 814void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 815 if (Node->getSubExpr() == 0) 816 OS << "throw"; 817 else { 818 OS << "throw "; 819 PrintExpr(Node->getSubExpr()); 820 } 821} 822 823void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 824 // Nothing to print: we picked up the default argument 825} 826 827// Obj-C 828 829void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 830 OS << "@"; 831 VisitStringLiteral(Node->getString()); 832} 833 834void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 835 OS << "@encode(" << Node->getEncodedType().getAsString() << ")"; 836} 837 838void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 839 OS << "@selector(" << Node->getSelector().getName() << ")"; 840} 841 842void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 843 OS << "@protocol(" << Node->getProtocol()->getName() << ")"; 844} 845 846void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 847 OS << "["; 848 Expr *receiver = Mess->getReceiver(); 849 if (receiver) PrintExpr(receiver); 850 else OS << Mess->getClassName()->getName(); 851 OS << ' '; 852 Selector selector = Mess->getSelector(); 853 if (selector.isUnarySelector()) { 854 OS << selector.getIdentifierInfoForSlot(0)->getName(); 855 } else { 856 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 857 if (i < selector.getNumArgs()) { 858 if (i > 0) OS << ' '; 859 if (selector.getIdentifierInfoForSlot(i)) 860 OS << selector.getIdentifierInfoForSlot(i)->getName() << ":"; 861 else 862 OS << ":"; 863 } 864 else OS << ", "; // Handle variadic methods. 865 866 PrintExpr(Mess->getArg(i)); 867 } 868 } 869 OS << "]"; 870} 871 872//===----------------------------------------------------------------------===// 873// Stmt method implementations 874//===----------------------------------------------------------------------===// 875 876void Stmt::dumpPretty() const { 877 printPretty(*llvm::cerr.stream()); 878} 879 880void Stmt::printPretty(std::ostream &OS, PrinterHelper* Helper) const { 881 if (this == 0) { 882 OS << "<NULL>"; 883 return; 884 } 885 886 StmtPrinter P(OS, Helper); 887 P.Visit(const_cast<Stmt*>(this)); 888} 889 890//===----------------------------------------------------------------------===// 891// PrinterHelper 892//===----------------------------------------------------------------------===// 893 894// Implement virtual destructor. 895PrinterHelper::~PrinterHelper() {} 896