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