StmtPrinter.cpp revision ae7840776d6cd31b4d7a4a345b61bcbb3744df6c
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::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 480 if (Node->getBase()) { 481 PrintExpr(Node->getBase()); 482 OS << (Node->isArrow() ? "->" : "."); 483 } 484 OS << Node->getDecl()->getName(); 485} 486 487void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 488 if (Node->getBase()) { 489 PrintExpr(Node->getBase()); 490 OS << "."; 491 } 492 // FIXME: OS << Node->getDecl()->getName(); 493} 494 495void StmtPrinter::VisitPreDefinedExpr(PreDefinedExpr *Node) { 496 switch (Node->getIdentType()) { 497 default: 498 assert(0 && "unknown case"); 499 case PreDefinedExpr::Func: 500 OS << "__func__"; 501 break; 502 case PreDefinedExpr::Function: 503 OS << "__FUNCTION__"; 504 break; 505 case PreDefinedExpr::PrettyFunction: 506 OS << "__PRETTY_FUNCTION__"; 507 break; 508 } 509} 510 511void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 512 // FIXME should print an L for wchar_t constants 513 unsigned value = Node->getValue(); 514 switch (value) { 515 case '\\': 516 OS << "'\\\\'"; 517 break; 518 case '\'': 519 OS << "'\\''"; 520 break; 521 case '\a': 522 // TODO: K&R: the meaning of '\\a' is different in traditional C 523 OS << "'\\a'"; 524 break; 525 case '\b': 526 OS << "'\\b'"; 527 break; 528 // Nonstandard escape sequence. 529 /*case '\e': 530 OS << "'\\e'"; 531 break;*/ 532 case '\f': 533 OS << "'\\f'"; 534 break; 535 case '\n': 536 OS << "'\\n'"; 537 break; 538 case '\r': 539 OS << "'\\r'"; 540 break; 541 case '\t': 542 OS << "'\\t'"; 543 break; 544 case '\v': 545 OS << "'\\v'"; 546 break; 547 default: 548 if (value < 256 && isprint(value)) { 549 OS << "'" << (char)value << "'"; 550 } else if (value < 256) { 551 OS << "'\\x" << std::hex << value << std::dec << "'"; 552 } else { 553 // FIXME what to really do here? 554 OS << value; 555 } 556 } 557} 558 559void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 560 bool isSigned = Node->getType()->isSignedIntegerType(); 561 OS << Node->getValue().toString(10, isSigned); 562 563 // Emit suffixes. Integer literals are always a builtin integer type. 564 switch (cast<BuiltinType>(Node->getType().getCanonicalType())->getKind()) { 565 default: assert(0 && "Unexpected type for integer literal!"); 566 case BuiltinType::Int: break; // no suffix. 567 case BuiltinType::UInt: OS << 'U'; break; 568 case BuiltinType::Long: OS << 'L'; break; 569 case BuiltinType::ULong: OS << "UL"; break; 570 case BuiltinType::LongLong: OS << "LL"; break; 571 case BuiltinType::ULongLong: OS << "ULL"; break; 572 } 573} 574void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 575 // FIXME: print value more precisely. 576 OS << Node->getValueAsDouble(); 577} 578 579void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 580 PrintExpr(Node->getSubExpr()); 581 OS << "i"; 582} 583 584void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 585 if (Str->isWide()) OS << 'L'; 586 OS << '"'; 587 588 // FIXME: this doesn't print wstrings right. 589 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) { 590 switch (Str->getStrData()[i]) { 591 default: OS << Str->getStrData()[i]; break; 592 // Handle some common ones to make dumps prettier. 593 case '\\': OS << "\\\\"; break; 594 case '"': OS << "\\\""; break; 595 case '\n': OS << "\\n"; break; 596 case '\t': OS << "\\t"; break; 597 case '\a': OS << "\\a"; break; 598 case '\b': OS << "\\b"; break; 599 } 600 } 601 OS << '"'; 602} 603void StmtPrinter::VisitParenExpr(ParenExpr *Node) { 604 OS << "("; 605 PrintExpr(Node->getSubExpr()); 606 OS << ")"; 607} 608void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 609 if (!Node->isPostfix()) { 610 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 611 612 // Print a space if this is an "identifier operator" like sizeof or __real. 613 switch (Node->getOpcode()) { 614 default: break; 615 case UnaryOperator::SizeOf: 616 case UnaryOperator::AlignOf: 617 case UnaryOperator::Real: 618 case UnaryOperator::Imag: 619 case UnaryOperator::Extension: 620 OS << ' '; 621 break; 622 } 623 } 624 PrintExpr(Node->getSubExpr()); 625 626 if (Node->isPostfix()) 627 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 628} 629 630bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) { 631 if (isa<CompoundLiteralExpr>(E)) { 632 // Base case, print the type and comma. 633 OS << E->getType().getAsString() << ", "; 634 return true; 635 } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) { 636 PrintOffsetOfDesignator(ASE->getLHS()); 637 OS << "["; 638 PrintExpr(ASE->getRHS()); 639 OS << "]"; 640 return false; 641 } else { 642 MemberExpr *ME = cast<MemberExpr>(E); 643 bool IsFirst = PrintOffsetOfDesignator(ME->getBase()); 644 OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getName(); 645 return false; 646 } 647} 648 649void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) { 650 OS << "__builtin_offsetof("; 651 PrintOffsetOfDesignator(Node->getSubExpr()); 652 OS << ")"; 653} 654 655void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) { 656 OS << (Node->isSizeOf() ? "sizeof(" : "__alignof("); 657 OS << Node->getArgumentType().getAsString() << ")"; 658} 659void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 660 PrintExpr(Node->getLHS()); 661 OS << "["; 662 PrintExpr(Node->getRHS()); 663 OS << "]"; 664} 665 666void StmtPrinter::VisitCallExpr(CallExpr *Call) { 667 PrintExpr(Call->getCallee()); 668 OS << "("; 669 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 670 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 671 // Don't print any defaulted arguments 672 break; 673 } 674 675 if (i) OS << ", "; 676 PrintExpr(Call->getArg(i)); 677 } 678 OS << ")"; 679} 680void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 681 PrintExpr(Node->getBase()); 682 OS << (Node->isArrow() ? "->" : "."); 683 684 FieldDecl *Field = Node->getMemberDecl(); 685 assert(Field && "MemberExpr should alway reference a field!"); 686 OS << Field->getName(); 687} 688void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 689 PrintExpr(Node->getBase()); 690 OS << "."; 691 OS << Node->getAccessor().getName(); 692} 693void StmtPrinter::VisitCastExpr(CastExpr *Node) { 694 OS << "(" << Node->getType().getAsString() << ")"; 695 PrintExpr(Node->getSubExpr()); 696} 697void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 698 OS << "(" << Node->getType().getAsString() << ")"; 699 PrintExpr(Node->getInitializer()); 700} 701void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 702 // No need to print anything, simply forward to the sub expression. 703 PrintExpr(Node->getSubExpr()); 704} 705void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 706 PrintExpr(Node->getLHS()); 707 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 708 PrintExpr(Node->getRHS()); 709} 710void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 711 PrintExpr(Node->getLHS()); 712 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 713 PrintExpr(Node->getRHS()); 714} 715void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 716 PrintExpr(Node->getCond()); 717 718 if (Node->getLHS()) { 719 OS << " ? "; 720 PrintExpr(Node->getLHS()); 721 OS << " : "; 722 } 723 else { // Handle GCC extention where LHS can be NULL. 724 OS << " ?: "; 725 } 726 727 PrintExpr(Node->getRHS()); 728} 729 730// GNU extensions. 731 732void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 733 OS << "&&" << Node->getLabel()->getName(); 734} 735 736void StmtPrinter::VisitStmtExpr(StmtExpr *E) { 737 OS << "("; 738 PrintRawCompoundStmt(E->getSubStmt()); 739 OS << ")"; 740} 741 742void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) { 743 OS << "__builtin_types_compatible_p("; 744 OS << Node->getArgType1().getAsString() << ","; 745 OS << Node->getArgType2().getAsString() << ")"; 746} 747 748void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 749 OS << "__builtin_choose_expr("; 750 PrintExpr(Node->getCond()); 751 OS << ", "; 752 PrintExpr(Node->getLHS()); 753 OS << ", "; 754 PrintExpr(Node->getRHS()); 755 OS << ")"; 756} 757 758void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) { 759 OS << "__builtin_overload("; 760 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 761 if (i) OS << ", "; 762 PrintExpr(Node->getExpr(i)); 763 } 764 OS << ")"; 765} 766 767void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 768 OS << "__builtin_shufflevector("; 769 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 770 if (i) OS << ", "; 771 PrintExpr(Node->getExpr(i)); 772 } 773 OS << ")"; 774} 775 776void StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 777 OS << "{ "; 778 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 779 if (i) OS << ", "; 780 PrintExpr(Node->getInit(i)); 781 } 782 OS << " }"; 783} 784 785void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 786 OS << "va_arg("; 787 PrintExpr(Node->getSubExpr()); 788 OS << ", "; 789 OS << Node->getType().getAsString(); 790 OS << ")"; 791} 792 793// C++ 794 795void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) { 796 OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<'; 797 OS << Node->getDestType().getAsString() << ">("; 798 PrintExpr(Node->getSubExpr()); 799 OS << ")"; 800} 801 802void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 803 OS << (Node->getValue() ? "true" : "false"); 804} 805 806void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 807 if (Node->getSubExpr() == 0) 808 OS << "throw"; 809 else { 810 OS << "throw "; 811 PrintExpr(Node->getSubExpr()); 812 } 813} 814 815void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 816 // Nothing to print: we picked up the default argument 817} 818 819// Obj-C 820 821void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 822 OS << "@"; 823 VisitStringLiteral(Node->getString()); 824} 825 826void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 827 OS << "@encode(" << Node->getEncodedType().getAsString() << ")"; 828} 829 830void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 831 OS << "@selector(" << Node->getSelector().getName() << ")"; 832} 833 834void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 835 OS << "@protocol(" << Node->getProtocol()->getName() << ")"; 836} 837 838void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 839 OS << "["; 840 Expr *receiver = Mess->getReceiver(); 841 if (receiver) PrintExpr(receiver); 842 else OS << Mess->getClassName()->getName(); 843 OS << ' '; 844 Selector selector = Mess->getSelector(); 845 if (selector.isUnarySelector()) { 846 OS << selector.getIdentifierInfoForSlot(0)->getName(); 847 } else { 848 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 849 if (i < selector.getNumArgs()) { 850 if (i > 0) OS << ' '; 851 if (selector.getIdentifierInfoForSlot(i)) 852 OS << selector.getIdentifierInfoForSlot(i)->getName() << ":"; 853 else 854 OS << ":"; 855 } 856 else OS << ", "; // Handle variadic methods. 857 858 PrintExpr(Mess->getArg(i)); 859 } 860 } 861 OS << "]"; 862} 863 864//===----------------------------------------------------------------------===// 865// Stmt method implementations 866//===----------------------------------------------------------------------===// 867 868void Stmt::dumpPretty() const { 869 printPretty(*llvm::cerr.stream()); 870} 871 872void Stmt::printPretty(std::ostream &OS, PrinterHelper* Helper) const { 873 if (this == 0) { 874 OS << "<NULL>"; 875 return; 876 } 877 878 StmtPrinter P(OS, Helper); 879 P.Visit(const_cast<Stmt*>(this)); 880} 881 882//===----------------------------------------------------------------------===// 883// PrinterHelper 884//===----------------------------------------------------------------------===// 885 886// Implement virtual destructor. 887PrinterHelper::~PrinterHelper() {} 888