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