StmtPrinter.cpp revision 218893
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" 18218893Sdim#include "clang/AST/DeclTemplate.h" 19193326Sed#include "clang/AST/PrettyPrinter.h" 20193326Sed#include "llvm/Support/Format.h" 21207619Srdivacky#include "clang/AST/Expr.h" 22218893Sdim#include "clang/AST/ExprCXX.h" 23193326Sedusing namespace clang; 24193326Sed 25193326Sed//===----------------------------------------------------------------------===// 26193326Sed// StmtPrinter Visitor 27193326Sed//===----------------------------------------------------------------------===// 28193326Sed 29193326Sednamespace { 30199990Srdivacky class StmtPrinter : public StmtVisitor<StmtPrinter> { 31193326Sed llvm::raw_ostream &OS; 32193326Sed ASTContext &Context; 33193326Sed unsigned IndentLevel; 34193326Sed clang::PrinterHelper* Helper; 35193326Sed PrintingPolicy Policy; 36193326Sed 37193326Sed public: 38198092Srdivacky StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper, 39195341Sed const PrintingPolicy &Policy, 40193326Sed unsigned Indentation = 0) 41193326Sed : OS(os), Context(C), IndentLevel(Indentation), Helper(helper), 42193326Sed Policy(Policy) {} 43198092Srdivacky 44193326Sed void PrintStmt(Stmt *S) { 45193326Sed PrintStmt(S, Policy.Indentation); 46193326Sed } 47193326Sed 48193326Sed void PrintStmt(Stmt *S, int SubIndent) { 49193326Sed IndentLevel += SubIndent; 50193326Sed if (S && isa<Expr>(S)) { 51193326Sed // If this is an expr used in a stmt context, indent and newline it. 52193326Sed Indent(); 53193326Sed Visit(S); 54193326Sed OS << ";\n"; 55193326Sed } else if (S) { 56193326Sed Visit(S); 57193326Sed } else { 58193326Sed Indent() << "<<<NULL STATEMENT>>>\n"; 59193326Sed } 60193326Sed IndentLevel -= SubIndent; 61193326Sed } 62193326Sed 63193326Sed void PrintRawCompoundStmt(CompoundStmt *S); 64193326Sed void PrintRawDecl(Decl *D); 65193326Sed void PrintRawDeclStmt(DeclStmt *S); 66193326Sed void PrintRawIfStmt(IfStmt *If); 67193326Sed void PrintRawCXXCatchStmt(CXXCatchStmt *Catch); 68218893Sdim void PrintCallArgs(CallExpr *E); 69198092Srdivacky 70193326Sed void PrintExpr(Expr *E) { 71193326Sed if (E) 72193326Sed Visit(E); 73193326Sed else 74193326Sed OS << "<null expr>"; 75193326Sed } 76198092Srdivacky 77193326Sed llvm::raw_ostream &Indent(int Delta = 0) { 78193326Sed for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 79193326Sed OS << " "; 80193326Sed return OS; 81193326Sed } 82198092Srdivacky 83198092Srdivacky void Visit(Stmt* S) { 84193326Sed if (Helper && Helper->handledStmt(S,OS)) 85193326Sed return; 86193326Sed else StmtVisitor<StmtPrinter>::Visit(S); 87193326Sed } 88212904Sdim 89218893Sdim void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED { 90212904Sdim Indent() << "<<unknown stmt type>>\n"; 91212904Sdim } 92218893Sdim void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED { 93212904Sdim OS << "<<unknown expr type>>"; 94212904Sdim } 95212904Sdim void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); 96198092Srdivacky 97212904Sdim#define ABSTRACT_STMT(CLASS) 98193326Sed#define STMT(CLASS, PARENT) \ 99193326Sed void Visit##CLASS(CLASS *Node); 100208600Srdivacky#include "clang/AST/StmtNodes.inc" 101193326Sed }; 102193326Sed} 103193326Sed 104193326Sed//===----------------------------------------------------------------------===// 105193326Sed// Stmt printing methods. 106193326Sed//===----------------------------------------------------------------------===// 107193326Sed 108193326Sed/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 109193326Sed/// with no newline after the }. 110193326Sedvoid StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 111193326Sed OS << "{\n"; 112193326Sed for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end(); 113193326Sed I != E; ++I) 114193326Sed PrintStmt(*I); 115198092Srdivacky 116193326Sed Indent() << "}"; 117193326Sed} 118193326Sed 119193326Sedvoid StmtPrinter::PrintRawDecl(Decl *D) { 120195341Sed D->print(OS, Policy, IndentLevel); 121193326Sed} 122193326Sed 123193326Sedvoid StmtPrinter::PrintRawDeclStmt(DeclStmt *S) { 124193326Sed DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end(); 125193326Sed llvm::SmallVector<Decl*, 2> Decls; 126198092Srdivacky for ( ; Begin != End; ++Begin) 127193326Sed Decls.push_back(*Begin); 128193326Sed 129195341Sed Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel); 130193326Sed} 131193326Sed 132193326Sedvoid StmtPrinter::VisitNullStmt(NullStmt *Node) { 133193326Sed Indent() << ";\n"; 134193326Sed} 135193326Sed 136193326Sedvoid StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 137193326Sed Indent(); 138193326Sed PrintRawDeclStmt(Node); 139193326Sed OS << ";\n"; 140193326Sed} 141193326Sed 142193326Sedvoid StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 143193326Sed Indent(); 144193326Sed PrintRawCompoundStmt(Node); 145193326Sed OS << "\n"; 146193326Sed} 147193326Sed 148193326Sedvoid StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 149193326Sed Indent(-1) << "case "; 150193326Sed PrintExpr(Node->getLHS()); 151193326Sed if (Node->getRHS()) { 152193326Sed OS << " ... "; 153193326Sed PrintExpr(Node->getRHS()); 154193326Sed } 155193326Sed OS << ":\n"; 156198092Srdivacky 157193326Sed PrintStmt(Node->getSubStmt(), 0); 158193326Sed} 159193326Sed 160193326Sedvoid StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 161193326Sed Indent(-1) << "default:\n"; 162193326Sed PrintStmt(Node->getSubStmt(), 0); 163193326Sed} 164193326Sed 165193326Sedvoid StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 166193326Sed Indent(-1) << Node->getName() << ":\n"; 167193326Sed PrintStmt(Node->getSubStmt(), 0); 168193326Sed} 169193326Sed 170193326Sedvoid StmtPrinter::PrintRawIfStmt(IfStmt *If) { 171193326Sed OS << "if ("; 172193326Sed PrintExpr(If->getCond()); 173193326Sed OS << ')'; 174198092Srdivacky 175193326Sed if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) { 176193326Sed OS << ' '; 177193326Sed PrintRawCompoundStmt(CS); 178193326Sed OS << (If->getElse() ? ' ' : '\n'); 179193326Sed } else { 180193326Sed OS << '\n'; 181193326Sed PrintStmt(If->getThen()); 182193326Sed if (If->getElse()) Indent(); 183193326Sed } 184198092Srdivacky 185193326Sed if (Stmt *Else = If->getElse()) { 186193326Sed OS << "else"; 187198092Srdivacky 188193326Sed if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) { 189193326Sed OS << ' '; 190193326Sed PrintRawCompoundStmt(CS); 191193326Sed OS << '\n'; 192193326Sed } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) { 193193326Sed OS << ' '; 194193326Sed PrintRawIfStmt(ElseIf); 195193326Sed } else { 196193326Sed OS << '\n'; 197193326Sed PrintStmt(If->getElse()); 198193326Sed } 199193326Sed } 200193326Sed} 201193326Sed 202193326Sedvoid StmtPrinter::VisitIfStmt(IfStmt *If) { 203193326Sed Indent(); 204193326Sed PrintRawIfStmt(If); 205193326Sed} 206193326Sed 207193326Sedvoid StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 208193326Sed Indent() << "switch ("; 209193326Sed PrintExpr(Node->getCond()); 210193326Sed OS << ")"; 211198092Srdivacky 212193326Sed // Pretty print compoundstmt bodies (very common). 213193326Sed if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 214193326Sed OS << " "; 215193326Sed PrintRawCompoundStmt(CS); 216193326Sed OS << "\n"; 217193326Sed } else { 218193326Sed OS << "\n"; 219193326Sed PrintStmt(Node->getBody()); 220193326Sed } 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::VisitDeclRefExpr(DeclRefExpr *Node) { 469198893Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 470198893Srdivacky Qualifier->print(OS, Policy); 471212904Sdim OS << Node->getNameInfo(); 472212904Sdim if (Node->hasExplicitTemplateArgs()) 473198893Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 474198893Srdivacky Node->getTemplateArgs(), 475198893Srdivacky Node->getNumTemplateArgs(), 476198893Srdivacky Policy); 477193326Sed} 478193326Sed 479199990Srdivackyvoid StmtPrinter::VisitDependentScopeDeclRefExpr( 480199990Srdivacky DependentScopeDeclRefExpr *Node) { 481218893Sdim if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 482218893Sdim Qualifier->print(OS, Policy); 483212904Sdim OS << Node->getNameInfo(); 484199990Srdivacky if (Node->hasExplicitTemplateArgs()) 485199990Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 486199990Srdivacky Node->getTemplateArgs(), 487199990Srdivacky Node->getNumTemplateArgs(), 488199990Srdivacky Policy); 489193326Sed} 490193326Sed 491199990Srdivackyvoid StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 492195341Sed if (Node->getQualifier()) 493195341Sed Node->getQualifier()->print(OS, Policy); 494212904Sdim OS << Node->getNameInfo(); 495199990Srdivacky if (Node->hasExplicitTemplateArgs()) 496199990Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 497199990Srdivacky Node->getTemplateArgs(), 498195341Sed Node->getNumTemplateArgs(), 499199990Srdivacky Policy); 500195341Sed} 501195341Sed 502193326Sedvoid StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 503193326Sed if (Node->getBase()) { 504193326Sed PrintExpr(Node->getBase()); 505193326Sed OS << (Node->isArrow() ? "->" : "."); 506193326Sed } 507207619Srdivacky OS << Node->getDecl(); 508193326Sed} 509193326Sed 510193326Sedvoid StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 511218893Sdim if (Node->isSuperReceiver()) 512218893Sdim OS << "super."; 513218893Sdim else if (Node->getBase()) { 514193326Sed PrintExpr(Node->getBase()); 515193326Sed OS << "."; 516193326Sed } 517193326Sed 518218893Sdim if (Node->isImplicitProperty()) 519218893Sdim OS << Node->getImplicitPropertyGetter()->getSelector().getAsString(); 520218893Sdim else 521218893Sdim OS << Node->getExplicitProperty()->getName(); 522193326Sed} 523193326Sed 524193326Sedvoid StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 525193326Sed switch (Node->getIdentType()) { 526193326Sed default: 527193326Sed assert(0 && "unknown case"); 528193326Sed case PredefinedExpr::Func: 529193326Sed OS << "__func__"; 530193326Sed break; 531193326Sed case PredefinedExpr::Function: 532193326Sed OS << "__FUNCTION__"; 533193326Sed break; 534193326Sed case PredefinedExpr::PrettyFunction: 535193326Sed OS << "__PRETTY_FUNCTION__"; 536193326Sed break; 537193326Sed } 538193326Sed} 539193326Sed 540193326Sedvoid StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 541193326Sed unsigned value = Node->getValue(); 542193326Sed if (Node->isWide()) 543193326Sed OS << "L"; 544193326Sed switch (value) { 545193326Sed case '\\': 546193326Sed OS << "'\\\\'"; 547193326Sed break; 548193326Sed case '\'': 549193326Sed OS << "'\\''"; 550193326Sed break; 551193326Sed case '\a': 552193326Sed // TODO: K&R: the meaning of '\\a' is different in traditional C 553193326Sed OS << "'\\a'"; 554193326Sed break; 555193326Sed case '\b': 556193326Sed OS << "'\\b'"; 557193326Sed break; 558193326Sed // Nonstandard escape sequence. 559193326Sed /*case '\e': 560193326Sed OS << "'\\e'"; 561193326Sed break;*/ 562193326Sed case '\f': 563193326Sed OS << "'\\f'"; 564193326Sed break; 565193326Sed case '\n': 566193326Sed OS << "'\\n'"; 567193326Sed break; 568193326Sed case '\r': 569193326Sed OS << "'\\r'"; 570193326Sed break; 571193326Sed case '\t': 572193326Sed OS << "'\\t'"; 573193326Sed break; 574193326Sed case '\v': 575193326Sed OS << "'\\v'"; 576193326Sed break; 577193326Sed default: 578193326Sed if (value < 256 && isprint(value)) { 579193326Sed OS << "'" << (char)value << "'"; 580193326Sed } else if (value < 256) { 581193326Sed OS << "'\\x" << llvm::format("%x", value) << "'"; 582193326Sed } else { 583193326Sed // FIXME what to really do here? 584193326Sed OS << value; 585193326Sed } 586193326Sed } 587193326Sed} 588193326Sed 589193326Sedvoid StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 590193326Sed bool isSigned = Node->getType()->isSignedIntegerType(); 591193326Sed OS << Node->getValue().toString(10, isSigned); 592198092Srdivacky 593193326Sed // Emit suffixes. Integer literals are always a builtin integer type. 594198092Srdivacky switch (Node->getType()->getAs<BuiltinType>()->getKind()) { 595193326Sed default: assert(0 && "Unexpected type for integer literal!"); 596193326Sed case BuiltinType::Int: break; // no suffix. 597193326Sed case BuiltinType::UInt: OS << 'U'; break; 598193326Sed case BuiltinType::Long: OS << 'L'; break; 599193326Sed case BuiltinType::ULong: OS << "UL"; break; 600193326Sed case BuiltinType::LongLong: OS << "LL"; break; 601193326Sed case BuiltinType::ULongLong: OS << "ULL"; break; 602193326Sed } 603193326Sed} 604193326Sedvoid StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 605193326Sed // FIXME: print value more precisely. 606193326Sed OS << Node->getValueAsApproximateDouble(); 607193326Sed} 608193326Sed 609193326Sedvoid StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 610193326Sed PrintExpr(Node->getSubExpr()); 611193326Sed OS << "i"; 612193326Sed} 613193326Sed 614193326Sedvoid StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 615193326Sed if (Str->isWide()) OS << 'L'; 616193326Sed OS << '"'; 617193326Sed 618193326Sed // FIXME: this doesn't print wstrings right. 619212904Sdim llvm::StringRef StrData = Str->getString(); 620212904Sdim for (llvm::StringRef::iterator I = StrData.begin(), E = StrData.end(); 621212904Sdim I != E; ++I) { 622212904Sdim unsigned char Char = *I; 623198092Srdivacky 624193326Sed switch (Char) { 625193326Sed default: 626193326Sed if (isprint(Char)) 627193326Sed OS << (char)Char; 628193326Sed else // Output anything hard as an octal escape. 629193326Sed OS << '\\' 630193326Sed << (char)('0'+ ((Char >> 6) & 7)) 631193326Sed << (char)('0'+ ((Char >> 3) & 7)) 632193326Sed << (char)('0'+ ((Char >> 0) & 7)); 633193326Sed break; 634193326Sed // Handle some common non-printable cases to make dumps prettier. 635193326Sed case '\\': OS << "\\\\"; break; 636193326Sed case '"': OS << "\\\""; break; 637193326Sed case '\n': OS << "\\n"; break; 638193326Sed case '\t': OS << "\\t"; break; 639193326Sed case '\a': OS << "\\a"; break; 640193326Sed case '\b': OS << "\\b"; break; 641193326Sed } 642193326Sed } 643193326Sed OS << '"'; 644193326Sed} 645193326Sedvoid StmtPrinter::VisitParenExpr(ParenExpr *Node) { 646193326Sed OS << "("; 647193326Sed PrintExpr(Node->getSubExpr()); 648193326Sed OS << ")"; 649193326Sed} 650193326Sedvoid StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 651193326Sed if (!Node->isPostfix()) { 652193326Sed OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 653198092Srdivacky 654194613Sed // Print a space if this is an "identifier operator" like __real, or if 655194613Sed // it might be concatenated incorrectly like '+'. 656193326Sed switch (Node->getOpcode()) { 657193326Sed default: break; 658212904Sdim case UO_Real: 659212904Sdim case UO_Imag: 660212904Sdim case UO_Extension: 661193326Sed OS << ' '; 662193326Sed break; 663212904Sdim case UO_Plus: 664212904Sdim case UO_Minus: 665194613Sed if (isa<UnaryOperator>(Node->getSubExpr())) 666194613Sed OS << ' '; 667194613Sed break; 668193326Sed } 669193326Sed } 670193326Sed PrintExpr(Node->getSubExpr()); 671198092Srdivacky 672193326Sed if (Node->isPostfix()) 673193326Sed OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 674193326Sed} 675193326Sed 676207619Srdivackyvoid StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) { 677207619Srdivacky OS << "__builtin_offsetof("; 678210299Sed OS << Node->getTypeSourceInfo()->getType().getAsString(Policy) << ", "; 679207619Srdivacky bool PrintedSomething = false; 680207619Srdivacky for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) { 681207619Srdivacky OffsetOfExpr::OffsetOfNode ON = Node->getComponent(i); 682207619Srdivacky if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Array) { 683207619Srdivacky // Array node 684207619Srdivacky OS << "["; 685207619Srdivacky PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex())); 686207619Srdivacky OS << "]"; 687207619Srdivacky PrintedSomething = true; 688207619Srdivacky continue; 689207619Srdivacky } 690207619Srdivacky 691207619Srdivacky // Skip implicit base indirections. 692207619Srdivacky if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Base) 693207619Srdivacky continue; 694207619Srdivacky 695207619Srdivacky // Field or identifier node. 696207619Srdivacky IdentifierInfo *Id = ON.getFieldName(); 697207619Srdivacky if (!Id) 698207619Srdivacky continue; 699207619Srdivacky 700207619Srdivacky if (PrintedSomething) 701207619Srdivacky OS << "."; 702207619Srdivacky else 703207619Srdivacky PrintedSomething = true; 704207619Srdivacky OS << Id->getName(); 705207619Srdivacky } 706207619Srdivacky OS << ")"; 707207619Srdivacky} 708207619Srdivacky 709193326Sedvoid StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) { 710193326Sed OS << (Node->isSizeOf() ? "sizeof" : "__alignof"); 711193326Sed if (Node->isArgumentType()) 712210299Sed OS << "(" << Node->getArgumentType().getAsString(Policy) << ")"; 713193326Sed else { 714193326Sed OS << " "; 715193326Sed PrintExpr(Node->getArgumentExpr()); 716193326Sed } 717193326Sed} 718193326Sedvoid StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 719193326Sed PrintExpr(Node->getLHS()); 720193326Sed OS << "["; 721193326Sed PrintExpr(Node->getRHS()); 722193326Sed OS << "]"; 723193326Sed} 724193326Sed 725218893Sdimvoid StmtPrinter::PrintCallArgs(CallExpr *Call) { 726193326Sed for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 727193326Sed if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 728193326Sed // Don't print any defaulted arguments 729193326Sed break; 730193326Sed } 731193326Sed 732193326Sed if (i) OS << ", "; 733193326Sed PrintExpr(Call->getArg(i)); 734193326Sed } 735218893Sdim} 736218893Sdim 737218893Sdimvoid StmtPrinter::VisitCallExpr(CallExpr *Call) { 738218893Sdim PrintExpr(Call->getCallee()); 739218893Sdim OS << "("; 740218893Sdim PrintCallArgs(Call); 741193326Sed OS << ")"; 742193326Sed} 743193326Sedvoid StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 744193326Sed // FIXME: Suppress printing implicit bases (like "this") 745193326Sed PrintExpr(Node->getBase()); 746202379Srdivacky if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl())) 747202379Srdivacky if (FD->isAnonymousStructOrUnion()) 748202379Srdivacky return; 749193326Sed OS << (Node->isArrow() ? "->" : "."); 750198092Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 751198092Srdivacky Qualifier->print(OS, Policy); 752198092Srdivacky 753212904Sdim OS << Node->getMemberNameInfo(); 754198092Srdivacky 755212904Sdim if (Node->hasExplicitTemplateArgs()) 756198092Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 757198092Srdivacky Node->getTemplateArgs(), 758198092Srdivacky Node->getNumTemplateArgs(), 759198092Srdivacky Policy); 760193326Sed} 761198092Srdivackyvoid StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) { 762198092Srdivacky PrintExpr(Node->getBase()); 763198092Srdivacky OS << (Node->isArrow() ? "->isa" : ".isa"); 764198092Srdivacky} 765198092Srdivacky 766193326Sedvoid StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 767193326Sed PrintExpr(Node->getBase()); 768193326Sed OS << "."; 769193326Sed OS << Node->getAccessor().getName(); 770193326Sed} 771193326Sedvoid StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) { 772210299Sed OS << "(" << Node->getType().getAsString(Policy) << ")"; 773193326Sed PrintExpr(Node->getSubExpr()); 774193326Sed} 775193326Sedvoid StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 776210299Sed OS << "(" << Node->getType().getAsString(Policy) << ")"; 777193326Sed PrintExpr(Node->getInitializer()); 778193326Sed} 779193326Sedvoid StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 780193326Sed // No need to print anything, simply forward to the sub expression. 781193326Sed PrintExpr(Node->getSubExpr()); 782193326Sed} 783193326Sedvoid StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 784193326Sed PrintExpr(Node->getLHS()); 785193326Sed OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 786193326Sed PrintExpr(Node->getRHS()); 787193326Sed} 788193326Sedvoid StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 789193326Sed PrintExpr(Node->getLHS()); 790193326Sed OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 791193326Sed PrintExpr(Node->getRHS()); 792193326Sed} 793193326Sedvoid StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 794193326Sed PrintExpr(Node->getCond()); 795218893Sdim OS << " ? "; 796218893Sdim PrintExpr(Node->getLHS()); 797218893Sdim OS << " : "; 798193326Sed PrintExpr(Node->getRHS()); 799193326Sed} 800193326Sed 801193326Sed// GNU extensions. 802193326Sed 803218893Sdimvoid 804218893SdimStmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) { 805218893Sdim PrintExpr(Node->getCommon()); 806218893Sdim OS << " ?: "; 807218893Sdim PrintExpr(Node->getFalseExpr()); 808218893Sdim} 809193326Sedvoid StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 810193326Sed OS << "&&" << Node->getLabel()->getName(); 811193326Sed} 812193326Sed 813193326Sedvoid StmtPrinter::VisitStmtExpr(StmtExpr *E) { 814193326Sed OS << "("; 815193326Sed PrintRawCompoundStmt(E->getSubStmt()); 816193326Sed OS << ")"; 817193326Sed} 818193326Sed 819193326Sedvoid StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 820193326Sed OS << "__builtin_choose_expr("; 821193326Sed PrintExpr(Node->getCond()); 822193326Sed OS << ", "; 823193326Sed PrintExpr(Node->getLHS()); 824193326Sed OS << ", "; 825193326Sed PrintExpr(Node->getRHS()); 826193326Sed OS << ")"; 827193326Sed} 828193326Sed 829193326Sedvoid StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 830193326Sed OS << "__null"; 831193326Sed} 832193326Sed 833193326Sedvoid StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 834193326Sed OS << "__builtin_shufflevector("; 835193326Sed for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 836193326Sed if (i) OS << ", "; 837193326Sed PrintExpr(Node->getExpr(i)); 838193326Sed } 839193326Sed OS << ")"; 840193326Sed} 841193326Sed 842193326Sedvoid StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 843193326Sed if (Node->getSyntacticForm()) { 844193326Sed Visit(Node->getSyntacticForm()); 845193326Sed return; 846193326Sed } 847193326Sed 848193326Sed OS << "{ "; 849193326Sed for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 850193326Sed if (i) OS << ", "; 851193326Sed if (Node->getInit(i)) 852193326Sed PrintExpr(Node->getInit(i)); 853193326Sed else 854193326Sed OS << "0"; 855193326Sed } 856193326Sed OS << " }"; 857193326Sed} 858193326Sed 859198092Srdivackyvoid StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { 860198092Srdivacky OS << "( "; 861198092Srdivacky for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) { 862198092Srdivacky if (i) OS << ", "; 863198092Srdivacky PrintExpr(Node->getExpr(i)); 864198092Srdivacky } 865198092Srdivacky OS << " )"; 866198092Srdivacky} 867198092Srdivacky 868193326Sedvoid StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { 869193326Sed for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(), 870193326Sed DEnd = Node->designators_end(); 871193326Sed D != DEnd; ++D) { 872193326Sed if (D->isFieldDesignator()) { 873193326Sed if (D->getDotLoc().isInvalid()) 874193326Sed OS << D->getFieldName()->getName() << ":"; 875193326Sed else 876193326Sed OS << "." << D->getFieldName()->getName(); 877193326Sed } else { 878193326Sed OS << "["; 879193326Sed if (D->isArrayDesignator()) { 880193326Sed PrintExpr(Node->getArrayIndex(*D)); 881193326Sed } else { 882193326Sed PrintExpr(Node->getArrayRangeStart(*D)); 883193326Sed OS << " ... "; 884198092Srdivacky PrintExpr(Node->getArrayRangeEnd(*D)); 885193326Sed } 886193326Sed OS << "]"; 887193326Sed } 888193326Sed } 889193326Sed 890193326Sed OS << " = "; 891193326Sed PrintExpr(Node->getInit()); 892193326Sed} 893193326Sed 894193326Sedvoid StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { 895195341Sed if (Policy.LangOpts.CPlusPlus) 896193326Sed OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()"; 897193326Sed else { 898193326Sed OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")"; 899193326Sed if (Node->getType()->isRecordType()) 900193326Sed OS << "{}"; 901193326Sed else 902193326Sed OS << 0; 903193326Sed } 904193326Sed} 905193326Sed 906193326Sedvoid StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 907193326Sed OS << "__builtin_va_arg("; 908193326Sed PrintExpr(Node->getSubExpr()); 909193326Sed OS << ", "; 910210299Sed OS << Node->getType().getAsString(Policy); 911193326Sed OS << ")"; 912193326Sed} 913193326Sed 914193326Sed// C++ 915193326Sedvoid StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 916193326Sed const char *OpStrings[NUM_OVERLOADED_OPERATORS] = { 917193326Sed "", 918193326Sed#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 919193326Sed Spelling, 920193326Sed#include "clang/Basic/OperatorKinds.def" 921193326Sed }; 922193326Sed 923193326Sed OverloadedOperatorKind Kind = Node->getOperator(); 924193326Sed if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 925193326Sed if (Node->getNumArgs() == 1) { 926193326Sed OS << OpStrings[Kind] << ' '; 927193326Sed PrintExpr(Node->getArg(0)); 928193326Sed } else { 929193326Sed PrintExpr(Node->getArg(0)); 930193326Sed OS << ' ' << OpStrings[Kind]; 931193326Sed } 932193326Sed } else if (Kind == OO_Call) { 933193326Sed PrintExpr(Node->getArg(0)); 934193326Sed OS << '('; 935193326Sed for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 936193326Sed if (ArgIdx > 1) 937193326Sed OS << ", "; 938193326Sed if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 939193326Sed PrintExpr(Node->getArg(ArgIdx)); 940193326Sed } 941193326Sed OS << ')'; 942193326Sed } else if (Kind == OO_Subscript) { 943193326Sed PrintExpr(Node->getArg(0)); 944193326Sed OS << '['; 945193326Sed PrintExpr(Node->getArg(1)); 946193326Sed OS << ']'; 947193326Sed } else if (Node->getNumArgs() == 1) { 948193326Sed OS << OpStrings[Kind] << ' '; 949193326Sed PrintExpr(Node->getArg(0)); 950193326Sed } else if (Node->getNumArgs() == 2) { 951193326Sed PrintExpr(Node->getArg(0)); 952193326Sed OS << ' ' << OpStrings[Kind] << ' '; 953193326Sed PrintExpr(Node->getArg(1)); 954193326Sed } else { 955193326Sed assert(false && "unknown overloaded operator"); 956193326Sed } 957193326Sed} 958193326Sed 959193326Sedvoid StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 960193326Sed VisitCallExpr(cast<CallExpr>(Node)); 961193326Sed} 962193326Sed 963218893Sdimvoid StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) { 964218893Sdim PrintExpr(Node->getCallee()); 965218893Sdim OS << "<<<"; 966218893Sdim PrintCallArgs(Node->getConfig()); 967218893Sdim OS << ">>>("; 968218893Sdim PrintCallArgs(Node); 969218893Sdim OS << ")"; 970218893Sdim} 971218893Sdim 972193326Sedvoid StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 973193326Sed OS << Node->getCastName() << '<'; 974210299Sed OS << Node->getTypeAsWritten().getAsString(Policy) << ">("; 975193326Sed PrintExpr(Node->getSubExpr()); 976193326Sed OS << ")"; 977193326Sed} 978193326Sed 979193326Sedvoid StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 980193326Sed VisitCXXNamedCastExpr(Node); 981193326Sed} 982193326Sed 983193326Sedvoid StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 984193326Sed VisitCXXNamedCastExpr(Node); 985193326Sed} 986193326Sed 987193326Sedvoid StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 988193326Sed VisitCXXNamedCastExpr(Node); 989193326Sed} 990193326Sed 991193326Sedvoid StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 992193326Sed VisitCXXNamedCastExpr(Node); 993193326Sed} 994193326Sed 995193326Sedvoid StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 996193326Sed OS << "typeid("; 997193326Sed if (Node->isTypeOperand()) { 998210299Sed OS << Node->getTypeOperand().getAsString(Policy); 999193326Sed } else { 1000193326Sed PrintExpr(Node->getExprOperand()); 1001193326Sed } 1002193326Sed OS << ")"; 1003193326Sed} 1004193326Sed 1005218893Sdimvoid StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) { 1006218893Sdim OS << "__uuidof("; 1007218893Sdim if (Node->isTypeOperand()) { 1008218893Sdim OS << Node->getTypeOperand().getAsString(Policy); 1009218893Sdim } else { 1010218893Sdim PrintExpr(Node->getExprOperand()); 1011218893Sdim } 1012218893Sdim OS << ")"; 1013218893Sdim} 1014218893Sdim 1015193326Sedvoid StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 1016193326Sed OS << (Node->getValue() ? "true" : "false"); 1017193326Sed} 1018193326Sed 1019193326Sedvoid StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 1020193326Sed OS << "nullptr"; 1021193326Sed} 1022193326Sed 1023193326Sedvoid StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 1024193326Sed OS << "this"; 1025193326Sed} 1026193326Sed 1027193326Sedvoid StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 1028193326Sed if (Node->getSubExpr() == 0) 1029193326Sed OS << "throw"; 1030193326Sed else { 1031193326Sed OS << "throw "; 1032193326Sed PrintExpr(Node->getSubExpr()); 1033193326Sed } 1034193326Sed} 1035193326Sed 1036193326Sedvoid StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 1037193326Sed // Nothing to print: we picked up the default argument 1038193326Sed} 1039193326Sed 1040193326Sedvoid StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 1041210299Sed OS << Node->getType().getAsString(Policy); 1042193326Sed OS << "("; 1043193326Sed PrintExpr(Node->getSubExpr()); 1044193326Sed OS << ")"; 1045193326Sed} 1046193326Sed 1047193326Sedvoid StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 1048193326Sed PrintExpr(Node->getSubExpr()); 1049193326Sed} 1050193326Sed 1051193326Sedvoid StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 1052210299Sed OS << Node->getType().getAsString(Policy); 1053193326Sed OS << "("; 1054193326Sed for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 1055198092Srdivacky ArgEnd = Node->arg_end(); 1056193326Sed Arg != ArgEnd; ++Arg) { 1057193326Sed if (Arg != Node->arg_begin()) 1058193326Sed OS << ", "; 1059193326Sed PrintExpr(*Arg); 1060193326Sed } 1061193326Sed OS << ")"; 1062193326Sed} 1063193326Sed 1064210299Sedvoid StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { 1065218893Sdim if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo()) 1066218893Sdim OS << TSInfo->getType().getAsString(Policy) << "()"; 1067218893Sdim else 1068218893Sdim OS << Node->getType().getAsString(Policy) << "()"; 1069193326Sed} 1070193326Sed 1071193326Sedvoid StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 1072193326Sed if (E->isGlobalNew()) 1073193326Sed OS << "::"; 1074193326Sed OS << "new "; 1075193326Sed unsigned NumPlace = E->getNumPlacementArgs(); 1076193326Sed if (NumPlace > 0) { 1077193326Sed OS << "("; 1078193326Sed PrintExpr(E->getPlacementArg(0)); 1079193326Sed for (unsigned i = 1; i < NumPlace; ++i) { 1080193326Sed OS << ", "; 1081193326Sed PrintExpr(E->getPlacementArg(i)); 1082193326Sed } 1083193326Sed OS << ") "; 1084193326Sed } 1085193326Sed if (E->isParenTypeId()) 1086193326Sed OS << "("; 1087193326Sed std::string TypeS; 1088193326Sed if (Expr *Size = E->getArraySize()) { 1089193326Sed llvm::raw_string_ostream s(TypeS); 1090193326Sed Size->printPretty(s, Context, Helper, Policy); 1091193326Sed s.flush(); 1092193326Sed TypeS = "[" + TypeS + "]"; 1093193326Sed } 1094193326Sed E->getAllocatedType().getAsStringInternal(TypeS, Policy); 1095193326Sed OS << TypeS; 1096193326Sed if (E->isParenTypeId()) 1097193326Sed OS << ")"; 1098193326Sed 1099193326Sed if (E->hasInitializer()) { 1100193326Sed OS << "("; 1101193326Sed unsigned NumCons = E->getNumConstructorArgs(); 1102193326Sed if (NumCons > 0) { 1103193326Sed PrintExpr(E->getConstructorArg(0)); 1104193326Sed for (unsigned i = 1; i < NumCons; ++i) { 1105193326Sed OS << ", "; 1106193326Sed PrintExpr(E->getConstructorArg(i)); 1107193326Sed } 1108193326Sed } 1109193326Sed OS << ")"; 1110193326Sed } 1111193326Sed} 1112193326Sed 1113193326Sedvoid StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 1114193326Sed if (E->isGlobalDelete()) 1115193326Sed OS << "::"; 1116193326Sed OS << "delete "; 1117193326Sed if (E->isArrayForm()) 1118193326Sed OS << "[] "; 1119193326Sed PrintExpr(E->getArgument()); 1120193326Sed} 1121193326Sed 1122198092Srdivackyvoid StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 1123198092Srdivacky PrintExpr(E->getBase()); 1124198092Srdivacky if (E->isArrow()) 1125198092Srdivacky OS << "->"; 1126198092Srdivacky else 1127198092Srdivacky OS << '.'; 1128198092Srdivacky if (E->getQualifier()) 1129198092Srdivacky E->getQualifier()->print(OS, Policy); 1130198092Srdivacky 1131198092Srdivacky std::string TypeS; 1132204643Srdivacky if (IdentifierInfo *II = E->getDestroyedTypeIdentifier()) 1133204643Srdivacky OS << II->getName(); 1134204643Srdivacky else 1135204643Srdivacky E->getDestroyedType().getAsStringInternal(TypeS, Policy); 1136198092Srdivacky OS << TypeS; 1137198092Srdivacky} 1138198092Srdivacky 1139193326Sedvoid StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 1140218893Sdim for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 1141218893Sdim if (isa<CXXDefaultArgExpr>(E->getArg(i))) { 1142218893Sdim // Don't print any defaulted arguments 1143218893Sdim break; 1144218893Sdim } 1145218893Sdim 1146218893Sdim if (i) OS << ", "; 1147218893Sdim PrintExpr(E->getArg(i)); 1148202379Srdivacky } 1149193326Sed} 1150193326Sed 1151218893Sdimvoid StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) { 1152193326Sed // Just forward to the sub expression. 1153193326Sed PrintExpr(E->getSubExpr()); 1154193326Sed} 1155193326Sed 1156198092Srdivackyvoid 1157193326SedStmtPrinter::VisitCXXUnresolvedConstructExpr( 1158193326Sed CXXUnresolvedConstructExpr *Node) { 1159210299Sed OS << Node->getTypeAsWritten().getAsString(Policy); 1160193326Sed OS << "("; 1161193326Sed for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(), 1162198092Srdivacky ArgEnd = Node->arg_end(); 1163193326Sed Arg != ArgEnd; ++Arg) { 1164193326Sed if (Arg != Node->arg_begin()) 1165193326Sed OS << ", "; 1166193326Sed PrintExpr(*Arg); 1167193326Sed } 1168193326Sed OS << ")"; 1169193326Sed} 1170193326Sed 1171199990Srdivackyvoid StmtPrinter::VisitCXXDependentScopeMemberExpr( 1172199990Srdivacky CXXDependentScopeMemberExpr *Node) { 1173200583Srdivacky if (!Node->isImplicitAccess()) { 1174200583Srdivacky PrintExpr(Node->getBase()); 1175200583Srdivacky OS << (Node->isArrow() ? "->" : "."); 1176200583Srdivacky } 1177198092Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1178198092Srdivacky Qualifier->print(OS, Policy); 1179200583Srdivacky else if (Node->hasExplicitTemplateArgs()) 1180198092Srdivacky // FIXME: Track use of "template" keyword explicitly? 1181198092Srdivacky OS << "template "; 1182198092Srdivacky 1183212904Sdim OS << Node->getMemberNameInfo(); 1184198092Srdivacky 1185200583Srdivacky if (Node->hasExplicitTemplateArgs()) { 1186198092Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 1187198092Srdivacky Node->getTemplateArgs(), 1188198092Srdivacky Node->getNumTemplateArgs(), 1189198092Srdivacky Policy); 1190198092Srdivacky } 1191193326Sed} 1192193326Sed 1193199990Srdivackyvoid StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 1194200583Srdivacky if (!Node->isImplicitAccess()) { 1195200583Srdivacky PrintExpr(Node->getBase()); 1196200583Srdivacky OS << (Node->isArrow() ? "->" : "."); 1197200583Srdivacky } 1198199990Srdivacky if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1199199990Srdivacky Qualifier->print(OS, Policy); 1200199990Srdivacky 1201199990Srdivacky // FIXME: this might originally have been written with 'template' 1202199990Srdivacky 1203212904Sdim OS << Node->getMemberNameInfo(); 1204199990Srdivacky 1205199990Srdivacky if (Node->hasExplicitTemplateArgs()) { 1206199990Srdivacky OS << TemplateSpecializationType::PrintTemplateArgumentList( 1207199990Srdivacky Node->getTemplateArgs(), 1208199990Srdivacky Node->getNumTemplateArgs(), 1209199990Srdivacky Policy); 1210199990Srdivacky } 1211199990Srdivacky} 1212199990Srdivacky 1213193326Sedstatic const char *getTypeTraitName(UnaryTypeTrait UTT) { 1214193326Sed switch (UTT) { 1215218893Sdim default: llvm_unreachable("Unknown unary type trait"); 1216193326Sed case UTT_HasNothrowAssign: return "__has_nothrow_assign"; 1217193326Sed case UTT_HasNothrowCopy: return "__has_nothrow_copy"; 1218193326Sed case UTT_HasNothrowConstructor: return "__has_nothrow_constructor"; 1219193326Sed case UTT_HasTrivialAssign: return "__has_trivial_assign"; 1220193326Sed case UTT_HasTrivialCopy: return "__has_trivial_copy"; 1221193326Sed case UTT_HasTrivialConstructor: return "__has_trivial_constructor"; 1222193326Sed case UTT_HasTrivialDestructor: return "__has_trivial_destructor"; 1223193326Sed case UTT_HasVirtualDestructor: return "__has_virtual_destructor"; 1224193326Sed case UTT_IsAbstract: return "__is_abstract"; 1225193326Sed case UTT_IsClass: return "__is_class"; 1226193326Sed case UTT_IsEmpty: return "__is_empty"; 1227193326Sed case UTT_IsEnum: return "__is_enum"; 1228193326Sed case UTT_IsPOD: return "__is_pod"; 1229193326Sed case UTT_IsPolymorphic: return "__is_polymorphic"; 1230193326Sed case UTT_IsUnion: return "__is_union"; 1231193326Sed } 1232218893Sdim return ""; 1233193326Sed} 1234193326Sed 1235218893Sdimstatic const char *getTypeTraitName(BinaryTypeTrait BTT) { 1236218893Sdim switch (BTT) { 1237218893Sdim case BTT_IsBaseOf: return "__is_base_of"; 1238218893Sdim case BTT_TypeCompatible: return "__builtin_types_compatible_p"; 1239218893Sdim case BTT_IsConvertibleTo: return "__is_convertible_to"; 1240218893Sdim } 1241218893Sdim return ""; 1242218893Sdim} 1243218893Sdim 1244193326Sedvoid StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { 1245193326Sed OS << getTypeTraitName(E->getTrait()) << "(" 1246210299Sed << E->getQueriedType().getAsString(Policy) << ")"; 1247193326Sed} 1248193326Sed 1249218893Sdimvoid StmtPrinter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { 1250218893Sdim OS << getTypeTraitName(E->getTrait()) << "(" 1251218893Sdim << E->getLhsType().getAsString(Policy) << "," 1252218893Sdim << E->getRhsType().getAsString(Policy) << ")"; 1253218893Sdim} 1254218893Sdim 1255218893Sdimvoid StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { 1256218893Sdim OS << "noexcept("; 1257218893Sdim PrintExpr(E->getOperand()); 1258218893Sdim OS << ")"; 1259218893Sdim} 1260218893Sdim 1261218893Sdimvoid StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) { 1262218893Sdim PrintExpr(E->getPattern()); 1263218893Sdim OS << "..."; 1264218893Sdim} 1265218893Sdim 1266218893Sdimvoid StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { 1267218893Sdim OS << "sizeof...(" << E->getPack()->getNameAsString() << ")"; 1268218893Sdim} 1269218893Sdim 1270218893Sdimvoid StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr( 1271218893Sdim SubstNonTypeTemplateParmPackExpr *Node) { 1272218893Sdim OS << Node->getParameterPack()->getNameAsString(); 1273218893Sdim} 1274218893Sdim 1275198092Srdivacky// Obj-C 1276193326Sed 1277193326Sedvoid StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 1278193326Sed OS << "@"; 1279193326Sed VisitStringLiteral(Node->getString()); 1280193326Sed} 1281193326Sed 1282193326Sedvoid StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 1283210299Sed OS << "@encode(" << Node->getEncodedType().getAsString(Policy) << ')'; 1284193326Sed} 1285193326Sed 1286193326Sedvoid StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 1287193326Sed OS << "@selector(" << Node->getSelector().getAsString() << ')'; 1288193326Sed} 1289193326Sed 1290193326Sedvoid StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 1291207619Srdivacky OS << "@protocol(" << Node->getProtocol() << ')'; 1292193326Sed} 1293193326Sed 1294193326Sedvoid StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 1295193326Sed OS << "["; 1296207619Srdivacky switch (Mess->getReceiverKind()) { 1297207619Srdivacky case ObjCMessageExpr::Instance: 1298207619Srdivacky PrintExpr(Mess->getInstanceReceiver()); 1299207619Srdivacky break; 1300207619Srdivacky 1301207619Srdivacky case ObjCMessageExpr::Class: 1302207619Srdivacky OS << Mess->getClassReceiver().getAsString(Policy); 1303207619Srdivacky break; 1304207619Srdivacky 1305207619Srdivacky case ObjCMessageExpr::SuperInstance: 1306207619Srdivacky case ObjCMessageExpr::SuperClass: 1307207619Srdivacky OS << "Super"; 1308207619Srdivacky break; 1309207619Srdivacky } 1310207619Srdivacky 1311193326Sed OS << ' '; 1312193326Sed Selector selector = Mess->getSelector(); 1313193326Sed if (selector.isUnarySelector()) { 1314218893Sdim OS << selector.getNameForSlot(0); 1315193326Sed } else { 1316193326Sed for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 1317193326Sed if (i < selector.getNumArgs()) { 1318193326Sed if (i > 0) OS << ' '; 1319193326Sed if (selector.getIdentifierInfoForSlot(i)) 1320193326Sed OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 1321193326Sed else 1322193326Sed OS << ":"; 1323193326Sed } 1324193326Sed else OS << ", "; // Handle variadic methods. 1325198092Srdivacky 1326193326Sed PrintExpr(Mess->getArg(i)); 1327193326Sed } 1328193326Sed } 1329193326Sed OS << "]"; 1330193326Sed} 1331193326Sed 1332193326Sed 1333193326Sedvoid StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 1334193326Sed BlockDecl *BD = Node->getBlockDecl(); 1335193326Sed OS << "^"; 1336198092Srdivacky 1337193326Sed const FunctionType *AFT = Node->getFunctionType(); 1338198092Srdivacky 1339193326Sed if (isa<FunctionNoProtoType>(AFT)) { 1340193326Sed OS << "()"; 1341193326Sed } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 1342193326Sed OS << '('; 1343193326Sed std::string ParamStr; 1344193326Sed for (BlockDecl::param_iterator AI = BD->param_begin(), 1345193326Sed E = BD->param_end(); AI != E; ++AI) { 1346193326Sed if (AI != BD->param_begin()) OS << ", "; 1347193326Sed ParamStr = (*AI)->getNameAsString(); 1348193326Sed (*AI)->getType().getAsStringInternal(ParamStr, Policy); 1349193326Sed OS << ParamStr; 1350193326Sed } 1351198092Srdivacky 1352193326Sed const FunctionProtoType *FT = cast<FunctionProtoType>(AFT); 1353193326Sed if (FT->isVariadic()) { 1354193326Sed if (!BD->param_empty()) OS << ", "; 1355193326Sed OS << "..."; 1356193326Sed } 1357193326Sed OS << ')'; 1358193326Sed } 1359193326Sed} 1360193326Sed 1361193326Sedvoid StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) { 1362207619Srdivacky OS << Node->getDecl(); 1363193326Sed} 1364218893Sdim 1365218893Sdimvoid StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {} 1366218893Sdim 1367193326Sed//===----------------------------------------------------------------------===// 1368193326Sed// Stmt method implementations 1369193326Sed//===----------------------------------------------------------------------===// 1370193326Sed 1371193326Sedvoid Stmt::dumpPretty(ASTContext& Context) const { 1372195341Sed printPretty(llvm::errs(), Context, 0, 1373195341Sed PrintingPolicy(Context.getLangOptions())); 1374193326Sed} 1375193326Sed 1376193326Sedvoid Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context, 1377193326Sed PrinterHelper* Helper, 1378193326Sed const PrintingPolicy &Policy, 1379193326Sed unsigned Indentation) const { 1380193326Sed if (this == 0) { 1381193326Sed OS << "<NULL>"; 1382193326Sed return; 1383193326Sed } 1384193326Sed 1385198398Srdivacky if (Policy.Dump && &Context) { 1386212904Sdim dump(OS, Context.getSourceManager()); 1387193326Sed return; 1388193326Sed } 1389198092Srdivacky 1390193326Sed StmtPrinter P(OS, Context, Helper, Policy, Indentation); 1391193326Sed P.Visit(const_cast<Stmt*>(this)); 1392193326Sed} 1393193326Sed 1394193326Sed//===----------------------------------------------------------------------===// 1395193326Sed// PrinterHelper 1396193326Sed//===----------------------------------------------------------------------===// 1397193326Sed 1398193326Sed// Implement virtual destructor. 1399193326SedPrinterHelper::~PrinterHelper() {} 1400