StmtPrinter.cpp revision 88a3514f36de96b19cdf50141c640df1a5f13f6c
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/DeclObjC.h" 17#include "clang/AST/PrettyPrinter.h" 18#include "llvm/Support/Compiler.h" 19#include "llvm/Support/Streams.h" 20#include "llvm/Support/Format.h" 21using namespace clang; 22 23//===----------------------------------------------------------------------===// 24// StmtPrinter Visitor 25//===----------------------------------------------------------------------===// 26 27namespace { 28 class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> { 29 llvm::raw_ostream &OS; 30 unsigned IndentLevel; 31 clang::PrinterHelper* Helper; 32 public: 33 StmtPrinter(llvm::raw_ostream &os, PrinterHelper* helper) : 34 OS(os), IndentLevel(0), Helper(helper) {} 35 36 void PrintStmt(Stmt *S, int SubIndent = 1) { 37 IndentLevel += SubIndent; 38 if (S && isa<Expr>(S)) { 39 // If this is an expr used in a stmt context, indent and newline it. 40 Indent(); 41 Visit(S); 42 OS << ";\n"; 43 } else if (S) { 44 Visit(S); 45 } else { 46 Indent() << "<<<NULL STATEMENT>>>\n"; 47 } 48 IndentLevel -= SubIndent; 49 } 50 51 void PrintRawCompoundStmt(CompoundStmt *S); 52 void PrintRawDecl(Decl *D); 53 void PrintRawDeclStmt(DeclStmt *S); 54 void PrintRawIfStmt(IfStmt *If); 55 56 void PrintExpr(Expr *E) { 57 if (E) 58 Visit(E); 59 else 60 OS << "<null expr>"; 61 } 62 63 llvm::raw_ostream &Indent(int Delta = 0) const { 64 for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 65 OS << " "; 66 return OS; 67 } 68 69 bool PrintOffsetOfDesignator(Expr *E); 70 void VisitUnaryOffsetOf(UnaryOperator *Node); 71 72 void Visit(Stmt* S) { 73 if (Helper && Helper->handledStmt(S,OS)) 74 return; 75 else StmtVisitor<StmtPrinter>::Visit(S); 76 } 77 78 void VisitStmt(Stmt *Node); 79#define STMT(CLASS, PARENT) \ 80 void Visit##CLASS(CLASS *Node); 81#include "clang/AST/StmtNodes.def" 82 }; 83} 84 85//===----------------------------------------------------------------------===// 86// Stmt printing methods. 87//===----------------------------------------------------------------------===// 88 89void StmtPrinter::VisitStmt(Stmt *Node) { 90 Indent() << "<<unknown stmt type>>\n"; 91} 92 93/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 94/// with no newline after the }. 95void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 96 OS << "{\n"; 97 for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end(); 98 I != E; ++I) 99 PrintStmt(*I); 100 101 Indent() << "}"; 102} 103 104void StmtPrinter::PrintRawDecl(Decl *D) { 105 // FIXME: Need to complete/beautify this... this code simply shows the 106 // nodes are where they need to be. 107 if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) { 108 OS << "typedef " << localType->getUnderlyingType().getAsString(); 109 OS << " " << localType->getNameAsString(); 110 } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 111 // Emit storage class for vardecls. 112 if (VarDecl *V = dyn_cast<VarDecl>(VD)) { 113 switch (V->getStorageClass()) { 114 default: assert(0 && "Unknown storage class!"); 115 case VarDecl::None: break; 116 case VarDecl::Extern: OS << "extern "; break; 117 case VarDecl::Static: OS << "static "; break; 118 case VarDecl::Auto: OS << "auto "; break; 119 case VarDecl::Register: OS << "register "; break; 120 } 121 } 122 123 std::string Name = VD->getNameAsString(); 124 VD->getType().getAsStringInternal(Name); 125 OS << Name; 126 127 // If this is a vardecl with an initializer, emit it. 128 if (VarDecl *V = dyn_cast<VarDecl>(VD)) { 129 if (V->getInit()) { 130 OS << " = "; 131 PrintExpr(V->getInit()); 132 } 133 } 134 } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) { 135 // print a free standing tag decl (e.g. "struct x;"). 136 OS << TD->getKindName(); 137 OS << " "; 138 if (const IdentifierInfo *II = TD->getIdentifier()) 139 OS << II->getName(); 140 else 141 OS << "<anonymous>"; 142 // FIXME: print tag bodies. 143 } else { 144 assert(0 && "Unexpected decl"); 145 } 146} 147 148void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) { 149 bool isFirst = false; 150 151 for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end(); 152 I != E; ++I) { 153 154 if (!isFirst) OS << ", "; 155 else isFirst = false; 156 157 PrintRawDecl(*I); 158 } 159} 160 161void StmtPrinter::VisitNullStmt(NullStmt *Node) { 162 Indent() << ";\n"; 163} 164 165void StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 166 for (DeclStmt::decl_iterator I = Node->decl_begin(), E = Node->decl_end(); 167 I!=E; ++I) { 168 Indent(); 169 PrintRawDecl(*I); 170 OS << ";\n"; 171 } 172} 173 174void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 175 Indent(); 176 PrintRawCompoundStmt(Node); 177 OS << "\n"; 178} 179 180void StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 181 Indent(-1) << "case "; 182 PrintExpr(Node->getLHS()); 183 if (Node->getRHS()) { 184 OS << " ... "; 185 PrintExpr(Node->getRHS()); 186 } 187 OS << ":\n"; 188 189 PrintStmt(Node->getSubStmt(), 0); 190} 191 192void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 193 Indent(-1) << "default:\n"; 194 PrintStmt(Node->getSubStmt(), 0); 195} 196 197void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 198 Indent(-1) << Node->getName() << ":\n"; 199 PrintStmt(Node->getSubStmt(), 0); 200} 201 202void StmtPrinter::PrintRawIfStmt(IfStmt *If) { 203 OS << "if "; 204 PrintExpr(If->getCond()); 205 206 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) { 207 OS << ' '; 208 PrintRawCompoundStmt(CS); 209 OS << (If->getElse() ? ' ' : '\n'); 210 } else { 211 OS << '\n'; 212 PrintStmt(If->getThen()); 213 if (If->getElse()) Indent(); 214 } 215 216 if (Stmt *Else = If->getElse()) { 217 OS << "else"; 218 219 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) { 220 OS << ' '; 221 PrintRawCompoundStmt(CS); 222 OS << '\n'; 223 } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) { 224 OS << ' '; 225 PrintRawIfStmt(ElseIf); 226 } else { 227 OS << '\n'; 228 PrintStmt(If->getElse()); 229 } 230 } 231} 232 233void StmtPrinter::VisitIfStmt(IfStmt *If) { 234 Indent(); 235 PrintRawIfStmt(If); 236} 237 238void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 239 Indent() << "switch ("; 240 PrintExpr(Node->getCond()); 241 OS << ")"; 242 243 // Pretty print compoundstmt bodies (very common). 244 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 245 OS << " "; 246 PrintRawCompoundStmt(CS); 247 OS << "\n"; 248 } else { 249 OS << "\n"; 250 PrintStmt(Node->getBody()); 251 } 252} 253 254void StmtPrinter::VisitSwitchCase(SwitchCase*) { 255 assert(0 && "SwitchCase is an abstract class"); 256} 257 258void StmtPrinter::VisitWhileStmt(WhileStmt *Node) { 259 Indent() << "while ("; 260 PrintExpr(Node->getCond()); 261 OS << ")\n"; 262 PrintStmt(Node->getBody()); 263} 264 265void StmtPrinter::VisitDoStmt(DoStmt *Node) { 266 Indent() << "do "; 267 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 268 PrintRawCompoundStmt(CS); 269 OS << " "; 270 } else { 271 OS << "\n"; 272 PrintStmt(Node->getBody()); 273 Indent(); 274 } 275 276 OS << "while "; 277 PrintExpr(Node->getCond()); 278 OS << ";\n"; 279} 280 281void StmtPrinter::VisitForStmt(ForStmt *Node) { 282 Indent() << "for ("; 283 if (Node->getInit()) { 284 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit())) 285 PrintRawDeclStmt(DS); 286 else 287 PrintExpr(cast<Expr>(Node->getInit())); 288 } 289 OS << ";"; 290 if (Node->getCond()) { 291 OS << " "; 292 PrintExpr(Node->getCond()); 293 } 294 OS << ";"; 295 if (Node->getInc()) { 296 OS << " "; 297 PrintExpr(Node->getInc()); 298 } 299 OS << ") "; 300 301 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 302 PrintRawCompoundStmt(CS); 303 OS << "\n"; 304 } else { 305 OS << "\n"; 306 PrintStmt(Node->getBody()); 307 } 308} 309 310void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) { 311 Indent() << "for ("; 312 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement())) 313 PrintRawDeclStmt(DS); 314 else 315 PrintExpr(cast<Expr>(Node->getElement())); 316 OS << " in "; 317 PrintExpr(Node->getCollection()); 318 OS << ") "; 319 320 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 321 PrintRawCompoundStmt(CS); 322 OS << "\n"; 323 } else { 324 OS << "\n"; 325 PrintStmt(Node->getBody()); 326 } 327} 328 329void StmtPrinter::VisitGotoStmt(GotoStmt *Node) { 330 Indent() << "goto " << Node->getLabel()->getName() << ";\n"; 331} 332 333void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) { 334 Indent() << "goto *"; 335 PrintExpr(Node->getTarget()); 336 OS << ";\n"; 337} 338 339void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) { 340 Indent() << "continue;\n"; 341} 342 343void StmtPrinter::VisitBreakStmt(BreakStmt *Node) { 344 Indent() << "break;\n"; 345} 346 347 348void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) { 349 Indent() << "return"; 350 if (Node->getRetValue()) { 351 OS << " "; 352 PrintExpr(Node->getRetValue()); 353 } 354 OS << ";\n"; 355} 356 357 358void StmtPrinter::VisitAsmStmt(AsmStmt *Node) { 359 Indent() << "asm "; 360 361 if (Node->isVolatile()) 362 OS << "volatile "; 363 364 OS << "("; 365 VisitStringLiteral(Node->getAsmString()); 366 367 // Outputs 368 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 || 369 Node->getNumClobbers() != 0) 370 OS << " : "; 371 372 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) { 373 if (i != 0) 374 OS << ", "; 375 376 if (!Node->getOutputName(i).empty()) { 377 OS << '['; 378 OS << Node->getOutputName(i); 379 OS << "] "; 380 } 381 382 VisitStringLiteral(Node->getOutputConstraint(i)); 383 OS << " "; 384 Visit(Node->getOutputExpr(i)); 385 } 386 387 // Inputs 388 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0) 389 OS << " : "; 390 391 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) { 392 if (i != 0) 393 OS << ", "; 394 395 if (!Node->getInputName(i).empty()) { 396 OS << '['; 397 OS << Node->getInputName(i); 398 OS << "] "; 399 } 400 401 VisitStringLiteral(Node->getInputConstraint(i)); 402 OS << " "; 403 Visit(Node->getInputExpr(i)); 404 } 405 406 // Clobbers 407 if (Node->getNumClobbers() != 0) 408 OS << " : "; 409 410 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) { 411 if (i != 0) 412 OS << ", "; 413 414 VisitStringLiteral(Node->getClobber(i)); 415 } 416 417 OS << ");\n"; 418} 419 420void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) { 421 Indent() << "@try"; 422 if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) { 423 PrintRawCompoundStmt(TS); 424 OS << "\n"; 425 } 426 427 for (ObjCAtCatchStmt *catchStmt = 428 static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts()); 429 catchStmt; 430 catchStmt = 431 static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) { 432 Indent() << "@catch("; 433 if (catchStmt->getCatchParamStmt()) { 434 if (DeclStmt *DS = dyn_cast<DeclStmt>(catchStmt->getCatchParamStmt())) 435 PrintRawDeclStmt(DS); 436 } 437 OS << ")"; 438 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) 439 { 440 PrintRawCompoundStmt(CS); 441 OS << "\n"; 442 } 443 } 444 445 if (ObjCAtFinallyStmt *FS =static_cast<ObjCAtFinallyStmt *>( 446 Node->getFinallyStmt())) { 447 Indent() << "@finally"; 448 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody())); 449 OS << "\n"; 450 } 451} 452 453void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) { 454} 455 456void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) { 457 Indent() << "@catch (...) { /* todo */ } \n"; 458} 459 460void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) { 461 Indent() << "@throw"; 462 if (Node->getThrowExpr()) { 463 OS << " "; 464 PrintExpr(Node->getThrowExpr()); 465 } 466 OS << ";\n"; 467} 468 469void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) { 470 Indent() << "@synchronized ("; 471 PrintExpr(Node->getSynchExpr()); 472 OS << ")"; 473 PrintRawCompoundStmt(Node->getSynchBody()); 474 OS << "\n"; 475} 476 477//===----------------------------------------------------------------------===// 478// Expr printing methods. 479//===----------------------------------------------------------------------===// 480 481void StmtPrinter::VisitExpr(Expr *Node) { 482 OS << "<<unknown expr type>>"; 483} 484 485void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { 486 OS << Node->getDecl()->getNameAsString(); 487} 488 489void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 490 if (Node->getBase()) { 491 PrintExpr(Node->getBase()); 492 OS << (Node->isArrow() ? "->" : "."); 493 } 494 OS << Node->getDecl()->getNameAsString(); 495} 496 497void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 498 if (Node->getBase()) { 499 PrintExpr(Node->getBase()); 500 OS << "."; 501 } 502 OS << Node->getProperty()->getNameAsCString(); 503} 504 505void StmtPrinter::VisitObjCKVCRefExpr(ObjCKVCRefExpr *Node) { 506 if (Node->getBase()) { 507 PrintExpr(Node->getBase()); 508 OS << "."; 509 } 510 // FIXME: Setter/Getter names 511} 512 513void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 514 switch (Node->getIdentType()) { 515 default: 516 assert(0 && "unknown case"); 517 case PredefinedExpr::Func: 518 OS << "__func__"; 519 break; 520 case PredefinedExpr::Function: 521 OS << "__FUNCTION__"; 522 break; 523 case PredefinedExpr::PrettyFunction: 524 OS << "__PRETTY_FUNCTION__"; 525 break; 526 } 527} 528 529void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 530 unsigned value = Node->getValue(); 531 if (Node->isWide()) 532 OS << "L"; 533 switch (value) { 534 case '\\': 535 OS << "'\\\\'"; 536 break; 537 case '\'': 538 OS << "'\\''"; 539 break; 540 case '\a': 541 // TODO: K&R: the meaning of '\\a' is different in traditional C 542 OS << "'\\a'"; 543 break; 544 case '\b': 545 OS << "'\\b'"; 546 break; 547 // Nonstandard escape sequence. 548 /*case '\e': 549 OS << "'\\e'"; 550 break;*/ 551 case '\f': 552 OS << "'\\f'"; 553 break; 554 case '\n': 555 OS << "'\\n'"; 556 break; 557 case '\r': 558 OS << "'\\r'"; 559 break; 560 case '\t': 561 OS << "'\\t'"; 562 break; 563 case '\v': 564 OS << "'\\v'"; 565 break; 566 default: 567 if (value < 256 && isprint(value)) { 568 OS << "'" << (char)value << "'"; 569 } else if (value < 256) { 570 OS << "'\\x" << llvm::format("%x", value) << "'"; 571 } else { 572 // FIXME what to really do here? 573 OS << value; 574 } 575 } 576} 577 578void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 579 bool isSigned = Node->getType()->isSignedIntegerType(); 580 OS << Node->getValue().toString(10, isSigned); 581 582 // Emit suffixes. Integer literals are always a builtin integer type. 583 switch (Node->getType()->getAsBuiltinType()->getKind()) { 584 default: assert(0 && "Unexpected type for integer literal!"); 585 case BuiltinType::Int: break; // no suffix. 586 case BuiltinType::UInt: OS << 'U'; break; 587 case BuiltinType::Long: OS << 'L'; break; 588 case BuiltinType::ULong: OS << "UL"; break; 589 case BuiltinType::LongLong: OS << "LL"; break; 590 case BuiltinType::ULongLong: OS << "ULL"; break; 591 } 592} 593void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 594 // FIXME: print value more precisely. 595 OS << Node->getValueAsApproximateDouble(); 596} 597 598void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 599 PrintExpr(Node->getSubExpr()); 600 OS << "i"; 601} 602 603void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 604 if (Str->isWide()) OS << 'L'; 605 OS << '"'; 606 607 // FIXME: this doesn't print wstrings right. 608 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) { 609 switch (Str->getStrData()[i]) { 610 default: OS << Str->getStrData()[i]; break; 611 // Handle some common ones to make dumps prettier. 612 case '\\': OS << "\\\\"; break; 613 case '"': OS << "\\\""; break; 614 case '\n': OS << "\\n"; break; 615 case '\t': OS << "\\t"; break; 616 case '\a': OS << "\\a"; break; 617 case '\b': OS << "\\b"; break; 618 } 619 } 620 OS << '"'; 621} 622void StmtPrinter::VisitParenExpr(ParenExpr *Node) { 623 OS << "("; 624 PrintExpr(Node->getSubExpr()); 625 OS << ")"; 626} 627void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 628 if (!Node->isPostfix()) { 629 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 630 631 // Print a space if this is an "identifier operator" like __real. 632 switch (Node->getOpcode()) { 633 default: break; 634 case UnaryOperator::Real: 635 case UnaryOperator::Imag: 636 case UnaryOperator::Extension: 637 OS << ' '; 638 break; 639 } 640 } 641 PrintExpr(Node->getSubExpr()); 642 643 if (Node->isPostfix()) 644 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 645} 646 647bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) { 648 if (isa<CompoundLiteralExpr>(E)) { 649 // Base case, print the type and comma. 650 OS << E->getType().getAsString() << ", "; 651 return true; 652 } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) { 653 PrintOffsetOfDesignator(ASE->getLHS()); 654 OS << "["; 655 PrintExpr(ASE->getRHS()); 656 OS << "]"; 657 return false; 658 } else { 659 MemberExpr *ME = cast<MemberExpr>(E); 660 bool IsFirst = PrintOffsetOfDesignator(ME->getBase()); 661 OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getNameAsString(); 662 return false; 663 } 664} 665 666void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) { 667 OS << "__builtin_offsetof("; 668 PrintOffsetOfDesignator(Node->getSubExpr()); 669 OS << ")"; 670} 671 672void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { 673 OS << (Node->isSizeOf() ? "sizeof" : "__alignof"); 674 if (Node->isArgumentType()) 675 OS << "(" << Node->getArgumentType().getAsString() << ")"; 676 else { 677 OS << " "; 678 PrintExpr(Node->getArgumentExpr()); 679 } 680} 681void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 682 PrintExpr(Node->getLHS()); 683 OS << "["; 684 PrintExpr(Node->getRHS()); 685 OS << "]"; 686} 687 688void StmtPrinter::VisitCallExpr(CallExpr *Call) { 689 PrintExpr(Call->getCallee()); 690 OS << "("; 691 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 692 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 693 // Don't print any defaulted arguments 694 break; 695 } 696 697 if (i) OS << ", "; 698 PrintExpr(Call->getArg(i)); 699 } 700 OS << ")"; 701} 702void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 703 PrintExpr(Node->getBase()); 704 OS << (Node->isArrow() ? "->" : "."); 705 OS << Node->getMemberDecl()->getNameAsString(); 706} 707void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 708 PrintExpr(Node->getBase()); 709 OS << "."; 710 OS << Node->getAccessor().getName(); 711} 712void StmtPrinter::VisitCastExpr(CastExpr *) { 713 assert(0 && "CastExpr is an abstract class"); 714} 715void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) { 716 assert(0 && "ExplicitCastExpr is an abstract class"); 717} 718void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) { 719 OS << "(" << Node->getType().getAsString() << ")"; 720 PrintExpr(Node->getSubExpr()); 721} 722void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 723 OS << "(" << Node->getType().getAsString() << ")"; 724 PrintExpr(Node->getInitializer()); 725} 726void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 727 // No need to print anything, simply forward to the sub expression. 728 PrintExpr(Node->getSubExpr()); 729} 730void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 731 PrintExpr(Node->getLHS()); 732 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 733 PrintExpr(Node->getRHS()); 734} 735void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 736 PrintExpr(Node->getLHS()); 737 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 738 PrintExpr(Node->getRHS()); 739} 740void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 741 PrintExpr(Node->getCond()); 742 743 if (Node->getLHS()) { 744 OS << " ? "; 745 PrintExpr(Node->getLHS()); 746 OS << " : "; 747 } 748 else { // Handle GCC extention where LHS can be NULL. 749 OS << " ?: "; 750 } 751 752 PrintExpr(Node->getRHS()); 753} 754 755// GNU extensions. 756 757void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 758 OS << "&&" << Node->getLabel()->getName(); 759} 760 761void StmtPrinter::VisitStmtExpr(StmtExpr *E) { 762 OS << "("; 763 PrintRawCompoundStmt(E->getSubStmt()); 764 OS << ")"; 765} 766 767void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) { 768 OS << "__builtin_types_compatible_p("; 769 OS << Node->getArgType1().getAsString() << ","; 770 OS << Node->getArgType2().getAsString() << ")"; 771} 772 773void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 774 OS << "__builtin_choose_expr("; 775 PrintExpr(Node->getCond()); 776 OS << ", "; 777 PrintExpr(Node->getLHS()); 778 OS << ", "; 779 PrintExpr(Node->getRHS()); 780 OS << ")"; 781} 782 783void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 784 OS << "__null"; 785} 786 787void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) { 788 OS << "__builtin_overload("; 789 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 790 if (i) OS << ", "; 791 PrintExpr(Node->getExpr(i)); 792 } 793 OS << ")"; 794} 795 796void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 797 OS << "__builtin_shufflevector("; 798 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 799 if (i) OS << ", "; 800 PrintExpr(Node->getExpr(i)); 801 } 802 OS << ")"; 803} 804 805void StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 806 OS << "{ "; 807 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 808 if (i) OS << ", "; 809 PrintExpr(Node->getInit(i)); 810 } 811 OS << " }"; 812} 813 814void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 815 OS << "va_arg("; 816 PrintExpr(Node->getSubExpr()); 817 OS << ", "; 818 OS << Node->getType().getAsString(); 819 OS << ")"; 820} 821 822// C++ 823void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 824 const char *OpStrings[NUM_OVERLOADED_OPERATORS] = { 825 "", 826#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 827 Spelling, 828#include "clang/Basic/OperatorKinds.def" 829 }; 830 831 OverloadedOperatorKind Kind = Node->getOperator(); 832 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 833 if (Node->getNumArgs() == 1) { 834 OS << OpStrings[Kind] << ' '; 835 PrintExpr(Node->getArg(0)); 836 } else { 837 PrintExpr(Node->getArg(0)); 838 OS << ' ' << OpStrings[Kind]; 839 } 840 } else if (Kind == OO_Call) { 841 PrintExpr(Node->getArg(0)); 842 OS << '('; 843 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 844 if (ArgIdx > 1) 845 OS << ", "; 846 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 847 PrintExpr(Node->getArg(ArgIdx)); 848 } 849 OS << ')'; 850 } else if (Kind == OO_Subscript) { 851 PrintExpr(Node->getArg(0)); 852 OS << '['; 853 PrintExpr(Node->getArg(1)); 854 OS << ']'; 855 } else if (Node->getNumArgs() == 1) { 856 OS << OpStrings[Kind] << ' '; 857 PrintExpr(Node->getArg(0)); 858 } else if (Node->getNumArgs() == 2) { 859 PrintExpr(Node->getArg(0)); 860 OS << ' ' << OpStrings[Kind] << ' '; 861 PrintExpr(Node->getArg(1)); 862 } else { 863 assert(false && "unknown overloaded operator"); 864 } 865} 866 867void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 868 VisitCallExpr(cast<CallExpr>(Node)); 869} 870 871void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 872 OS << Node->getCastName() << '<'; 873 OS << Node->getTypeAsWritten().getAsString() << ">("; 874 PrintExpr(Node->getSubExpr()); 875 OS << ")"; 876} 877 878void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 879 VisitCXXNamedCastExpr(Node); 880} 881 882void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 883 VisitCXXNamedCastExpr(Node); 884} 885 886void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 887 VisitCXXNamedCastExpr(Node); 888} 889 890void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 891 VisitCXXNamedCastExpr(Node); 892} 893 894void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 895 OS << "typeid("; 896 if (Node->isTypeOperand()) { 897 OS << Node->getTypeOperand().getAsString(); 898 } else { 899 PrintExpr(Node->getExprOperand()); 900 } 901 OS << ")"; 902} 903 904void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 905 OS << (Node->getValue() ? "true" : "false"); 906} 907 908void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 909 OS << "this"; 910} 911 912void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 913 if (Node->getSubExpr() == 0) 914 OS << "throw"; 915 else { 916 OS << "throw "; 917 PrintExpr(Node->getSubExpr()); 918 } 919} 920 921void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 922 // Nothing to print: we picked up the default argument 923} 924 925void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 926 OS << Node->getType().getAsString(); 927 OS << "("; 928 PrintExpr(Node->getSubExpr()); 929 OS << ")"; 930} 931 932void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) { 933 OS << Node->getType().getAsString() << "()"; 934} 935 936void 937StmtPrinter::VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E) { 938 PrintRawDecl(E->getVarDecl()); 939} 940 941void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 942 if (E->isGlobalNew()) 943 OS << "::"; 944 OS << "new "; 945 unsigned NumPlace = E->getNumPlacementArgs(); 946 if (NumPlace > 0) { 947 OS << "("; 948 PrintExpr(E->getPlacementArg(0)); 949 for (unsigned i = 1; i < NumPlace; ++i) { 950 OS << ", "; 951 PrintExpr(E->getPlacementArg(i)); 952 } 953 OS << ") "; 954 } 955 if (E->isParenTypeId()) 956 OS << "("; 957 std::string TypeS; 958 if (Expr *Size = E->getArraySize()) { 959 llvm::raw_string_ostream s(TypeS); 960 Size->printPretty(s); 961 s.flush(); 962 TypeS = "[" + TypeS + "]"; 963 } 964 E->getAllocatedType().getAsStringInternal(TypeS); 965 OS << TypeS; 966 if (E->isParenTypeId()) 967 OS << ")"; 968 969 if (E->hasInitializer()) { 970 OS << "("; 971 unsigned NumCons = E->getNumConstructorArgs(); 972 if (NumCons > 0) { 973 PrintExpr(E->getConstructorArg(0)); 974 for (unsigned i = 1; i < NumCons; ++i) { 975 OS << ", "; 976 PrintExpr(E->getConstructorArg(i)); 977 } 978 } 979 OS << ")"; 980 } 981} 982 983void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 984 if (E->isGlobalDelete()) 985 OS << "::"; 986 OS << "delete "; 987 if (E->isArrayForm()) 988 OS << "[] "; 989 PrintExpr(E->getArgument()); 990} 991 992void StmtPrinter::VisitCXXDependentNameExpr(CXXDependentNameExpr *E) { 993 OS << E->getName()->getName(); 994} 995 996// Obj-C 997 998void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 999 OS << "@"; 1000 VisitStringLiteral(Node->getString()); 1001} 1002 1003void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 1004 OS << "@encode(" << Node->getEncodedType().getAsString() << ')'; 1005} 1006 1007void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 1008 OS << "@selector(" << Node->getSelector().getAsString() << ')'; 1009} 1010 1011void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 1012 OS << "@protocol(" << Node->getProtocol()->getNameAsString() << ')'; 1013} 1014 1015void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 1016 OS << "["; 1017 Expr *receiver = Mess->getReceiver(); 1018 if (receiver) PrintExpr(receiver); 1019 else OS << Mess->getClassName()->getName(); 1020 OS << ' '; 1021 Selector selector = Mess->getSelector(); 1022 if (selector.isUnarySelector()) { 1023 OS << selector.getIdentifierInfoForSlot(0)->getName(); 1024 } else { 1025 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 1026 if (i < selector.getNumArgs()) { 1027 if (i > 0) OS << ' '; 1028 if (selector.getIdentifierInfoForSlot(i)) 1029 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 1030 else 1031 OS << ":"; 1032 } 1033 else OS << ", "; // Handle variadic methods. 1034 1035 PrintExpr(Mess->getArg(i)); 1036 } 1037 } 1038 OS << "]"; 1039} 1040 1041void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) { 1042 OS << "super"; 1043} 1044 1045void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 1046 BlockDecl *BD = Node->getBlockDecl(); 1047 OS << "^"; 1048 1049 const FunctionType *AFT = Node->getFunctionType(); 1050 1051 if (isa<FunctionTypeNoProto>(AFT)) { 1052 OS << "()"; 1053 } else if (!BD->param_empty() || cast<FunctionTypeProto>(AFT)->isVariadic()) { 1054 OS << '('; 1055 std::string ParamStr; 1056 for (BlockDecl::param_iterator AI = BD->param_begin(), 1057 E = BD->param_end(); AI != E; ++AI) { 1058 if (AI != BD->param_begin()) OS << ", "; 1059 ParamStr = (*AI)->getNameAsString(); 1060 (*AI)->getType().getAsStringInternal(ParamStr); 1061 OS << ParamStr; 1062 } 1063 1064 const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT); 1065 if (FT->isVariadic()) { 1066 if (!BD->param_empty()) OS << ", "; 1067 OS << "..."; 1068 } 1069 OS << ')'; 1070 } 1071} 1072 1073void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) { 1074 OS << Node->getDecl()->getNameAsString(); 1075} 1076//===----------------------------------------------------------------------===// 1077// Stmt method implementations 1078//===----------------------------------------------------------------------===// 1079 1080void Stmt::dumpPretty() const { 1081 printPretty(llvm::errs()); 1082} 1083 1084void Stmt::printPretty(llvm::raw_ostream &OS, PrinterHelper* Helper) const { 1085 if (this == 0) { 1086 OS << "<NULL>"; 1087 return; 1088 } 1089 1090 StmtPrinter P(OS, Helper); 1091 P.Visit(const_cast<Stmt*>(this)); 1092} 1093 1094//===----------------------------------------------------------------------===// 1095// PrinterHelper 1096//===----------------------------------------------------------------------===// 1097 1098// Implement virtual destructor. 1099PrinterHelper::~PrinterHelper() {} 1100