StmtPrinter.cpp revision 207619
1193326Sed//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which 11193326Sed// pretty print the AST back out to C code. 12193326Sed// 13193326Sed//===----------------------------------------------------------------------===// 14193326Sed 15193326Sed#include "clang/AST/StmtVisitor.h" 16193326Sed#include "clang/AST/DeclCXX.h" 17193326Sed#include "clang/AST/DeclObjC.h" 18193326Sed#include "clang/AST/PrettyPrinter.h" 19193326Sed#include "llvm/Support/Format.h" 20207619Srdivacky#include "clang/AST/Expr.h" 21193326Sedusing namespace clang; 22193326Sed 23193326Sed//===----------------------------------------------------------------------===// 24193326Sed// StmtPrinter Visitor 25193326Sed//===----------------------------------------------------------------------===// 26193326Sed 27193326Sednamespace { 28199990Srdivacky class StmtPrinter : public StmtVisitor<StmtPrinter> { 29193326Sed llvm::raw_ostream &OS; 30193326Sed ASTContext &Context; 31193326Sed unsigned IndentLevel; 32193326Sed clang::PrinterHelper* Helper; 33193326Sed PrintingPolicy Policy; 34193326Sed 35193326Sed public: 36198092Srdivacky StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper, 37195341Sed const PrintingPolicy &Policy, 38193326Sed unsigned Indentation = 0) 39193326Sed : OS(os), Context(C), IndentLevel(Indentation), Helper(helper), 40193326Sed Policy(Policy) {} 41198092Srdivacky 42193326Sed void PrintStmt(Stmt *S) { 43193326Sed PrintStmt(S, Policy.Indentation); 44193326Sed } 45193326Sed 46193326Sed void PrintStmt(Stmt *S, int SubIndent) { 47193326Sed IndentLevel += SubIndent; 48193326Sed if (S && isa<Expr>(S)) { 49193326Sed // If this is an expr used in a stmt context, indent and newline it. 50193326Sed Indent(); 51193326Sed Visit(S); 52193326Sed OS << ";\n"; 53193326Sed } else if (S) { 54193326Sed Visit(S); 55193326Sed } else { 56193326Sed Indent() << "<<<NULL STATEMENT>>>\n"; 57193326Sed } 58193326Sed IndentLevel -= SubIndent; 59193326Sed } 60193326Sed 61193326Sed void PrintRawCompoundStmt(CompoundStmt *S); 62193326Sed void PrintRawDecl(Decl *D); 63193326Sed void PrintRawDeclStmt(DeclStmt *S); 64193326Sed void PrintRawIfStmt(IfStmt *If); 65193326Sed void PrintRawCXXCatchStmt(CXXCatchStmt *Catch); 66198092Srdivacky 67193326Sed void PrintExpr(Expr *E) { 68193326Sed if (E) 69193326Sed Visit(E); 70193326Sed else 71193326Sed OS << "<null expr>"; 72193326Sed } 73198092Srdivacky 74193326Sed llvm::raw_ostream &Indent(int Delta = 0) { 75193326Sed for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 76193326Sed OS << " "; 77193326Sed return OS; 78193326Sed } 79198092Srdivacky 80193326Sed bool PrintOffsetOfDesignator(Expr *E); 81193326Sed void VisitUnaryOffsetOf(UnaryOperator *Node); 82198092Srdivacky 83198092Srdivacky void Visit(Stmt* S) { 84193326Sed if (Helper && Helper->handledStmt(S,OS)) 85193326Sed return; 86193326Sed else StmtVisitor<StmtPrinter>::Visit(S); 87193326Sed } 88198092Srdivacky 89193326Sed void VisitStmt(Stmt *Node); 90193326Sed#define STMT(CLASS, PARENT) \ 91193326Sed void Visit##CLASS(CLASS *Node); 92193326Sed#include "clang/AST/StmtNodes.def" 93193326Sed }; 94193326Sed} 95193326Sed 96193326Sed//===----------------------------------------------------------------------===// 97193326Sed// Stmt printing methods. 98193326Sed//===----------------------------------------------------------------------===// 99193326Sed 100193326Sedvoid StmtPrinter::VisitStmt(Stmt *Node) { 101193326Sed Indent() << "<<unknown stmt type>>\n"; 102193326Sed} 103193326Sed 104193326Sed/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 105193326Sed/// with no newline after the }. 106193326Sedvoid StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 107193326Sed OS << "{\n"; 108193326Sed for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end(); 109193326Sed I != E; ++I) 110193326Sed PrintStmt(*I); 111198092Srdivacky 112193326Sed Indent() << "}"; 113193326Sed} 114193326Sed 115193326Sedvoid StmtPrinter::PrintRawDecl(Decl *D) { 116195341Sed D->print(OS, Policy, IndentLevel); 117193326Sed} 118193326Sed 119193326Sedvoid StmtPrinter::PrintRawDeclStmt(DeclStmt *S) { 120193326Sed DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end(); 121193326Sed llvm::SmallVector<Decl*, 2> Decls; 122198092Srdivacky for ( ; Begin != End; ++Begin) 123193326Sed Decls.push_back(*Begin); 124193326Sed 125195341Sed Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel); 126193326Sed} 127193326Sed 128193326Sedvoid StmtPrinter::VisitNullStmt(NullStmt *Node) { 129193326Sed Indent() << ";\n"; 130193326Sed} 131193326Sed 132193326Sedvoid StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 133193326Sed Indent(); 134193326Sed PrintRawDeclStmt(Node); 135193326Sed OS << ";\n"; 136193326Sed} 137193326Sed 138193326Sedvoid StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 139193326Sed Indent(); 140193326Sed PrintRawCompoundStmt(Node); 141193326Sed OS << "\n"; 142193326Sed} 143193326Sed 144193326Sedvoid StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 145193326Sed Indent(-1) << "case "; 146193326Sed PrintExpr(Node->getLHS()); 147193326Sed if (Node->getRHS()) { 148193326Sed OS << " ... "; 149193326Sed PrintExpr(Node->getRHS()); 150193326Sed } 151193326Sed OS << ":\n"; 152198092Srdivacky 153193326Sed PrintStmt(Node->getSubStmt(), 0); 154193326Sed} 155193326Sed 156193326Sedvoid StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 157193326Sed Indent(-1) << "default:\n"; 158193326Sed PrintStmt(Node->getSubStmt(), 0); 159193326Sed} 160193326Sed 161193326Sedvoid StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 162193326Sed Indent(-1) << Node->getName() << ":\n"; 163193326Sed PrintStmt(Node->getSubStmt(), 0); 164193326Sed} 165193326Sed 166193326Sedvoid StmtPrinter::PrintRawIfStmt(IfStmt *If) { 167193326Sed OS << "if ("; 168193326Sed PrintExpr(If->getCond()); 169193326Sed OS << ')'; 170198092Srdivacky 171193326Sed if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) { 172193326Sed OS << ' '; 173193326Sed PrintRawCompoundStmt(CS); 174193326Sed OS << (If->getElse() ? ' ' : '\n'); 175193326Sed } else { 176193326Sed OS << '\n'; 177193326Sed PrintStmt(If->getThen()); 178193326Sed if (If->getElse()) Indent(); 179193326Sed } 180198092Srdivacky 181193326Sed if (Stmt *Else = If->getElse()) { 182193326Sed OS << "else"; 183198092Srdivacky 184193326Sed if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) { 185193326Sed OS << ' '; 186193326Sed PrintRawCompoundStmt(CS); 187193326Sed OS << '\n'; 188193326Sed } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) { 189193326Sed OS << ' '; 190193326Sed PrintRawIfStmt(ElseIf); 191193326Sed } else { 192193326Sed OS << '\n'; 193193326Sed PrintStmt(If->getElse()); 194193326Sed } 195193326Sed } 196193326Sed} 197193326Sed 198193326Sedvoid StmtPrinter::VisitIfStmt(IfStmt *If) { 199193326Sed Indent(); 200193326Sed PrintRawIfStmt(If); 201193326Sed} 202193326Sed 203193326Sedvoid StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 204193326Sed Indent() << "switch ("; 205193326Sed PrintExpr(Node->getCond()); 206193326Sed OS << ")"; 207198092Srdivacky 208193326Sed // Pretty print compoundstmt bodies (very common). 209193326Sed if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 210193326Sed OS << " "; 211193326Sed PrintRawCompoundStmt(CS); 212193326Sed OS << "\n"; 213193326Sed } else { 214193326Sed OS << "\n"; 215193326Sed PrintStmt(Node->getBody()); 216193326Sed } 217193326Sed} 218193326Sed 219193326Sedvoid StmtPrinter::VisitSwitchCase(SwitchCase*) { 220193326Sed assert(0 && "SwitchCase is an abstract class"); 221193326Sed} 222193326Sed 223193326Sedvoid StmtPrinter::VisitWhileStmt(WhileStmt *Node) { 224193326Sed Indent() << "while ("; 225193326Sed PrintExpr(Node->getCond()); 226193326Sed OS << ")\n"; 227193326Sed PrintStmt(Node->getBody()); 228193326Sed} 229193326Sed 230193326Sedvoid StmtPrinter::VisitDoStmt(DoStmt *Node) { 231193326Sed Indent() << "do "; 232193326Sed if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 233193326Sed PrintRawCompoundStmt(CS); 234193326Sed OS << " "; 235193326Sed } else { 236193326Sed OS << "\n"; 237193326Sed PrintStmt(Node->getBody()); 238193326Sed Indent(); 239193326Sed } 240198092Srdivacky 241193326Sed OS << "while ("; 242193326Sed PrintExpr(Node->getCond()); 243193326Sed OS << ");\n"; 244193326Sed} 245193326Sed 246193326Sedvoid StmtPrinter::VisitForStmt(ForStmt *Node) { 247193326Sed Indent() << "for ("; 248193326Sed if (Node->getInit()) { 249193326Sed if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit())) 250193326Sed PrintRawDeclStmt(DS); 251193326Sed else 252193326Sed PrintExpr(cast<Expr>(Node->getInit())); 253193326Sed } 254193326Sed OS << ";"; 255193326Sed if (Node->getCond()) { 256193326Sed OS << " "; 257193326Sed PrintExpr(Node->getCond()); 258193326Sed } 259193326Sed OS << ";"; 260193326Sed if (Node->getInc()) { 261193326Sed OS << " "; 262193326Sed PrintExpr(Node->getInc()); 263193326Sed } 264193326Sed OS << ") "; 265198092Srdivacky 266193326Sed if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 267193326Sed PrintRawCompoundStmt(CS); 268193326Sed OS << "\n"; 269193326Sed } else { 270193326Sed OS << "\n"; 271193326Sed PrintStmt(Node->getBody()); 272193326Sed } 273193326Sed} 274193326Sed 275193326Sedvoid StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) { 276193326Sed Indent() << "for ("; 277193326Sed if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement())) 278193326Sed PrintRawDeclStmt(DS); 279193326Sed else 280193326Sed PrintExpr(cast<Expr>(Node->getElement())); 281193326Sed OS << " in "; 282193326Sed PrintExpr(Node->getCollection()); 283193326Sed OS << ") "; 284198092Srdivacky 285193326Sed if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 286193326Sed PrintRawCompoundStmt(CS); 287193326Sed OS << "\n"; 288193326Sed } else { 289193326Sed OS << "\n"; 290193326Sed PrintStmt(Node->getBody()); 291193326Sed } 292193326Sed} 293193326Sed 294193326Sedvoid StmtPrinter::VisitGotoStmt(GotoStmt *Node) { 295193326Sed Indent() << "goto " << Node->getLabel()->getName() << ";\n"; 296193326Sed} 297193326Sed 298193326Sedvoid StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) { 299193326Sed Indent() << "goto *"; 300193326Sed PrintExpr(Node->getTarget()); 301193326Sed OS << ";\n"; 302193326Sed} 303193326Sed 304193326Sedvoid StmtPrinter::VisitContinueStmt(ContinueStmt *Node) { 305193326Sed Indent() << "continue;\n"; 306193326Sed} 307193326Sed 308193326Sedvoid StmtPrinter::VisitBreakStmt(BreakStmt *Node) { 309193326Sed Indent() << "break;\n"; 310193326Sed} 311193326Sed 312193326Sed 313193326Sedvoid StmtPrinter::VisitReturnStmt(ReturnStmt *Node) { 314193326Sed Indent() << "return"; 315193326Sed if (Node->getRetValue()) { 316193326Sed OS << " "; 317193326Sed PrintExpr(Node->getRetValue()); 318193326Sed } 319193326Sed OS << ";\n"; 320193326Sed} 321193326Sed 322193326Sed 323193326Sedvoid StmtPrinter::VisitAsmStmt(AsmStmt *Node) { 324193326Sed Indent() << "asm "; 325198092Srdivacky 326193326Sed if (Node->isVolatile()) 327193326Sed OS << "volatile "; 328198092Srdivacky 329193326Sed OS << "("; 330193326Sed VisitStringLiteral(Node->getAsmString()); 331198092Srdivacky 332193326Sed // Outputs 333193326Sed if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 || 334193326Sed Node->getNumClobbers() != 0) 335193326Sed OS << " : "; 336198092Srdivacky 337193326Sed for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) { 338193326Sed if (i != 0) 339193326Sed OS << ", "; 340198092Srdivacky 341193326Sed if (!Node->getOutputName(i).empty()) { 342193326Sed OS << '['; 343193326Sed OS << Node->getOutputName(i); 344193326Sed OS << "] "; 345193326Sed } 346198092Srdivacky 347193326Sed VisitStringLiteral(Node->getOutputConstraintLiteral(i)); 348193326Sed OS << " "; 349193326Sed Visit(Node->getOutputExpr(i)); 350193326Sed } 351198092Srdivacky 352193326Sed // Inputs 353193326Sed if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0) 354193326Sed OS << " : "; 355198092Srdivacky 356193326Sed for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) { 357193326Sed if (i != 0) 358193326Sed OS << ", "; 359198092Srdivacky 360193326Sed if (!Node->getInputName(i).empty()) { 361193326Sed OS << '['; 362193326Sed OS << Node->getInputName(i); 363193326Sed OS << "] "; 364193326Sed } 365198092Srdivacky 366193326Sed VisitStringLiteral(Node->getInputConstraintLiteral(i)); 367193326Sed OS << " "; 368193326Sed Visit(Node->getInputExpr(i)); 369193326Sed } 370198092Srdivacky 371193326Sed // Clobbers 372193326Sed if (Node->getNumClobbers() != 0) 373193326Sed OS << " : "; 374198092Srdivacky 375193326Sed for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) { 376193326Sed if (i != 0) 377193326Sed OS << ", "; 378198092Srdivacky 379193326Sed VisitStringLiteral(Node->getClobber(i)); 380193326Sed } 381198092Srdivacky 382193326Sed OS << ");\n"; 383193326Sed} 384193326Sed 385193326Sedvoid StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) { 386193326Sed Indent() << "@try"; 387193326Sed if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) { 388193326Sed PrintRawCompoundStmt(TS); 389193326Sed OS << "\n"; 390193326Sed } 391198092Srdivacky 392207619Srdivacky for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) { 393207619Srdivacky ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I); 394193326Sed Indent() << "@catch("; 395193326Sed if (catchStmt->getCatchParamDecl()) { 396193326Sed if (Decl *DS = catchStmt->getCatchParamDecl()) 397193326Sed PrintRawDecl(DS); 398193326Sed } 399193326Sed OS << ")"; 400198092Srdivacky if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) { 401198092Srdivacky PrintRawCompoundStmt(CS); 402198092Srdivacky OS << "\n"; 403198092Srdivacky } 404193326Sed } 405198092Srdivacky 406198092Srdivacky if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>( 407198092Srdivacky Node->getFinallyStmt())) { 408193326Sed Indent() << "@finally"; 409193326Sed PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody())); 410193326Sed OS << "\n"; 411198092Srdivacky } 412193326Sed} 413193326Sed 414193326Sedvoid StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) { 415193326Sed} 416193326Sed 417193326Sedvoid StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) { 418193326Sed Indent() << "@catch (...) { /* todo */ } \n"; 419193326Sed} 420193326Sed 421193326Sedvoid StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) { 422193326Sed Indent() << "@throw"; 423193326Sed if (Node->getThrowExpr()) { 424193326Sed OS << " "; 425193326Sed PrintExpr(Node->getThrowExpr()); 426193326Sed } 427193326Sed OS << ";\n"; 428193326Sed} 429193326Sed 430193326Sedvoid StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) { 431193326Sed Indent() << "@synchronized ("; 432193326Sed PrintExpr(Node->getSynchExpr()); 433193326Sed OS << ")"; 434193326Sed PrintRawCompoundStmt(Node->getSynchBody()); 435193326Sed OS << "\n"; 436193326Sed} 437193326Sed 438193326Sedvoid StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) { 439193326Sed OS << "catch ("; 440193326Sed if (Decl *ExDecl = Node->getExceptionDecl()) 441193326Sed PrintRawDecl(ExDecl); 442193326Sed else 443193326Sed OS << "..."; 444193326Sed OS << ") "; 445193326Sed PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock())); 446193326Sed} 447193326Sed 448193326Sedvoid StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) { 449193326Sed Indent(); 450193326Sed PrintRawCXXCatchStmt(Node); 451193326Sed OS << "\n"; 452193326Sed} 453193326Sed 454193326Sedvoid StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) { 455193326Sed Indent() << "try "; 456193326Sed PrintRawCompoundStmt(Node->getTryBlock()); 457198092Srdivacky for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) { 458193326Sed OS << " "; 459193326Sed PrintRawCXXCatchStmt(Node->getHandler(i)); 460193326Sed } 461193326Sed OS << "\n"; 462193326Sed} 463193326Sed 464193326Sed//===----------------------------------------------------------------------===// 465193326Sed// Expr printing methods. 466193326Sed//===----------------------------------------------------------------------===// 467193326Sed 468193326Sedvoid StmtPrinter::VisitExpr(Expr *Node) { 469193326Sed OS << "<<unknown expr type>>"; 470193326Sed} 471193326Sed 472193326Sedvoid StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { 473198893Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 474198893Srdivacky Qualifier->print(OS, Policy); 475207619Srdivacky OS << Node->getDecl(); 476198893Srdivacky if (Node->hasExplicitTemplateArgumentList()) 477198893Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 478198893Srdivacky Node->getTemplateArgs(), 479198893Srdivacky Node->getNumTemplateArgs(), 480198893Srdivacky Policy); 481193326Sed} 482193326Sed 483199990Srdivackyvoid StmtPrinter::VisitDependentScopeDeclRefExpr( 484199990Srdivacky DependentScopeDeclRefExpr *Node) { 485193326Sed Node->getQualifier()->print(OS, Policy); 486193326Sed OS << Node->getDeclName().getAsString(); 487199990Srdivacky if (Node->hasExplicitTemplateArgs()) 488199990Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 489199990Srdivacky Node->getTemplateArgs(), 490199990Srdivacky Node->getNumTemplateArgs(), 491199990Srdivacky Policy); 492193326Sed} 493193326Sed 494199990Srdivackyvoid StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 495195341Sed if (Node->getQualifier()) 496195341Sed Node->getQualifier()->print(OS, Policy); 497199990Srdivacky OS << Node->getName().getAsString(); 498199990Srdivacky if (Node->hasExplicitTemplateArgs()) 499199990Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 500199990Srdivacky Node->getTemplateArgs(), 501195341Sed Node->getNumTemplateArgs(), 502199990Srdivacky Policy); 503195341Sed} 504195341Sed 505193326Sedvoid StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 506193326Sed if (Node->getBase()) { 507193326Sed PrintExpr(Node->getBase()); 508193326Sed OS << (Node->isArrow() ? "->" : "."); 509193326Sed } 510207619Srdivacky OS << Node->getDecl(); 511193326Sed} 512193326Sed 513193326Sedvoid StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 514193326Sed if (Node->getBase()) { 515193326Sed PrintExpr(Node->getBase()); 516193326Sed OS << "."; 517193326Sed } 518193326Sed OS << Node->getProperty()->getNameAsCString(); 519193326Sed} 520193326Sed 521198092Srdivackyvoid StmtPrinter::VisitObjCImplicitSetterGetterRefExpr( 522198092Srdivacky ObjCImplicitSetterGetterRefExpr *Node) { 523193326Sed if (Node->getBase()) { 524193326Sed PrintExpr(Node->getBase()); 525193326Sed OS << "."; 526193326Sed } 527198092Srdivacky if (Node->getGetterMethod()) 528207619Srdivacky OS << Node->getGetterMethod(); 529198092Srdivacky 530193326Sed} 531193326Sed 532193326Sedvoid StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 533193326Sed switch (Node->getIdentType()) { 534193326Sed default: 535193326Sed assert(0 && "unknown case"); 536193326Sed case PredefinedExpr::Func: 537193326Sed OS << "__func__"; 538193326Sed break; 539193326Sed case PredefinedExpr::Function: 540193326Sed OS << "__FUNCTION__"; 541193326Sed break; 542193326Sed case PredefinedExpr::PrettyFunction: 543193326Sed OS << "__PRETTY_FUNCTION__"; 544193326Sed break; 545193326Sed } 546193326Sed} 547193326Sed 548193326Sedvoid StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 549193326Sed unsigned value = Node->getValue(); 550193326Sed if (Node->isWide()) 551193326Sed OS << "L"; 552193326Sed switch (value) { 553193326Sed case '\\': 554193326Sed OS << "'\\\\'"; 555193326Sed break; 556193326Sed case '\'': 557193326Sed OS << "'\\''"; 558193326Sed break; 559193326Sed case '\a': 560193326Sed // TODO: K&R: the meaning of '\\a' is different in traditional C 561193326Sed OS << "'\\a'"; 562193326Sed break; 563193326Sed case '\b': 564193326Sed OS << "'\\b'"; 565193326Sed break; 566193326Sed // Nonstandard escape sequence. 567193326Sed /*case '\e': 568193326Sed OS << "'\\e'"; 569193326Sed break;*/ 570193326Sed case '\f': 571193326Sed OS << "'\\f'"; 572193326Sed break; 573193326Sed case '\n': 574193326Sed OS << "'\\n'"; 575193326Sed break; 576193326Sed case '\r': 577193326Sed OS << "'\\r'"; 578193326Sed break; 579193326Sed case '\t': 580193326Sed OS << "'\\t'"; 581193326Sed break; 582193326Sed case '\v': 583193326Sed OS << "'\\v'"; 584193326Sed break; 585193326Sed default: 586193326Sed if (value < 256 && isprint(value)) { 587193326Sed OS << "'" << (char)value << "'"; 588193326Sed } else if (value < 256) { 589193326Sed OS << "'\\x" << llvm::format("%x", value) << "'"; 590193326Sed } else { 591193326Sed // FIXME what to really do here? 592193326Sed OS << value; 593193326Sed } 594193326Sed } 595193326Sed} 596193326Sed 597193326Sedvoid StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 598193326Sed bool isSigned = Node->getType()->isSignedIntegerType(); 599193326Sed OS << Node->getValue().toString(10, isSigned); 600198092Srdivacky 601193326Sed // Emit suffixes. Integer literals are always a builtin integer type. 602198092Srdivacky switch (Node->getType()->getAs<BuiltinType>()->getKind()) { 603193326Sed default: assert(0 && "Unexpected type for integer literal!"); 604193326Sed case BuiltinType::Int: break; // no suffix. 605193326Sed case BuiltinType::UInt: OS << 'U'; break; 606193326Sed case BuiltinType::Long: OS << 'L'; break; 607193326Sed case BuiltinType::ULong: OS << "UL"; break; 608193326Sed case BuiltinType::LongLong: OS << "LL"; break; 609193326Sed case BuiltinType::ULongLong: OS << "ULL"; break; 610193326Sed } 611193326Sed} 612193326Sedvoid StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 613193326Sed // FIXME: print value more precisely. 614193326Sed OS << Node->getValueAsApproximateDouble(); 615193326Sed} 616193326Sed 617193326Sedvoid StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 618193326Sed PrintExpr(Node->getSubExpr()); 619193326Sed OS << "i"; 620193326Sed} 621193326Sed 622193326Sedvoid StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 623193326Sed if (Str->isWide()) OS << 'L'; 624193326Sed OS << '"'; 625193326Sed 626193326Sed // FIXME: this doesn't print wstrings right. 627193326Sed for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) { 628193326Sed unsigned char Char = Str->getStrData()[i]; 629198092Srdivacky 630193326Sed switch (Char) { 631193326Sed default: 632193326Sed if (isprint(Char)) 633193326Sed OS << (char)Char; 634193326Sed else // Output anything hard as an octal escape. 635193326Sed OS << '\\' 636193326Sed << (char)('0'+ ((Char >> 6) & 7)) 637193326Sed << (char)('0'+ ((Char >> 3) & 7)) 638193326Sed << (char)('0'+ ((Char >> 0) & 7)); 639193326Sed break; 640193326Sed // Handle some common non-printable cases to make dumps prettier. 641193326Sed case '\\': OS << "\\\\"; break; 642193326Sed case '"': OS << "\\\""; break; 643193326Sed case '\n': OS << "\\n"; break; 644193326Sed case '\t': OS << "\\t"; break; 645193326Sed case '\a': OS << "\\a"; break; 646193326Sed case '\b': OS << "\\b"; break; 647193326Sed } 648193326Sed } 649193326Sed OS << '"'; 650193326Sed} 651193326Sedvoid StmtPrinter::VisitParenExpr(ParenExpr *Node) { 652193326Sed OS << "("; 653193326Sed PrintExpr(Node->getSubExpr()); 654193326Sed OS << ")"; 655193326Sed} 656193326Sedvoid StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 657193326Sed if (!Node->isPostfix()) { 658193326Sed OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 659198092Srdivacky 660194613Sed // Print a space if this is an "identifier operator" like __real, or if 661194613Sed // it might be concatenated incorrectly like '+'. 662193326Sed switch (Node->getOpcode()) { 663193326Sed default: break; 664193326Sed case UnaryOperator::Real: 665193326Sed case UnaryOperator::Imag: 666193326Sed case UnaryOperator::Extension: 667193326Sed OS << ' '; 668193326Sed break; 669194613Sed case UnaryOperator::Plus: 670194613Sed case UnaryOperator::Minus: 671194613Sed if (isa<UnaryOperator>(Node->getSubExpr())) 672194613Sed OS << ' '; 673194613Sed break; 674193326Sed } 675193326Sed } 676193326Sed PrintExpr(Node->getSubExpr()); 677198092Srdivacky 678193326Sed if (Node->isPostfix()) 679193326Sed OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 680193326Sed} 681193326Sed 682193326Sedbool StmtPrinter::PrintOffsetOfDesignator(Expr *E) { 683193326Sed if (isa<UnaryOperator>(E)) { 684193326Sed // Base case, print the type and comma. 685193326Sed OS << E->getType().getAsString() << ", "; 686193326Sed return true; 687193326Sed } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) { 688193326Sed PrintOffsetOfDesignator(ASE->getLHS()); 689193326Sed OS << "["; 690193326Sed PrintExpr(ASE->getRHS()); 691193326Sed OS << "]"; 692193326Sed return false; 693193326Sed } else { 694193326Sed MemberExpr *ME = cast<MemberExpr>(E); 695193326Sed bool IsFirst = PrintOffsetOfDesignator(ME->getBase()); 696207619Srdivacky OS << (IsFirst ? "" : ".") << ME->getMemberDecl(); 697193326Sed return false; 698193326Sed } 699193326Sed} 700193326Sed 701193326Sedvoid StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) { 702193326Sed OS << "__builtin_offsetof("; 703193326Sed PrintOffsetOfDesignator(Node->getSubExpr()); 704193326Sed OS << ")"; 705193326Sed} 706193326Sed 707207619Srdivackyvoid StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) { 708207619Srdivacky OS << "__builtin_offsetof("; 709207619Srdivacky OS << Node->getTypeSourceInfo()->getType().getAsString() << ", "; 710207619Srdivacky bool PrintedSomething = false; 711207619Srdivacky for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) { 712207619Srdivacky OffsetOfExpr::OffsetOfNode ON = Node->getComponent(i); 713207619Srdivacky if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Array) { 714207619Srdivacky // Array node 715207619Srdivacky OS << "["; 716207619Srdivacky PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex())); 717207619Srdivacky OS << "]"; 718207619Srdivacky PrintedSomething = true; 719207619Srdivacky continue; 720207619Srdivacky } 721207619Srdivacky 722207619Srdivacky // Skip implicit base indirections. 723207619Srdivacky if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Base) 724207619Srdivacky continue; 725207619Srdivacky 726207619Srdivacky // Field or identifier node. 727207619Srdivacky IdentifierInfo *Id = ON.getFieldName(); 728207619Srdivacky if (!Id) 729207619Srdivacky continue; 730207619Srdivacky 731207619Srdivacky if (PrintedSomething) 732207619Srdivacky OS << "."; 733207619Srdivacky else 734207619Srdivacky PrintedSomething = true; 735207619Srdivacky OS << Id->getName(); 736207619Srdivacky } 737207619Srdivacky OS << ")"; 738207619Srdivacky} 739207619Srdivacky 740193326Sedvoid StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { 741193326Sed OS << (Node->isSizeOf() ? "sizeof" : "__alignof"); 742193326Sed if (Node->isArgumentType()) 743193326Sed OS << "(" << Node->getArgumentType().getAsString() << ")"; 744193326Sed else { 745193326Sed OS << " "; 746193326Sed PrintExpr(Node->getArgumentExpr()); 747193326Sed } 748193326Sed} 749193326Sedvoid StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 750193326Sed PrintExpr(Node->getLHS()); 751193326Sed OS << "["; 752193326Sed PrintExpr(Node->getRHS()); 753193326Sed OS << "]"; 754193326Sed} 755193326Sed 756193326Sedvoid StmtPrinter::VisitCallExpr(CallExpr *Call) { 757193326Sed PrintExpr(Call->getCallee()); 758193326Sed OS << "("; 759193326Sed for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 760193326Sed if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 761193326Sed // Don't print any defaulted arguments 762193326Sed break; 763193326Sed } 764193326Sed 765193326Sed if (i) OS << ", "; 766193326Sed PrintExpr(Call->getArg(i)); 767193326Sed } 768193326Sed OS << ")"; 769193326Sed} 770193326Sedvoid StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 771193326Sed // FIXME: Suppress printing implicit bases (like "this") 772193326Sed PrintExpr(Node->getBase()); 773202379Srdivacky if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl())) 774202379Srdivacky if (FD->isAnonymousStructOrUnion()) 775202379Srdivacky return; 776193326Sed OS << (Node->isArrow() ? "->" : "."); 777198092Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 778198092Srdivacky Qualifier->print(OS, Policy); 779198092Srdivacky 780207619Srdivacky OS << Node->getMemberDecl(); 781198092Srdivacky 782198092Srdivacky if (Node->hasExplicitTemplateArgumentList()) 783198092Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 784198092Srdivacky Node->getTemplateArgs(), 785198092Srdivacky Node->getNumTemplateArgs(), 786198092Srdivacky Policy); 787193326Sed} 788198092Srdivackyvoid StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) { 789198092Srdivacky PrintExpr(Node->getBase()); 790198092Srdivacky OS << (Node->isArrow() ? "->isa" : ".isa"); 791198092Srdivacky} 792198092Srdivacky 793193326Sedvoid StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 794193326Sed PrintExpr(Node->getBase()); 795193326Sed OS << "."; 796193326Sed OS << Node->getAccessor().getName(); 797193326Sed} 798193326Sedvoid StmtPrinter::VisitCastExpr(CastExpr *) { 799193326Sed assert(0 && "CastExpr is an abstract class"); 800193326Sed} 801193326Sedvoid StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) { 802193326Sed assert(0 && "ExplicitCastExpr is an abstract class"); 803193326Sed} 804193326Sedvoid StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) { 805193326Sed OS << "(" << Node->getType().getAsString() << ")"; 806193326Sed PrintExpr(Node->getSubExpr()); 807193326Sed} 808193326Sedvoid StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 809193326Sed OS << "(" << Node->getType().getAsString() << ")"; 810193326Sed PrintExpr(Node->getInitializer()); 811193326Sed} 812193326Sedvoid StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 813193326Sed // No need to print anything, simply forward to the sub expression. 814193326Sed PrintExpr(Node->getSubExpr()); 815193326Sed} 816193326Sedvoid StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 817193326Sed PrintExpr(Node->getLHS()); 818193326Sed OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 819193326Sed PrintExpr(Node->getRHS()); 820193326Sed} 821193326Sedvoid StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 822193326Sed PrintExpr(Node->getLHS()); 823193326Sed OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 824193326Sed PrintExpr(Node->getRHS()); 825193326Sed} 826193326Sedvoid StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 827193326Sed PrintExpr(Node->getCond()); 828198092Srdivacky 829193326Sed if (Node->getLHS()) { 830193326Sed OS << " ? "; 831193326Sed PrintExpr(Node->getLHS()); 832193326Sed OS << " : "; 833193326Sed } 834193326Sed else { // Handle GCC extension where LHS can be NULL. 835193326Sed OS << " ?: "; 836193326Sed } 837198092Srdivacky 838193326Sed PrintExpr(Node->getRHS()); 839193326Sed} 840193326Sed 841193326Sed// GNU extensions. 842193326Sed 843193326Sedvoid StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 844193326Sed OS << "&&" << Node->getLabel()->getName(); 845193326Sed} 846193326Sed 847193326Sedvoid StmtPrinter::VisitStmtExpr(StmtExpr *E) { 848193326Sed OS << "("; 849193326Sed PrintRawCompoundStmt(E->getSubStmt()); 850193326Sed OS << ")"; 851193326Sed} 852193326Sed 853193326Sedvoid StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) { 854193326Sed OS << "__builtin_types_compatible_p("; 855193326Sed OS << Node->getArgType1().getAsString() << ","; 856193326Sed OS << Node->getArgType2().getAsString() << ")"; 857193326Sed} 858193326Sed 859193326Sedvoid StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 860193326Sed OS << "__builtin_choose_expr("; 861193326Sed PrintExpr(Node->getCond()); 862193326Sed OS << ", "; 863193326Sed PrintExpr(Node->getLHS()); 864193326Sed OS << ", "; 865193326Sed PrintExpr(Node->getRHS()); 866193326Sed OS << ")"; 867193326Sed} 868193326Sed 869193326Sedvoid StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 870193326Sed OS << "__null"; 871193326Sed} 872193326Sed 873193326Sedvoid StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 874193326Sed OS << "__builtin_shufflevector("; 875193326Sed for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 876193326Sed if (i) OS << ", "; 877193326Sed PrintExpr(Node->getExpr(i)); 878193326Sed } 879193326Sed OS << ")"; 880193326Sed} 881193326Sed 882193326Sedvoid StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 883193326Sed if (Node->getSyntacticForm()) { 884193326Sed Visit(Node->getSyntacticForm()); 885193326Sed return; 886193326Sed } 887193326Sed 888193326Sed OS << "{ "; 889193326Sed for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 890193326Sed if (i) OS << ", "; 891193326Sed if (Node->getInit(i)) 892193326Sed PrintExpr(Node->getInit(i)); 893193326Sed else 894193326Sed OS << "0"; 895193326Sed } 896193326Sed OS << " }"; 897193326Sed} 898193326Sed 899198092Srdivackyvoid StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { 900198092Srdivacky OS << "( "; 901198092Srdivacky for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) { 902198092Srdivacky if (i) OS << ", "; 903198092Srdivacky PrintExpr(Node->getExpr(i)); 904198092Srdivacky } 905198092Srdivacky OS << " )"; 906198092Srdivacky} 907198092Srdivacky 908193326Sedvoid StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { 909193326Sed for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(), 910193326Sed DEnd = Node->designators_end(); 911193326Sed D != DEnd; ++D) { 912193326Sed if (D->isFieldDesignator()) { 913193326Sed if (D->getDotLoc().isInvalid()) 914193326Sed OS << D->getFieldName()->getName() << ":"; 915193326Sed else 916193326Sed OS << "." << D->getFieldName()->getName(); 917193326Sed } else { 918193326Sed OS << "["; 919193326Sed if (D->isArrayDesignator()) { 920193326Sed PrintExpr(Node->getArrayIndex(*D)); 921193326Sed } else { 922193326Sed PrintExpr(Node->getArrayRangeStart(*D)); 923193326Sed OS << " ... "; 924198092Srdivacky PrintExpr(Node->getArrayRangeEnd(*D)); 925193326Sed } 926193326Sed OS << "]"; 927193326Sed } 928193326Sed } 929193326Sed 930193326Sed OS << " = "; 931193326Sed PrintExpr(Node->getInit()); 932193326Sed} 933193326Sed 934193326Sedvoid StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { 935195341Sed if (Policy.LangOpts.CPlusPlus) 936193326Sed OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()"; 937193326Sed else { 938193326Sed OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")"; 939193326Sed if (Node->getType()->isRecordType()) 940193326Sed OS << "{}"; 941193326Sed else 942193326Sed OS << 0; 943193326Sed } 944193326Sed} 945193326Sed 946193326Sedvoid StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 947193326Sed OS << "__builtin_va_arg("; 948193326Sed PrintExpr(Node->getSubExpr()); 949193326Sed OS << ", "; 950193326Sed OS << Node->getType().getAsString(); 951193326Sed OS << ")"; 952193326Sed} 953193326Sed 954193326Sed// C++ 955193326Sedvoid StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 956193326Sed const char *OpStrings[NUM_OVERLOADED_OPERATORS] = { 957193326Sed "", 958193326Sed#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 959193326Sed Spelling, 960193326Sed#include "clang/Basic/OperatorKinds.def" 961193326Sed }; 962193326Sed 963193326Sed OverloadedOperatorKind Kind = Node->getOperator(); 964193326Sed if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 965193326Sed if (Node->getNumArgs() == 1) { 966193326Sed OS << OpStrings[Kind] << ' '; 967193326Sed PrintExpr(Node->getArg(0)); 968193326Sed } else { 969193326Sed PrintExpr(Node->getArg(0)); 970193326Sed OS << ' ' << OpStrings[Kind]; 971193326Sed } 972193326Sed } else if (Kind == OO_Call) { 973193326Sed PrintExpr(Node->getArg(0)); 974193326Sed OS << '('; 975193326Sed for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 976193326Sed if (ArgIdx > 1) 977193326Sed OS << ", "; 978193326Sed if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 979193326Sed PrintExpr(Node->getArg(ArgIdx)); 980193326Sed } 981193326Sed OS << ')'; 982193326Sed } else if (Kind == OO_Subscript) { 983193326Sed PrintExpr(Node->getArg(0)); 984193326Sed OS << '['; 985193326Sed PrintExpr(Node->getArg(1)); 986193326Sed OS << ']'; 987193326Sed } else if (Node->getNumArgs() == 1) { 988193326Sed OS << OpStrings[Kind] << ' '; 989193326Sed PrintExpr(Node->getArg(0)); 990193326Sed } else if (Node->getNumArgs() == 2) { 991193326Sed PrintExpr(Node->getArg(0)); 992193326Sed OS << ' ' << OpStrings[Kind] << ' '; 993193326Sed PrintExpr(Node->getArg(1)); 994193326Sed } else { 995193326Sed assert(false && "unknown overloaded operator"); 996193326Sed } 997193326Sed} 998193326Sed 999193326Sedvoid StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 1000193326Sed VisitCallExpr(cast<CallExpr>(Node)); 1001193326Sed} 1002193326Sed 1003193326Sedvoid StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 1004193326Sed OS << Node->getCastName() << '<'; 1005193326Sed OS << Node->getTypeAsWritten().getAsString() << ">("; 1006193326Sed PrintExpr(Node->getSubExpr()); 1007193326Sed OS << ")"; 1008193326Sed} 1009193326Sed 1010193326Sedvoid StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 1011193326Sed VisitCXXNamedCastExpr(Node); 1012193326Sed} 1013193326Sed 1014193326Sedvoid StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 1015193326Sed VisitCXXNamedCastExpr(Node); 1016193326Sed} 1017193326Sed 1018193326Sedvoid StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 1019193326Sed VisitCXXNamedCastExpr(Node); 1020193326Sed} 1021193326Sed 1022193326Sedvoid StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 1023193326Sed VisitCXXNamedCastExpr(Node); 1024193326Sed} 1025193326Sed 1026193326Sedvoid StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 1027193326Sed OS << "typeid("; 1028193326Sed if (Node->isTypeOperand()) { 1029193326Sed OS << Node->getTypeOperand().getAsString(); 1030193326Sed } else { 1031193326Sed PrintExpr(Node->getExprOperand()); 1032193326Sed } 1033193326Sed OS << ")"; 1034193326Sed} 1035193326Sed 1036193326Sedvoid StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 1037193326Sed OS << (Node->getValue() ? "true" : "false"); 1038193326Sed} 1039193326Sed 1040193326Sedvoid StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 1041193326Sed OS << "nullptr"; 1042193326Sed} 1043193326Sed 1044193326Sedvoid StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 1045193326Sed OS << "this"; 1046193326Sed} 1047193326Sed 1048193326Sedvoid StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 1049193326Sed if (Node->getSubExpr() == 0) 1050193326Sed OS << "throw"; 1051193326Sed else { 1052193326Sed OS << "throw "; 1053193326Sed PrintExpr(Node->getSubExpr()); 1054193326Sed } 1055193326Sed} 1056193326Sed 1057193326Sedvoid StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 1058193326Sed // Nothing to print: we picked up the default argument 1059193326Sed} 1060193326Sed 1061193326Sedvoid StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 1062193326Sed OS << Node->getType().getAsString(); 1063193326Sed OS << "("; 1064193326Sed PrintExpr(Node->getSubExpr()); 1065193326Sed OS << ")"; 1066193326Sed} 1067193326Sed 1068193326Sedvoid StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 1069193326Sed PrintExpr(Node->getSubExpr()); 1070193326Sed} 1071193326Sed 1072203955Srdivackyvoid StmtPrinter::VisitCXXBindReferenceExpr(CXXBindReferenceExpr *Node) { 1073203955Srdivacky PrintExpr(Node->getSubExpr()); 1074203955Srdivacky} 1075203955Srdivacky 1076193326Sedvoid StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 1077193326Sed OS << Node->getType().getAsString(); 1078193326Sed OS << "("; 1079193326Sed for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 1080198092Srdivacky ArgEnd = Node->arg_end(); 1081193326Sed Arg != ArgEnd; ++Arg) { 1082193326Sed if (Arg != Node->arg_begin()) 1083193326Sed OS << ", "; 1084193326Sed PrintExpr(*Arg); 1085193326Sed } 1086193326Sed OS << ")"; 1087193326Sed} 1088193326Sed 1089193326Sedvoid StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) { 1090193326Sed OS << Node->getType().getAsString() << "()"; 1091193326Sed} 1092193326Sed 1093193326Sedvoid StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 1094193326Sed if (E->isGlobalNew()) 1095193326Sed OS << "::"; 1096193326Sed OS << "new "; 1097193326Sed unsigned NumPlace = E->getNumPlacementArgs(); 1098193326Sed if (NumPlace > 0) { 1099193326Sed OS << "("; 1100193326Sed PrintExpr(E->getPlacementArg(0)); 1101193326Sed for (unsigned i = 1; i < NumPlace; ++i) { 1102193326Sed OS << ", "; 1103193326Sed PrintExpr(E->getPlacementArg(i)); 1104193326Sed } 1105193326Sed OS << ") "; 1106193326Sed } 1107193326Sed if (E->isParenTypeId()) 1108193326Sed OS << "("; 1109193326Sed std::string TypeS; 1110193326Sed if (Expr *Size = E->getArraySize()) { 1111193326Sed llvm::raw_string_ostream s(TypeS); 1112193326Sed Size->printPretty(s, Context, Helper, Policy); 1113193326Sed s.flush(); 1114193326Sed TypeS = "[" + TypeS + "]"; 1115193326Sed } 1116193326Sed E->getAllocatedType().getAsStringInternal(TypeS, Policy); 1117193326Sed OS << TypeS; 1118193326Sed if (E->isParenTypeId()) 1119193326Sed OS << ")"; 1120193326Sed 1121193326Sed if (E->hasInitializer()) { 1122193326Sed OS << "("; 1123193326Sed unsigned NumCons = E->getNumConstructorArgs(); 1124193326Sed if (NumCons > 0) { 1125193326Sed PrintExpr(E->getConstructorArg(0)); 1126193326Sed for (unsigned i = 1; i < NumCons; ++i) { 1127193326Sed OS << ", "; 1128193326Sed PrintExpr(E->getConstructorArg(i)); 1129193326Sed } 1130193326Sed } 1131193326Sed OS << ")"; 1132193326Sed } 1133193326Sed} 1134193326Sed 1135193326Sedvoid StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 1136193326Sed if (E->isGlobalDelete()) 1137193326Sed OS << "::"; 1138193326Sed OS << "delete "; 1139193326Sed if (E->isArrayForm()) 1140193326Sed OS << "[] "; 1141193326Sed PrintExpr(E->getArgument()); 1142193326Sed} 1143193326Sed 1144198092Srdivackyvoid StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 1145198092Srdivacky PrintExpr(E->getBase()); 1146198092Srdivacky if (E->isArrow()) 1147198092Srdivacky OS << "->"; 1148198092Srdivacky else 1149198092Srdivacky OS << '.'; 1150198092Srdivacky if (E->getQualifier()) 1151198092Srdivacky E->getQualifier()->print(OS, Policy); 1152198092Srdivacky 1153198092Srdivacky std::string TypeS; 1154204643Srdivacky if (IdentifierInfo *II = E->getDestroyedTypeIdentifier()) 1155204643Srdivacky OS << II->getName(); 1156204643Srdivacky else 1157204643Srdivacky E->getDestroyedType().getAsStringInternal(TypeS, Policy); 1158198092Srdivacky OS << TypeS; 1159198092Srdivacky} 1160198092Srdivacky 1161193326Sedvoid StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 1162202379Srdivacky // FIXME. For now we just print a trivial constructor call expression, 1163202379Srdivacky // constructing its first argument object. 1164202379Srdivacky if (E->getNumArgs() == 1) { 1165202379Srdivacky CXXConstructorDecl *CD = E->getConstructor(); 1166202379Srdivacky if (CD->isTrivial()) 1167202379Srdivacky PrintExpr(E->getArg(0)); 1168202379Srdivacky } 1169193326Sed // Nothing to print. 1170193326Sed} 1171193326Sed 1172193326Sedvoid StmtPrinter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) { 1173193326Sed // Just forward to the sub expression. 1174193326Sed PrintExpr(E->getSubExpr()); 1175193326Sed} 1176193326Sed 1177198092Srdivackyvoid 1178193326SedStmtPrinter::VisitCXXUnresolvedConstructExpr( 1179193326Sed CXXUnresolvedConstructExpr *Node) { 1180193326Sed OS << Node->getTypeAsWritten().getAsString(); 1181193326Sed OS << "("; 1182193326Sed for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(), 1183198092Srdivacky ArgEnd = Node->arg_end(); 1184193326Sed Arg != ArgEnd; ++Arg) { 1185193326Sed if (Arg != Node->arg_begin()) 1186193326Sed OS << ", "; 1187193326Sed PrintExpr(*Arg); 1188193326Sed } 1189193326Sed OS << ")"; 1190193326Sed} 1191193326Sed 1192199990Srdivackyvoid StmtPrinter::VisitCXXDependentScopeMemberExpr( 1193199990Srdivacky CXXDependentScopeMemberExpr *Node) { 1194200583Srdivacky if (!Node->isImplicitAccess()) { 1195200583Srdivacky PrintExpr(Node->getBase()); 1196200583Srdivacky OS << (Node->isArrow() ? "->" : "."); 1197200583Srdivacky } 1198198092Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1199198092Srdivacky Qualifier->print(OS, Policy); 1200200583Srdivacky else if (Node->hasExplicitTemplateArgs()) 1201198092Srdivacky // FIXME: Track use of "template" keyword explicitly? 1202198092Srdivacky OS << "template "; 1203198092Srdivacky 1204193326Sed OS << Node->getMember().getAsString(); 1205198092Srdivacky 1206200583Srdivacky if (Node->hasExplicitTemplateArgs()) { 1207198092Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 1208198092Srdivacky Node->getTemplateArgs(), 1209198092Srdivacky Node->getNumTemplateArgs(), 1210198092Srdivacky Policy); 1211198092Srdivacky } 1212193326Sed} 1213193326Sed 1214199990Srdivackyvoid StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 1215200583Srdivacky if (!Node->isImplicitAccess()) { 1216200583Srdivacky PrintExpr(Node->getBase()); 1217200583Srdivacky OS << (Node->isArrow() ? "->" : "."); 1218200583Srdivacky } 1219199990Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1220199990Srdivacky Qualifier->print(OS, Policy); 1221199990Srdivacky 1222199990Srdivacky // FIXME: this might originally have been written with 'template' 1223199990Srdivacky 1224199990Srdivacky OS << Node->getMemberName().getAsString(); 1225199990Srdivacky 1226199990Srdivacky if (Node->hasExplicitTemplateArgs()) { 1227199990Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 1228199990Srdivacky Node->getTemplateArgs(), 1229199990Srdivacky Node->getNumTemplateArgs(), 1230199990Srdivacky Policy); 1231199990Srdivacky } 1232199990Srdivacky} 1233199990Srdivacky 1234193326Sedstatic const char *getTypeTraitName(UnaryTypeTrait UTT) { 1235193326Sed switch (UTT) { 1236193326Sed default: assert(false && "Unknown type trait"); 1237193326Sed case UTT_HasNothrowAssign: return "__has_nothrow_assign"; 1238193326Sed case UTT_HasNothrowCopy: return "__has_nothrow_copy"; 1239193326Sed case UTT_HasNothrowConstructor: return "__has_nothrow_constructor"; 1240193326Sed case UTT_HasTrivialAssign: return "__has_trivial_assign"; 1241193326Sed case UTT_HasTrivialCopy: return "__has_trivial_copy"; 1242193326Sed case UTT_HasTrivialConstructor: return "__has_trivial_constructor"; 1243193326Sed case UTT_HasTrivialDestructor: return "__has_trivial_destructor"; 1244193326Sed case UTT_HasVirtualDestructor: return "__has_virtual_destructor"; 1245193326Sed case UTT_IsAbstract: return "__is_abstract"; 1246193326Sed case UTT_IsClass: return "__is_class"; 1247193326Sed case UTT_IsEmpty: return "__is_empty"; 1248193326Sed case UTT_IsEnum: return "__is_enum"; 1249193326Sed case UTT_IsPOD: return "__is_pod"; 1250193326Sed case UTT_IsPolymorphic: return "__is_polymorphic"; 1251193326Sed case UTT_IsUnion: return "__is_union"; 1252193326Sed } 1253193326Sed} 1254193326Sed 1255193326Sedvoid StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { 1256193326Sed OS << getTypeTraitName(E->getTrait()) << "(" 1257193326Sed << E->getQueriedType().getAsString() << ")"; 1258193326Sed} 1259193326Sed 1260198092Srdivacky// Obj-C 1261193326Sed 1262193326Sedvoid StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 1263193326Sed OS << "@"; 1264193326Sed VisitStringLiteral(Node->getString()); 1265193326Sed} 1266193326Sed 1267193326Sedvoid StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 1268193326Sed OS << "@encode(" << Node->getEncodedType().getAsString() << ')'; 1269193326Sed} 1270193326Sed 1271193326Sedvoid StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 1272193326Sed OS << "@selector(" << Node->getSelector().getAsString() << ')'; 1273193326Sed} 1274193326Sed 1275193326Sedvoid StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 1276207619Srdivacky OS << "@protocol(" << Node->getProtocol() << ')'; 1277193326Sed} 1278193326Sed 1279193326Sedvoid StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 1280193326Sed OS << "["; 1281207619Srdivacky switch (Mess->getReceiverKind()) { 1282207619Srdivacky case ObjCMessageExpr::Instance: 1283207619Srdivacky PrintExpr(Mess->getInstanceReceiver()); 1284207619Srdivacky break; 1285207619Srdivacky 1286207619Srdivacky case ObjCMessageExpr::Class: 1287207619Srdivacky OS << Mess->getClassReceiver().getAsString(Policy); 1288207619Srdivacky break; 1289207619Srdivacky 1290207619Srdivacky case ObjCMessageExpr::SuperInstance: 1291207619Srdivacky case ObjCMessageExpr::SuperClass: 1292207619Srdivacky OS << "Super"; 1293207619Srdivacky break; 1294207619Srdivacky } 1295207619Srdivacky 1296193326Sed OS << ' '; 1297193326Sed Selector selector = Mess->getSelector(); 1298193326Sed if (selector.isUnarySelector()) { 1299193326Sed OS << selector.getIdentifierInfoForSlot(0)->getName(); 1300193326Sed } else { 1301193326Sed for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 1302193326Sed if (i < selector.getNumArgs()) { 1303193326Sed if (i > 0) OS << ' '; 1304193326Sed if (selector.getIdentifierInfoForSlot(i)) 1305193326Sed OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 1306193326Sed else 1307193326Sed OS << ":"; 1308193326Sed } 1309193326Sed else OS << ", "; // Handle variadic methods. 1310198092Srdivacky 1311193326Sed PrintExpr(Mess->getArg(i)); 1312193326Sed } 1313193326Sed } 1314193326Sed OS << "]"; 1315193326Sed} 1316193326Sed 1317193326Sedvoid StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) { 1318193326Sed OS << "super"; 1319193326Sed} 1320193326Sed 1321193326Sedvoid StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 1322193326Sed BlockDecl *BD = Node->getBlockDecl(); 1323193326Sed OS << "^"; 1324198092Srdivacky 1325193326Sed const FunctionType *AFT = Node->getFunctionType(); 1326198092Srdivacky 1327193326Sed if (isa<FunctionNoProtoType>(AFT)) { 1328193326Sed OS << "()"; 1329193326Sed } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 1330193326Sed OS << '('; 1331193326Sed std::string ParamStr; 1332193326Sed for (BlockDecl::param_iterator AI = BD->param_begin(), 1333193326Sed E = BD->param_end(); AI != E; ++AI) { 1334193326Sed if (AI != BD->param_begin()) OS << ", "; 1335193326Sed ParamStr = (*AI)->getNameAsString(); 1336193326Sed (*AI)->getType().getAsStringInternal(ParamStr, Policy); 1337193326Sed OS << ParamStr; 1338193326Sed } 1339198092Srdivacky 1340193326Sed const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 1341193326Sed if (FT->isVariadic()) { 1342193326Sed if (!BD->param_empty()) OS << ", "; 1343193326Sed OS << "..."; 1344193326Sed } 1345193326Sed OS << ')'; 1346193326Sed } 1347193326Sed} 1348193326Sed 1349193326Sedvoid StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) { 1350207619Srdivacky OS << Node->getDecl(); 1351193326Sed} 1352193326Sed//===----------------------------------------------------------------------===// 1353193326Sed// Stmt method implementations 1354193326Sed//===----------------------------------------------------------------------===// 1355193326Sed 1356193326Sedvoid Stmt::dumpPretty(ASTContext& Context) const { 1357195341Sed printPretty(llvm::errs(), Context, 0, 1358195341Sed PrintingPolicy(Context.getLangOptions())); 1359193326Sed} 1360193326Sed 1361193326Sedvoid Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context, 1362193326Sed PrinterHelper* Helper, 1363193326Sed const PrintingPolicy &Policy, 1364193326Sed unsigned Indentation) const { 1365193326Sed if (this == 0) { 1366193326Sed OS << "<NULL>"; 1367193326Sed return; 1368193326Sed } 1369193326Sed 1370198398Srdivacky if (Policy.Dump && &Context) { 1371198092Srdivacky dump(Context.getSourceManager()); 1372193326Sed return; 1373193326Sed } 1374198092Srdivacky 1375193326Sed StmtPrinter P(OS, Context, Helper, Policy, Indentation); 1376193326Sed P.Visit(const_cast<Stmt*>(this)); 1377193326Sed} 1378193326Sed 1379193326Sed//===----------------------------------------------------------------------===// 1380193326Sed// PrinterHelper 1381193326Sed//===----------------------------------------------------------------------===// 1382193326Sed 1383193326Sed// Implement virtual destructor. 1384193326SedPrinterHelper::~PrinterHelper() {} 1385