StmtPrinter.cpp revision 202379
152419Sjulian//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===// 252419Sjulian// 352419Sjulian// The LLVM Compiler Infrastructure 452419Sjulian// 552419Sjulian// This file is distributed under the University of Illinois Open Source 652419Sjulian// License. See LICENSE.TXT for details. 752419Sjulian// 852419Sjulian//===----------------------------------------------------------------------===// 952419Sjulian// 1052419Sjulian// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which 1152419Sjulian// pretty print the AST back out to C code. 1252419Sjulian// 1352419Sjulian//===----------------------------------------------------------------------===// 1452419Sjulian 1552419Sjulian#include "clang/AST/StmtVisitor.h" 1652419Sjulian#include "clang/AST/DeclCXX.h" 1752419Sjulian#include "clang/AST/DeclObjC.h" 1852419Sjulian#include "clang/AST/PrettyPrinter.h" 1952419Sjulian#include "llvm/Support/Format.h" 2052419Sjulianusing namespace clang; 2152419Sjulian 2252419Sjulian//===----------------------------------------------------------------------===// 2352419Sjulian// StmtPrinter Visitor 2452419Sjulian//===----------------------------------------------------------------------===// 2552419Sjulian 2652419Sjuliannamespace { 2752419Sjulian class StmtPrinter : public StmtVisitor<StmtPrinter> { 2852419Sjulian llvm::raw_ostream &OS; 2952419Sjulian ASTContext &Context; 3052419Sjulian unsigned IndentLevel; 3152419Sjulian clang::PrinterHelper* Helper; 3252419Sjulian PrintingPolicy Policy; 3352419Sjulian 3452419Sjulian public: 3552419Sjulian StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper, 3652419Sjulian const PrintingPolicy &Policy, 3752419Sjulian unsigned Indentation = 0) 3852419Sjulian : OS(os), Context(C), IndentLevel(Indentation), Helper(helper), 3952419Sjulian Policy(Policy) {} 4052419Sjulian 4152419Sjulian void PrintStmt(Stmt *S) { 4252419Sjulian PrintStmt(S, Policy.Indentation); 4352419Sjulian } 4453913Sarchie 4552419Sjulian void PrintStmt(Stmt *S, int SubIndent) { 4653913Sarchie IndentLevel += SubIndent; 4753913Sarchie if (S && isa<Expr>(S)) { 4853913Sarchie // If this is an expr used in a stmt context, indent and newline it. 4953913Sarchie Indent(); 5052419Sjulian Visit(S); 5152419Sjulian OS << ";\n"; 5252419Sjulian } else if (S) { 5352419Sjulian Visit(S); 5452419Sjulian } else { 5552419Sjulian Indent() << "<<<NULL STATEMENT>>>\n"; 5653913Sarchie } 5753913Sarchie IndentLevel -= SubIndent; 5852419Sjulian } 5953913Sarchie 6053913Sarchie void PrintRawCompoundStmt(CompoundStmt *S); 6152419Sjulian void PrintRawDecl(Decl *D); 6253913Sarchie void PrintRawDeclStmt(DeclStmt *S); 6353913Sarchie void PrintRawIfStmt(IfStmt *If); 6453913Sarchie void PrintRawCXXCatchStmt(CXXCatchStmt *Catch); 6552419Sjulian 6653913Sarchie void PrintExpr(Expr *E) { 6753913Sarchie if (E) 6853913Sarchie Visit(E); 6953913Sarchie else 7053913Sarchie OS << "<null expr>"; 7152419Sjulian } 7253913Sarchie 7353913Sarchie llvm::raw_ostream &Indent(int Delta = 0) { 7453913Sarchie for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 7553913Sarchie OS << " "; 7653913Sarchie return OS; 7753913Sarchie } 7853913Sarchie 7953913Sarchie bool PrintOffsetOfDesignator(Expr *E); 8053913Sarchie void VisitUnaryOffsetOf(UnaryOperator *Node); 8153913Sarchie 8253913Sarchie void Visit(Stmt* S) { 8352419Sjulian if (Helper && Helper->handledStmt(S,OS)) 8452419Sjulian return; 8552419Sjulian else StmtVisitor<StmtPrinter>::Visit(S); 8652419Sjulian } 8752419Sjulian 8852419Sjulian void VisitStmt(Stmt *Node); 8952419Sjulian#define STMT(CLASS, PARENT) \ 9052419Sjulian void Visit##CLASS(CLASS *Node); 9152419Sjulian#include "clang/AST/StmtNodes.def" 9252419Sjulian }; 9352419Sjulian} 9453913Sarchie 9553913Sarchie//===----------------------------------------------------------------------===// 9653913Sarchie// Stmt printing methods. 9753913Sarchie//===----------------------------------------------------------------------===// 9853913Sarchie 9953913Sarchievoid StmtPrinter::VisitStmt(Stmt *Node) { 10053913Sarchie Indent() << "<<unknown stmt type>>\n"; 10153913Sarchie} 10253913Sarchie 10353913Sarchie/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 10453913Sarchie/// with no newline after the }. 10553913Sarchievoid StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 10654098Sarchie OS << "{\n"; 10753913Sarchie for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end(); 10853913Sarchie I != E; ++I) 10953913Sarchie PrintStmt(*I); 11053913Sarchie 11153913Sarchie Indent() << "}"; 11253913Sarchie} 11353913Sarchie 11453913Sarchievoid StmtPrinter::PrintRawDecl(Decl *D) { 11553913Sarchie D->print(OS, Policy, IndentLevel); 11653913Sarchie} 11753913Sarchie 11853913Sarchievoid StmtPrinter::PrintRawDeclStmt(DeclStmt *S) { 11953913Sarchie DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end(); 12053913Sarchie llvm::SmallVector<Decl*, 2> Decls; 12153913Sarchie for ( ; Begin != End; ++Begin) 12253913Sarchie Decls.push_back(*Begin); 12353913Sarchie 12453913Sarchie Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel); 12553913Sarchie} 12653913Sarchie 12753913Sarchievoid StmtPrinter::VisitNullStmt(NullStmt *Node) { 12853913Sarchie Indent() << ";\n"; 12953913Sarchie} 13053913Sarchie 13153913Sarchievoid StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 13253913Sarchie Indent(); 13353913Sarchie PrintRawDeclStmt(Node); 13452419Sjulian OS << ";\n"; 13552419Sjulian} 13652419Sjulian 13752419Sjulianvoid StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 13852419Sjulian Indent(); 13952419Sjulian PrintRawCompoundStmt(Node); 14052419Sjulian OS << "\n"; 14152419Sjulian} 14252419Sjulian 14352419Sjulianvoid StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 14452419Sjulian Indent(-1) << "case "; 14552419Sjulian PrintExpr(Node->getLHS()); 14652419Sjulian if (Node->getRHS()) { 14752419Sjulian OS << " ... "; 14852419Sjulian PrintExpr(Node->getRHS()); 14952419Sjulian } 15052419Sjulian OS << ":\n"; 15152419Sjulian 15252419Sjulian PrintStmt(Node->getSubStmt(), 0); 15352419Sjulian} 15452419Sjulian 15552419Sjulianvoid StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 15652419Sjulian Indent(-1) << "default:\n"; 15752419Sjulian PrintStmt(Node->getSubStmt(), 0); 15852419Sjulian} 15952419Sjulian 16052419Sjulianvoid StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 16152419Sjulian Indent(-1) << Node->getName() << ":\n"; 16252419Sjulian PrintStmt(Node->getSubStmt(), 0); 16352419Sjulian} 16453913Sarchie 16552419Sjulianvoid StmtPrinter::PrintRawIfStmt(IfStmt *If) { 16652419Sjulian OS << "if ("; 16752419Sjulian PrintExpr(If->getCond()); 16852419Sjulian OS << ')'; 16952419Sjulian 17053913Sarchie if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) { 17153913Sarchie OS << ' '; 17252419Sjulian PrintRawCompoundStmt(CS); 17352419Sjulian OS << (If->getElse() ? ' ' : '\n'); 17452419Sjulian } else { 17552419Sjulian OS << '\n'; 17653913Sarchie PrintStmt(If->getThen()); 17752419Sjulian if (If->getElse()) Indent(); 17853913Sarchie } 17953913Sarchie 18053913Sarchie if (Stmt *Else = If->getElse()) { 18153913Sarchie OS << "else"; 18253913Sarchie 18353913Sarchie if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) { 18453913Sarchie OS << ' '; 18553913Sarchie PrintRawCompoundStmt(CS); 18653913Sarchie OS << '\n'; 18753913Sarchie } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) { 18852419Sjulian OS << ' '; 18952419Sjulian PrintRawIfStmt(ElseIf); 19052419Sjulian } else { 19152419Sjulian OS << '\n'; 19253913Sarchie PrintStmt(If->getElse()); 19353913Sarchie } 19453913Sarchie } 19552419Sjulian} 19653913Sarchie 19753913Sarchievoid StmtPrinter::VisitIfStmt(IfStmt *If) { 19853913Sarchie Indent(); 19952419Sjulian PrintRawIfStmt(If); 20053913Sarchie} 20153913Sarchie 20253913Sarchievoid StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 20353913Sarchie Indent() << "switch ("; 20452419Sjulian PrintExpr(Node->getCond()); 20553913Sarchie OS << ")"; 20653913Sarchie 20753913Sarchie // Pretty print compoundstmt bodies (very common). 20852419Sjulian if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 20953913Sarchie OS << " "; 21053913Sarchie PrintRawCompoundStmt(CS); 21153913Sarchie OS << "\n"; 21253913Sarchie } else { 21353913Sarchie OS << "\n"; 21453913Sarchie PrintStmt(Node->getBody()); 21553913Sarchie } 21653913Sarchie} 21753913Sarchie 21853913Sarchievoid StmtPrinter::VisitSwitchCase(SwitchCase*) { 21953913Sarchie assert(0 && "SwitchCase is an abstract class"); 22053913Sarchie} 22153913Sarchie 22253913Sarchievoid StmtPrinter::VisitWhileStmt(WhileStmt *Node) { 22353913Sarchie Indent() << "while ("; 22453913Sarchie PrintExpr(Node->getCond()); 22553913Sarchie OS << ")\n"; 22653913Sarchie PrintStmt(Node->getBody()); 22753913Sarchie} 22853913Sarchie 22953913Sarchievoid StmtPrinter::VisitDoStmt(DoStmt *Node) { 23053913Sarchie Indent() << "do "; 23153913Sarchie if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 23253913Sarchie PrintRawCompoundStmt(CS); 23353913Sarchie OS << " "; 23453913Sarchie } else { 23553913Sarchie OS << "\n"; 23653913Sarchie PrintStmt(Node->getBody()); 23753913Sarchie Indent(); 23853913Sarchie } 23953913Sarchie 24052419Sjulian OS << "while ("; 24152419Sjulian PrintExpr(Node->getCond()); 24252419Sjulian OS << ");\n"; 24353913Sarchie} 24452419Sjulian 24553913Sarchievoid StmtPrinter::VisitForStmt(ForStmt *Node) { 24653913Sarchie Indent() << "for ("; 24752419Sjulian if (Node->getInit()) { 24853913Sarchie if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit())) 24952419Sjulian PrintRawDeclStmt(DS); 25053913Sarchie else 25153913Sarchie PrintExpr(cast<Expr>(Node->getInit())); 25253913Sarchie } 25352419Sjulian OS << ";"; 25453913Sarchie if (Node->getCond()) { 25552419Sjulian OS << " "; 25652419Sjulian PrintExpr(Node->getCond()); 25752419Sjulian } 25852419Sjulian OS << ";"; 25952419Sjulian if (Node->getInc()) { 26052419Sjulian OS << " "; 26153913Sarchie PrintExpr(Node->getInc()); 26252419Sjulian } 26352419Sjulian OS << ") "; 26452419Sjulian 26552419Sjulian if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 26652419Sjulian PrintRawCompoundStmt(CS); 26752419Sjulian OS << "\n"; 26852419Sjulian } else { 26952419Sjulian OS << "\n"; 27052419Sjulian PrintStmt(Node->getBody()); 27152419Sjulian } 27252419Sjulian} 27352419Sjulian 27452419Sjulianvoid StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) { 27552419Sjulian Indent() << "for ("; 27652419Sjulian if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement())) 27752419Sjulian PrintRawDeclStmt(DS); 27852419Sjulian else 27952419Sjulian PrintExpr(cast<Expr>(Node->getElement())); 28052419Sjulian OS << " in "; 28152419Sjulian PrintExpr(Node->getCollection()); 28252419Sjulian OS << ") "; 28352419Sjulian 28452419Sjulian if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 28552419Sjulian PrintRawCompoundStmt(CS); 28652419Sjulian OS << "\n"; 28752419Sjulian } else { 28852419Sjulian OS << "\n"; 28952419Sjulian PrintStmt(Node->getBody()); 29052419Sjulian } 29152419Sjulian} 29252419Sjulian 29352419Sjulianvoid StmtPrinter::VisitGotoStmt(GotoStmt *Node) { 29452419Sjulian Indent() << "goto " << Node->getLabel()->getName() << ";\n"; 29552419Sjulian} 29652419Sjulian 29752419Sjulianvoid StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) { 298 Indent() << "goto *"; 299 PrintExpr(Node->getTarget()); 300 OS << ";\n"; 301} 302 303void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) { 304 Indent() << "continue;\n"; 305} 306 307void StmtPrinter::VisitBreakStmt(BreakStmt *Node) { 308 Indent() << "break;\n"; 309} 310 311 312void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) { 313 Indent() << "return"; 314 if (Node->getRetValue()) { 315 OS << " "; 316 PrintExpr(Node->getRetValue()); 317 } 318 OS << ";\n"; 319} 320 321 322void StmtPrinter::VisitAsmStmt(AsmStmt *Node) { 323 Indent() << "asm "; 324 325 if (Node->isVolatile()) 326 OS << "volatile "; 327 328 OS << "("; 329 VisitStringLiteral(Node->getAsmString()); 330 331 // Outputs 332 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 || 333 Node->getNumClobbers() != 0) 334 OS << " : "; 335 336 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) { 337 if (i != 0) 338 OS << ", "; 339 340 if (!Node->getOutputName(i).empty()) { 341 OS << '['; 342 OS << Node->getOutputName(i); 343 OS << "] "; 344 } 345 346 VisitStringLiteral(Node->getOutputConstraintLiteral(i)); 347 OS << " "; 348 Visit(Node->getOutputExpr(i)); 349 } 350 351 // Inputs 352 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0) 353 OS << " : "; 354 355 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) { 356 if (i != 0) 357 OS << ", "; 358 359 if (!Node->getInputName(i).empty()) { 360 OS << '['; 361 OS << Node->getInputName(i); 362 OS << "] "; 363 } 364 365 VisitStringLiteral(Node->getInputConstraintLiteral(i)); 366 OS << " "; 367 Visit(Node->getInputExpr(i)); 368 } 369 370 // Clobbers 371 if (Node->getNumClobbers() != 0) 372 OS << " : "; 373 374 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) { 375 if (i != 0) 376 OS << ", "; 377 378 VisitStringLiteral(Node->getClobber(i)); 379 } 380 381 OS << ");\n"; 382} 383 384void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) { 385 Indent() << "@try"; 386 if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) { 387 PrintRawCompoundStmt(TS); 388 OS << "\n"; 389 } 390 391 for (ObjCAtCatchStmt *catchStmt = 392 static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts()); 393 catchStmt; 394 catchStmt = 395 static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) { 396 Indent() << "@catch("; 397 if (catchStmt->getCatchParamDecl()) { 398 if (Decl *DS = catchStmt->getCatchParamDecl()) 399 PrintRawDecl(DS); 400 } 401 OS << ")"; 402 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) { 403 PrintRawCompoundStmt(CS); 404 OS << "\n"; 405 } 406 } 407 408 if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>( 409 Node->getFinallyStmt())) { 410 Indent() << "@finally"; 411 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody())); 412 OS << "\n"; 413 } 414} 415 416void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) { 417} 418 419void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) { 420 Indent() << "@catch (...) { /* todo */ } \n"; 421} 422 423void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) { 424 Indent() << "@throw"; 425 if (Node->getThrowExpr()) { 426 OS << " "; 427 PrintExpr(Node->getThrowExpr()); 428 } 429 OS << ";\n"; 430} 431 432void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) { 433 Indent() << "@synchronized ("; 434 PrintExpr(Node->getSynchExpr()); 435 OS << ")"; 436 PrintRawCompoundStmt(Node->getSynchBody()); 437 OS << "\n"; 438} 439 440void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) { 441 OS << "catch ("; 442 if (Decl *ExDecl = Node->getExceptionDecl()) 443 PrintRawDecl(ExDecl); 444 else 445 OS << "..."; 446 OS << ") "; 447 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock())); 448} 449 450void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) { 451 Indent(); 452 PrintRawCXXCatchStmt(Node); 453 OS << "\n"; 454} 455 456void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) { 457 Indent() << "try "; 458 PrintRawCompoundStmt(Node->getTryBlock()); 459 for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) { 460 OS << " "; 461 PrintRawCXXCatchStmt(Node->getHandler(i)); 462 } 463 OS << "\n"; 464} 465 466//===----------------------------------------------------------------------===// 467// Expr printing methods. 468//===----------------------------------------------------------------------===// 469 470void StmtPrinter::VisitExpr(Expr *Node) { 471 OS << "<<unknown expr type>>"; 472} 473 474void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { 475 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 476 Qualifier->print(OS, Policy); 477 OS << Node->getDecl()->getNameAsString(); 478 if (Node->hasExplicitTemplateArgumentList()) 479 OS << TemplateSpecializationType::PrintTemplateArgumentList( 480 Node->getTemplateArgs(), 481 Node->getNumTemplateArgs(), 482 Policy); 483} 484 485void StmtPrinter::VisitDependentScopeDeclRefExpr( 486 DependentScopeDeclRefExpr *Node) { 487 Node->getQualifier()->print(OS, Policy); 488 OS << Node->getDeclName().getAsString(); 489 if (Node->hasExplicitTemplateArgs()) 490 OS << TemplateSpecializationType::PrintTemplateArgumentList( 491 Node->getTemplateArgs(), 492 Node->getNumTemplateArgs(), 493 Policy); 494} 495 496void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 497 if (Node->getQualifier()) 498 Node->getQualifier()->print(OS, Policy); 499 OS << Node->getName().getAsString(); 500 if (Node->hasExplicitTemplateArgs()) 501 OS << TemplateSpecializationType::PrintTemplateArgumentList( 502 Node->getTemplateArgs(), 503 Node->getNumTemplateArgs(), 504 Policy); 505} 506 507void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 508 if (Node->getBase()) { 509 PrintExpr(Node->getBase()); 510 OS << (Node->isArrow() ? "->" : "."); 511 } 512 OS << Node->getDecl()->getNameAsString(); 513} 514 515void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 516 if (Node->getBase()) { 517 PrintExpr(Node->getBase()); 518 OS << "."; 519 } 520 OS << Node->getProperty()->getNameAsCString(); 521} 522 523void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr( 524 ObjCImplicitSetterGetterRefExpr *Node) { 525 if (Node->getBase()) { 526 PrintExpr(Node->getBase()); 527 OS << "."; 528 } 529 if (Node->getGetterMethod()) 530 OS << Node->getGetterMethod()->getNameAsString(); 531 532} 533 534void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 535 switch (Node->getIdentType()) { 536 default: 537 assert(0 && "unknown case"); 538 case PredefinedExpr::Func: 539 OS << "__func__"; 540 break; 541 case PredefinedExpr::Function: 542 OS << "__FUNCTION__"; 543 break; 544 case PredefinedExpr::PrettyFunction: 545 OS << "__PRETTY_FUNCTION__"; 546 break; 547 } 548} 549 550void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 551 unsigned value = Node->getValue(); 552 if (Node->isWide()) 553 OS << "L"; 554 switch (value) { 555 case '\\': 556 OS << "'\\\\'"; 557 break; 558 case '\'': 559 OS << "'\\''"; 560 break; 561 case '\a': 562 // TODO: K&R: the meaning of '\\a' is different in traditional C 563 OS << "'\\a'"; 564 break; 565 case '\b': 566 OS << "'\\b'"; 567 break; 568 // Nonstandard escape sequence. 569 /*case '\e': 570 OS << "'\\e'"; 571 break;*/ 572 case '\f': 573 OS << "'\\f'"; 574 break; 575 case '\n': 576 OS << "'\\n'"; 577 break; 578 case '\r': 579 OS << "'\\r'"; 580 break; 581 case '\t': 582 OS << "'\\t'"; 583 break; 584 case '\v': 585 OS << "'\\v'"; 586 break; 587 default: 588 if (value < 256 && isprint(value)) { 589 OS << "'" << (char)value << "'"; 590 } else if (value < 256) { 591 OS << "'\\x" << llvm::format("%x", value) << "'"; 592 } else { 593 // FIXME what to really do here? 594 OS << value; 595 } 596 } 597} 598 599void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 600 bool isSigned = Node->getType()->isSignedIntegerType(); 601 OS << Node->getValue().toString(10, isSigned); 602 603 // Emit suffixes. Integer literals are always a builtin integer type. 604 switch (Node->getType()->getAs<BuiltinType>()->getKind()) { 605 default: assert(0 && "Unexpected type for integer literal!"); 606 case BuiltinType::Int: break; // no suffix. 607 case BuiltinType::UInt: OS << 'U'; break; 608 case BuiltinType::Long: OS << 'L'; break; 609 case BuiltinType::ULong: OS << "UL"; break; 610 case BuiltinType::LongLong: OS << "LL"; break; 611 case BuiltinType::ULongLong: OS << "ULL"; break; 612 } 613} 614void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 615 // FIXME: print value more precisely. 616 OS << Node->getValueAsApproximateDouble(); 617} 618 619void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 620 PrintExpr(Node->getSubExpr()); 621 OS << "i"; 622} 623 624void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 625 if (Str->isWide()) OS << 'L'; 626 OS << '"'; 627 628 // FIXME: this doesn't print wstrings right. 629 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) { 630 unsigned char Char = Str->getStrData()[i]; 631 632 switch (Char) { 633 default: 634 if (isprint(Char)) 635 OS << (char)Char; 636 else // Output anything hard as an octal escape. 637 OS << '\\' 638 << (char)('0'+ ((Char >> 6) & 7)) 639 << (char)('0'+ ((Char >> 3) & 7)) 640 << (char)('0'+ ((Char >> 0) & 7)); 641 break; 642 // Handle some common non-printable cases to make dumps prettier. 643 case '\\': OS << "\\\\"; break; 644 case '"': OS << "\\\""; break; 645 case '\n': OS << "\\n"; break; 646 case '\t': OS << "\\t"; break; 647 case '\a': OS << "\\a"; break; 648 case '\b': OS << "\\b"; break; 649 } 650 } 651 OS << '"'; 652} 653void StmtPrinter::VisitParenExpr(ParenExpr *Node) { 654 OS << "("; 655 PrintExpr(Node->getSubExpr()); 656 OS << ")"; 657} 658void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 659 if (!Node->isPostfix()) { 660 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 661 662 // Print a space if this is an "identifier operator" like __real, or if 663 // it might be concatenated incorrectly like '+'. 664 switch (Node->getOpcode()) { 665 default: break; 666 case UnaryOperator::Real: 667 case UnaryOperator::Imag: 668 case UnaryOperator::Extension: 669 OS << ' '; 670 break; 671 case UnaryOperator::Plus: 672 case UnaryOperator::Minus: 673 if (isa<UnaryOperator>(Node->getSubExpr())) 674 OS << ' '; 675 break; 676 } 677 } 678 PrintExpr(Node->getSubExpr()); 679 680 if (Node->isPostfix()) 681 OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 682} 683 684bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) { 685 if (isa<UnaryOperator>(E)) { 686 // Base case, print the type and comma. 687 OS << E->getType().getAsString() << ", "; 688 return true; 689 } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) { 690 PrintOffsetOfDesignator(ASE->getLHS()); 691 OS << "["; 692 PrintExpr(ASE->getRHS()); 693 OS << "]"; 694 return false; 695 } else { 696 MemberExpr *ME = cast<MemberExpr>(E); 697 bool IsFirst = PrintOffsetOfDesignator(ME->getBase()); 698 OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getNameAsString(); 699 return false; 700 } 701} 702 703void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) { 704 OS << "__builtin_offsetof("; 705 PrintOffsetOfDesignator(Node->getSubExpr()); 706 OS << ")"; 707} 708 709void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { 710 OS << (Node->isSizeOf() ? "sizeof" : "__alignof"); 711 if (Node->isArgumentType()) 712 OS << "(" << Node->getArgumentType().getAsString() << ")"; 713 else { 714 OS << " "; 715 PrintExpr(Node->getArgumentExpr()); 716 } 717} 718void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 719 PrintExpr(Node->getLHS()); 720 OS << "["; 721 PrintExpr(Node->getRHS()); 722 OS << "]"; 723} 724 725void StmtPrinter::VisitCallExpr(CallExpr *Call) { 726 PrintExpr(Call->getCallee()); 727 OS << "("; 728 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 729 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 730 // Don't print any defaulted arguments 731 break; 732 } 733 734 if (i) OS << ", "; 735 PrintExpr(Call->getArg(i)); 736 } 737 OS << ")"; 738} 739void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 740 // FIXME: Suppress printing implicit bases (like "this") 741 PrintExpr(Node->getBase()); 742 if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl())) 743 if (FD->isAnonymousStructOrUnion()) 744 return; 745 OS << (Node->isArrow() ? "->" : "."); 746 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 747 Qualifier->print(OS, Policy); 748 749 OS << Node->getMemberDecl()->getNameAsString(); 750 751 if (Node->hasExplicitTemplateArgumentList()) 752 OS << TemplateSpecializationType::PrintTemplateArgumentList( 753 Node->getTemplateArgs(), 754 Node->getNumTemplateArgs(), 755 Policy); 756} 757void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) { 758 PrintExpr(Node->getBase()); 759 OS << (Node->isArrow() ? "->isa" : ".isa"); 760} 761 762void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 763 PrintExpr(Node->getBase()); 764 OS << "."; 765 OS << Node->getAccessor().getName(); 766} 767void StmtPrinter::VisitCastExpr(CastExpr *) { 768 assert(0 && "CastExpr is an abstract class"); 769} 770void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) { 771 assert(0 && "ExplicitCastExpr is an abstract class"); 772} 773void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) { 774 OS << "(" << Node->getType().getAsString() << ")"; 775 PrintExpr(Node->getSubExpr()); 776} 777void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 778 OS << "(" << Node->getType().getAsString() << ")"; 779 PrintExpr(Node->getInitializer()); 780} 781void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 782 // No need to print anything, simply forward to the sub expression. 783 PrintExpr(Node->getSubExpr()); 784} 785void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 786 PrintExpr(Node->getLHS()); 787 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 788 PrintExpr(Node->getRHS()); 789} 790void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 791 PrintExpr(Node->getLHS()); 792 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 793 PrintExpr(Node->getRHS()); 794} 795void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 796 PrintExpr(Node->getCond()); 797 798 if (Node->getLHS()) { 799 OS << " ? "; 800 PrintExpr(Node->getLHS()); 801 OS << " : "; 802 } 803 else { // Handle GCC extension where LHS can be NULL. 804 OS << " ?: "; 805 } 806 807 PrintExpr(Node->getRHS()); 808} 809 810// GNU extensions. 811 812void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 813 OS << "&&" << Node->getLabel()->getName(); 814} 815 816void StmtPrinter::VisitStmtExpr(StmtExpr *E) { 817 OS << "("; 818 PrintRawCompoundStmt(E->getSubStmt()); 819 OS << ")"; 820} 821 822void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) { 823 OS << "__builtin_types_compatible_p("; 824 OS << Node->getArgType1().getAsString() << ","; 825 OS << Node->getArgType2().getAsString() << ")"; 826} 827 828void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 829 OS << "__builtin_choose_expr("; 830 PrintExpr(Node->getCond()); 831 OS << ", "; 832 PrintExpr(Node->getLHS()); 833 OS << ", "; 834 PrintExpr(Node->getRHS()); 835 OS << ")"; 836} 837 838void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 839 OS << "__null"; 840} 841 842void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 843 OS << "__builtin_shufflevector("; 844 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 845 if (i) OS << ", "; 846 PrintExpr(Node->getExpr(i)); 847 } 848 OS << ")"; 849} 850 851void StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 852 if (Node->getSyntacticForm()) { 853 Visit(Node->getSyntacticForm()); 854 return; 855 } 856 857 OS << "{ "; 858 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 859 if (i) OS << ", "; 860 if (Node->getInit(i)) 861 PrintExpr(Node->getInit(i)); 862 else 863 OS << "0"; 864 } 865 OS << " }"; 866} 867 868void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { 869 OS << "( "; 870 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) { 871 if (i) OS << ", "; 872 PrintExpr(Node->getExpr(i)); 873 } 874 OS << " )"; 875} 876 877void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { 878 for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(), 879 DEnd = Node->designators_end(); 880 D != DEnd; ++D) { 881 if (D->isFieldDesignator()) { 882 if (D->getDotLoc().isInvalid()) 883 OS << D->getFieldName()->getName() << ":"; 884 else 885 OS << "." << D->getFieldName()->getName(); 886 } else { 887 OS << "["; 888 if (D->isArrayDesignator()) { 889 PrintExpr(Node->getArrayIndex(*D)); 890 } else { 891 PrintExpr(Node->getArrayRangeStart(*D)); 892 OS << " ... "; 893 PrintExpr(Node->getArrayRangeEnd(*D)); 894 } 895 OS << "]"; 896 } 897 } 898 899 OS << " = "; 900 PrintExpr(Node->getInit()); 901} 902 903void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { 904 if (Policy.LangOpts.CPlusPlus) 905 OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()"; 906 else { 907 OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")"; 908 if (Node->getType()->isRecordType()) 909 OS << "{}"; 910 else 911 OS << 0; 912 } 913} 914 915void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 916 OS << "__builtin_va_arg("; 917 PrintExpr(Node->getSubExpr()); 918 OS << ", "; 919 OS << Node->getType().getAsString(); 920 OS << ")"; 921} 922 923// C++ 924void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 925 const char *OpStrings[NUM_OVERLOADED_OPERATORS] = { 926 "", 927#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 928 Spelling, 929#include "clang/Basic/OperatorKinds.def" 930 }; 931 932 OverloadedOperatorKind Kind = Node->getOperator(); 933 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 934 if (Node->getNumArgs() == 1) { 935 OS << OpStrings[Kind] << ' '; 936 PrintExpr(Node->getArg(0)); 937 } else { 938 PrintExpr(Node->getArg(0)); 939 OS << ' ' << OpStrings[Kind]; 940 } 941 } else if (Kind == OO_Call) { 942 PrintExpr(Node->getArg(0)); 943 OS << '('; 944 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 945 if (ArgIdx > 1) 946 OS << ", "; 947 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 948 PrintExpr(Node->getArg(ArgIdx)); 949 } 950 OS << ')'; 951 } else if (Kind == OO_Subscript) { 952 PrintExpr(Node->getArg(0)); 953 OS << '['; 954 PrintExpr(Node->getArg(1)); 955 OS << ']'; 956 } else if (Node->getNumArgs() == 1) { 957 OS << OpStrings[Kind] << ' '; 958 PrintExpr(Node->getArg(0)); 959 } else if (Node->getNumArgs() == 2) { 960 PrintExpr(Node->getArg(0)); 961 OS << ' ' << OpStrings[Kind] << ' '; 962 PrintExpr(Node->getArg(1)); 963 } else { 964 assert(false && "unknown overloaded operator"); 965 } 966} 967 968void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 969 VisitCallExpr(cast<CallExpr>(Node)); 970} 971 972void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 973 OS << Node->getCastName() << '<'; 974 OS << Node->getTypeAsWritten().getAsString() << ">("; 975 PrintExpr(Node->getSubExpr()); 976 OS << ")"; 977} 978 979void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 980 VisitCXXNamedCastExpr(Node); 981} 982 983void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 984 VisitCXXNamedCastExpr(Node); 985} 986 987void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 988 VisitCXXNamedCastExpr(Node); 989} 990 991void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 992 VisitCXXNamedCastExpr(Node); 993} 994 995void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 996 OS << "typeid("; 997 if (Node->isTypeOperand()) { 998 OS << Node->getTypeOperand().getAsString(); 999 } else { 1000 PrintExpr(Node->getExprOperand()); 1001 } 1002 OS << ")"; 1003} 1004 1005void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 1006 OS << (Node->getValue() ? "true" : "false"); 1007} 1008 1009void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 1010 OS << "nullptr"; 1011} 1012 1013void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 1014 OS << "this"; 1015} 1016 1017void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 1018 if (Node->getSubExpr() == 0) 1019 OS << "throw"; 1020 else { 1021 OS << "throw "; 1022 PrintExpr(Node->getSubExpr()); 1023 } 1024} 1025 1026void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 1027 // Nothing to print: we picked up the default argument 1028} 1029 1030void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 1031 OS << Node->getType().getAsString(); 1032 OS << "("; 1033 PrintExpr(Node->getSubExpr()); 1034 OS << ")"; 1035} 1036 1037void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 1038 PrintExpr(Node->getSubExpr()); 1039} 1040 1041void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 1042 OS << Node->getType().getAsString(); 1043 OS << "("; 1044 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 1045 ArgEnd = Node->arg_end(); 1046 Arg != ArgEnd; ++Arg) { 1047 if (Arg != Node->arg_begin()) 1048 OS << ", "; 1049 PrintExpr(*Arg); 1050 } 1051 OS << ")"; 1052} 1053 1054void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) { 1055 OS << Node->getType().getAsString() << "()"; 1056} 1057 1058void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 1059 if (E->isGlobalNew()) 1060 OS << "::"; 1061 OS << "new "; 1062 unsigned NumPlace = E->getNumPlacementArgs(); 1063 if (NumPlace > 0) { 1064 OS << "("; 1065 PrintExpr(E->getPlacementArg(0)); 1066 for (unsigned i = 1; i < NumPlace; ++i) { 1067 OS << ", "; 1068 PrintExpr(E->getPlacementArg(i)); 1069 } 1070 OS << ") "; 1071 } 1072 if (E->isParenTypeId()) 1073 OS << "("; 1074 std::string TypeS; 1075 if (Expr *Size = E->getArraySize()) { 1076 llvm::raw_string_ostream s(TypeS); 1077 Size->printPretty(s, Context, Helper, Policy); 1078 s.flush(); 1079 TypeS = "[" + TypeS + "]"; 1080 } 1081 E->getAllocatedType().getAsStringInternal(TypeS, Policy); 1082 OS << TypeS; 1083 if (E->isParenTypeId()) 1084 OS << ")"; 1085 1086 if (E->hasInitializer()) { 1087 OS << "("; 1088 unsigned NumCons = E->getNumConstructorArgs(); 1089 if (NumCons > 0) { 1090 PrintExpr(E->getConstructorArg(0)); 1091 for (unsigned i = 1; i < NumCons; ++i) { 1092 OS << ", "; 1093 PrintExpr(E->getConstructorArg(i)); 1094 } 1095 } 1096 OS << ")"; 1097 } 1098} 1099 1100void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 1101 if (E->isGlobalDelete()) 1102 OS << "::"; 1103 OS << "delete "; 1104 if (E->isArrayForm()) 1105 OS << "[] "; 1106 PrintExpr(E->getArgument()); 1107} 1108 1109void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 1110 PrintExpr(E->getBase()); 1111 if (E->isArrow()) 1112 OS << "->"; 1113 else 1114 OS << '.'; 1115 if (E->getQualifier()) 1116 E->getQualifier()->print(OS, Policy); 1117 1118 std::string TypeS; 1119 E->getDestroyedType().getAsStringInternal(TypeS, Policy); 1120 OS << TypeS; 1121} 1122 1123void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 1124 // FIXME. For now we just print a trivial constructor call expression, 1125 // constructing its first argument object. 1126 if (E->getNumArgs() == 1) { 1127 CXXConstructorDecl *CD = E->getConstructor(); 1128 if (CD->isTrivial()) 1129 PrintExpr(E->getArg(0)); 1130 } 1131 // Nothing to print. 1132} 1133 1134void StmtPrinter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) { 1135 // Just forward to the sub expression. 1136 PrintExpr(E->getSubExpr()); 1137} 1138 1139void 1140StmtPrinter::VisitCXXUnresolvedConstructExpr( 1141 CXXUnresolvedConstructExpr *Node) { 1142 OS << Node->getTypeAsWritten().getAsString(); 1143 OS << "("; 1144 for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(), 1145 ArgEnd = Node->arg_end(); 1146 Arg != ArgEnd; ++Arg) { 1147 if (Arg != Node->arg_begin()) 1148 OS << ", "; 1149 PrintExpr(*Arg); 1150 } 1151 OS << ")"; 1152} 1153 1154void StmtPrinter::VisitCXXDependentScopeMemberExpr( 1155 CXXDependentScopeMemberExpr *Node) { 1156 if (!Node->isImplicitAccess()) { 1157 PrintExpr(Node->getBase()); 1158 OS << (Node->isArrow() ? "->" : "."); 1159 } 1160 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1161 Qualifier->print(OS, Policy); 1162 else if (Node->hasExplicitTemplateArgs()) 1163 // FIXME: Track use of "template" keyword explicitly? 1164 OS << "template "; 1165 1166 OS << Node->getMember().getAsString(); 1167 1168 if (Node->hasExplicitTemplateArgs()) { 1169 OS << TemplateSpecializationType::PrintTemplateArgumentList( 1170 Node->getTemplateArgs(), 1171 Node->getNumTemplateArgs(), 1172 Policy); 1173 } 1174} 1175 1176void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 1177 if (!Node->isImplicitAccess()) { 1178 PrintExpr(Node->getBase()); 1179 OS << (Node->isArrow() ? "->" : "."); 1180 } 1181 if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1182 Qualifier->print(OS, Policy); 1183 1184 // FIXME: this might originally have been written with 'template' 1185 1186 OS << Node->getMemberName().getAsString(); 1187 1188 if (Node->hasExplicitTemplateArgs()) { 1189 OS << TemplateSpecializationType::PrintTemplateArgumentList( 1190 Node->getTemplateArgs(), 1191 Node->getNumTemplateArgs(), 1192 Policy); 1193 } 1194} 1195 1196static const char *getTypeTraitName(UnaryTypeTrait UTT) { 1197 switch (UTT) { 1198 default: assert(false && "Unknown type trait"); 1199 case UTT_HasNothrowAssign: return "__has_nothrow_assign"; 1200 case UTT_HasNothrowCopy: return "__has_nothrow_copy"; 1201 case UTT_HasNothrowConstructor: return "__has_nothrow_constructor"; 1202 case UTT_HasTrivialAssign: return "__has_trivial_assign"; 1203 case UTT_HasTrivialCopy: return "__has_trivial_copy"; 1204 case UTT_HasTrivialConstructor: return "__has_trivial_constructor"; 1205 case UTT_HasTrivialDestructor: return "__has_trivial_destructor"; 1206 case UTT_HasVirtualDestructor: return "__has_virtual_destructor"; 1207 case UTT_IsAbstract: return "__is_abstract"; 1208 case UTT_IsClass: return "__is_class"; 1209 case UTT_IsEmpty: return "__is_empty"; 1210 case UTT_IsEnum: return "__is_enum"; 1211 case UTT_IsPOD: return "__is_pod"; 1212 case UTT_IsPolymorphic: return "__is_polymorphic"; 1213 case UTT_IsUnion: return "__is_union"; 1214 } 1215} 1216 1217void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { 1218 OS << getTypeTraitName(E->getTrait()) << "(" 1219 << E->getQueriedType().getAsString() << ")"; 1220} 1221 1222// Obj-C 1223 1224void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 1225 OS << "@"; 1226 VisitStringLiteral(Node->getString()); 1227} 1228 1229void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 1230 OS << "@encode(" << Node->getEncodedType().getAsString() << ')'; 1231} 1232 1233void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 1234 OS << "@selector(" << Node->getSelector().getAsString() << ')'; 1235} 1236 1237void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 1238 OS << "@protocol(" << Node->getProtocol()->getNameAsString() << ')'; 1239} 1240 1241void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 1242 OS << "["; 1243 Expr *receiver = Mess->getReceiver(); 1244 if (receiver) PrintExpr(receiver); 1245 else OS << Mess->getClassName()->getName(); 1246 OS << ' '; 1247 Selector selector = Mess->getSelector(); 1248 if (selector.isUnarySelector()) { 1249 OS << selector.getIdentifierInfoForSlot(0)->getName(); 1250 } else { 1251 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 1252 if (i < selector.getNumArgs()) { 1253 if (i > 0) OS << ' '; 1254 if (selector.getIdentifierInfoForSlot(i)) 1255 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 1256 else 1257 OS << ":"; 1258 } 1259 else OS << ", "; // Handle variadic methods. 1260 1261 PrintExpr(Mess->getArg(i)); 1262 } 1263 } 1264 OS << "]"; 1265} 1266 1267void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) { 1268 OS << "super"; 1269} 1270 1271void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 1272 BlockDecl *BD = Node->getBlockDecl(); 1273 OS << "^"; 1274 1275 const FunctionType *AFT = Node->getFunctionType(); 1276 1277 if (isa<FunctionNoProtoType>(AFT)) { 1278 OS << "()"; 1279 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 1280 OS << '('; 1281 std::string ParamStr; 1282 for (BlockDecl::param_iterator AI = BD->param_begin(), 1283 E = BD->param_end(); AI != E; ++AI) { 1284 if (AI != BD->param_begin()) OS << ", "; 1285 ParamStr = (*AI)->getNameAsString(); 1286 (*AI)->getType().getAsStringInternal(ParamStr, Policy); 1287 OS << ParamStr; 1288 } 1289 1290 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 1291 if (FT->isVariadic()) { 1292 if (!BD->param_empty()) OS << ", "; 1293 OS << "..."; 1294 } 1295 OS << ')'; 1296 } 1297} 1298 1299void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) { 1300 OS << Node->getDecl()->getNameAsString(); 1301} 1302//===----------------------------------------------------------------------===// 1303// Stmt method implementations 1304//===----------------------------------------------------------------------===// 1305 1306void Stmt::dumpPretty(ASTContext& Context) const { 1307 printPretty(llvm::errs(), Context, 0, 1308 PrintingPolicy(Context.getLangOptions())); 1309} 1310 1311void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context, 1312 PrinterHelper* Helper, 1313 const PrintingPolicy &Policy, 1314 unsigned Indentation) const { 1315 if (this == 0) { 1316 OS << "<NULL>"; 1317 return; 1318 } 1319 1320 if (Policy.Dump && &Context) { 1321 dump(Context.getSourceManager()); 1322 return; 1323 } 1324 1325 StmtPrinter P(OS, Context, Helper, Policy, Indentation); 1326 P.Visit(const_cast<Stmt*>(this)); 1327} 1328 1329//===----------------------------------------------------------------------===// 1330// PrinterHelper 1331//===----------------------------------------------------------------------===// 1332 1333// Implement virtual destructor. 1334PrinterHelper::~PrinterHelper() {} 1335