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