StmtPrinter.cpp revision 200583
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"
20193326Sedusing namespace clang;
21193326Sed
22193326Sed//===----------------------------------------------------------------------===//
23193326Sed// StmtPrinter Visitor
24193326Sed//===----------------------------------------------------------------------===//
25193326Sed
26193326Sednamespace  {
27199990Srdivacky  class StmtPrinter : public StmtVisitor<StmtPrinter> {
28193326Sed    llvm::raw_ostream &OS;
29193326Sed    ASTContext &Context;
30193326Sed    unsigned IndentLevel;
31193326Sed    clang::PrinterHelper* Helper;
32193326Sed    PrintingPolicy Policy;
33193326Sed
34193326Sed  public:
35198092Srdivacky    StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper,
36195341Sed                const PrintingPolicy &Policy,
37193326Sed                unsigned Indentation = 0)
38193326Sed      : OS(os), Context(C), IndentLevel(Indentation), Helper(helper),
39193326Sed        Policy(Policy) {}
40198092Srdivacky
41193326Sed    void PrintStmt(Stmt *S) {
42193326Sed      PrintStmt(S, Policy.Indentation);
43193326Sed    }
44193326Sed
45193326Sed    void PrintStmt(Stmt *S, int SubIndent) {
46193326Sed      IndentLevel += SubIndent;
47193326Sed      if (S && isa<Expr>(S)) {
48193326Sed        // If this is an expr used in a stmt context, indent and newline it.
49193326Sed        Indent();
50193326Sed        Visit(S);
51193326Sed        OS << ";\n";
52193326Sed      } else if (S) {
53193326Sed        Visit(S);
54193326Sed      } else {
55193326Sed        Indent() << "<<<NULL STATEMENT>>>\n";
56193326Sed      }
57193326Sed      IndentLevel -= SubIndent;
58193326Sed    }
59193326Sed
60193326Sed    void PrintRawCompoundStmt(CompoundStmt *S);
61193326Sed    void PrintRawDecl(Decl *D);
62193326Sed    void PrintRawDeclStmt(DeclStmt *S);
63193326Sed    void PrintRawIfStmt(IfStmt *If);
64193326Sed    void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
65198092Srdivacky
66193326Sed    void PrintExpr(Expr *E) {
67193326Sed      if (E)
68193326Sed        Visit(E);
69193326Sed      else
70193326Sed        OS << "<null expr>";
71193326Sed    }
72198092Srdivacky
73193326Sed    llvm::raw_ostream &Indent(int Delta = 0) {
74193326Sed      for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
75193326Sed        OS << "  ";
76193326Sed      return OS;
77193326Sed    }
78198092Srdivacky
79193326Sed    bool PrintOffsetOfDesignator(Expr *E);
80193326Sed    void VisitUnaryOffsetOf(UnaryOperator *Node);
81198092Srdivacky
82198092Srdivacky    void Visit(Stmt* S) {
83193326Sed      if (Helper && Helper->handledStmt(S,OS))
84193326Sed          return;
85193326Sed      else StmtVisitor<StmtPrinter>::Visit(S);
86193326Sed    }
87198092Srdivacky
88193326Sed    void VisitStmt(Stmt *Node);
89193326Sed#define STMT(CLASS, PARENT) \
90193326Sed    void Visit##CLASS(CLASS *Node);
91193326Sed#include "clang/AST/StmtNodes.def"
92193326Sed  };
93193326Sed}
94193326Sed
95193326Sed//===----------------------------------------------------------------------===//
96193326Sed//  Stmt printing methods.
97193326Sed//===----------------------------------------------------------------------===//
98193326Sed
99193326Sedvoid StmtPrinter::VisitStmt(Stmt *Node) {
100193326Sed  Indent() << "<<unknown stmt type>>\n";
101193326Sed}
102193326Sed
103193326Sed/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
104193326Sed/// with no newline after the }.
105193326Sedvoid StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
106193326Sed  OS << "{\n";
107193326Sed  for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
108193326Sed       I != E; ++I)
109193326Sed    PrintStmt(*I);
110198092Srdivacky
111193326Sed  Indent() << "}";
112193326Sed}
113193326Sed
114193326Sedvoid StmtPrinter::PrintRawDecl(Decl *D) {
115195341Sed  D->print(OS, Policy, IndentLevel);
116193326Sed}
117193326Sed
118193326Sedvoid StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
119193326Sed  DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end();
120193326Sed  llvm::SmallVector<Decl*, 2> Decls;
121198092Srdivacky  for ( ; Begin != End; ++Begin)
122193326Sed    Decls.push_back(*Begin);
123193326Sed
124195341Sed  Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
125193326Sed}
126193326Sed
127193326Sedvoid StmtPrinter::VisitNullStmt(NullStmt *Node) {
128193326Sed  Indent() << ";\n";
129193326Sed}
130193326Sed
131193326Sedvoid StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
132193326Sed  Indent();
133193326Sed  PrintRawDeclStmt(Node);
134193326Sed  OS << ";\n";
135193326Sed}
136193326Sed
137193326Sedvoid StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
138193326Sed  Indent();
139193326Sed  PrintRawCompoundStmt(Node);
140193326Sed  OS << "\n";
141193326Sed}
142193326Sed
143193326Sedvoid StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
144193326Sed  Indent(-1) << "case ";
145193326Sed  PrintExpr(Node->getLHS());
146193326Sed  if (Node->getRHS()) {
147193326Sed    OS << " ... ";
148193326Sed    PrintExpr(Node->getRHS());
149193326Sed  }
150193326Sed  OS << ":\n";
151198092Srdivacky
152193326Sed  PrintStmt(Node->getSubStmt(), 0);
153193326Sed}
154193326Sed
155193326Sedvoid StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
156193326Sed  Indent(-1) << "default:\n";
157193326Sed  PrintStmt(Node->getSubStmt(), 0);
158193326Sed}
159193326Sed
160193326Sedvoid StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
161193326Sed  Indent(-1) << Node->getName() << ":\n";
162193326Sed  PrintStmt(Node->getSubStmt(), 0);
163193326Sed}
164193326Sed
165193326Sedvoid StmtPrinter::PrintRawIfStmt(IfStmt *If) {
166193326Sed  OS << "if (";
167193326Sed  PrintExpr(If->getCond());
168193326Sed  OS << ')';
169198092Srdivacky
170193326Sed  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
171193326Sed    OS << ' ';
172193326Sed    PrintRawCompoundStmt(CS);
173193326Sed    OS << (If->getElse() ? ' ' : '\n');
174193326Sed  } else {
175193326Sed    OS << '\n';
176193326Sed    PrintStmt(If->getThen());
177193326Sed    if (If->getElse()) Indent();
178193326Sed  }
179198092Srdivacky
180193326Sed  if (Stmt *Else = If->getElse()) {
181193326Sed    OS << "else";
182198092Srdivacky
183193326Sed    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
184193326Sed      OS << ' ';
185193326Sed      PrintRawCompoundStmt(CS);
186193326Sed      OS << '\n';
187193326Sed    } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
188193326Sed      OS << ' ';
189193326Sed      PrintRawIfStmt(ElseIf);
190193326Sed    } else {
191193326Sed      OS << '\n';
192193326Sed      PrintStmt(If->getElse());
193193326Sed    }
194193326Sed  }
195193326Sed}
196193326Sed
197193326Sedvoid StmtPrinter::VisitIfStmt(IfStmt *If) {
198193326Sed  Indent();
199193326Sed  PrintRawIfStmt(If);
200193326Sed}
201193326Sed
202193326Sedvoid StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
203193326Sed  Indent() << "switch (";
204193326Sed  PrintExpr(Node->getCond());
205193326Sed  OS << ")";
206198092Srdivacky
207193326Sed  // Pretty print compoundstmt bodies (very common).
208193326Sed  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
209193326Sed    OS << " ";
210193326Sed    PrintRawCompoundStmt(CS);
211193326Sed    OS << "\n";
212193326Sed  } else {
213193326Sed    OS << "\n";
214193326Sed    PrintStmt(Node->getBody());
215193326Sed  }
216193326Sed}
217193326Sed
218193326Sedvoid StmtPrinter::VisitSwitchCase(SwitchCase*) {
219193326Sed  assert(0 && "SwitchCase is an abstract class");
220193326Sed}
221193326Sed
222193326Sedvoid StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
223193326Sed  Indent() << "while (";
224193326Sed  PrintExpr(Node->getCond());
225193326Sed  OS << ")\n";
226193326Sed  PrintStmt(Node->getBody());
227193326Sed}
228193326Sed
229193326Sedvoid StmtPrinter::VisitDoStmt(DoStmt *Node) {
230193326Sed  Indent() << "do ";
231193326Sed  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
232193326Sed    PrintRawCompoundStmt(CS);
233193326Sed    OS << " ";
234193326Sed  } else {
235193326Sed    OS << "\n";
236193326Sed    PrintStmt(Node->getBody());
237193326Sed    Indent();
238193326Sed  }
239198092Srdivacky
240193326Sed  OS << "while (";
241193326Sed  PrintExpr(Node->getCond());
242193326Sed  OS << ");\n";
243193326Sed}
244193326Sed
245193326Sedvoid StmtPrinter::VisitForStmt(ForStmt *Node) {
246193326Sed  Indent() << "for (";
247193326Sed  if (Node->getInit()) {
248193326Sed    if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
249193326Sed      PrintRawDeclStmt(DS);
250193326Sed    else
251193326Sed      PrintExpr(cast<Expr>(Node->getInit()));
252193326Sed  }
253193326Sed  OS << ";";
254193326Sed  if (Node->getCond()) {
255193326Sed    OS << " ";
256193326Sed    PrintExpr(Node->getCond());
257193326Sed  }
258193326Sed  OS << ";";
259193326Sed  if (Node->getInc()) {
260193326Sed    OS << " ";
261193326Sed    PrintExpr(Node->getInc());
262193326Sed  }
263193326Sed  OS << ") ";
264198092Srdivacky
265193326Sed  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
266193326Sed    PrintRawCompoundStmt(CS);
267193326Sed    OS << "\n";
268193326Sed  } else {
269193326Sed    OS << "\n";
270193326Sed    PrintStmt(Node->getBody());
271193326Sed  }
272193326Sed}
273193326Sed
274193326Sedvoid StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
275193326Sed  Indent() << "for (";
276193326Sed  if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
277193326Sed    PrintRawDeclStmt(DS);
278193326Sed  else
279193326Sed    PrintExpr(cast<Expr>(Node->getElement()));
280193326Sed  OS << " in ";
281193326Sed  PrintExpr(Node->getCollection());
282193326Sed  OS << ") ";
283198092Srdivacky
284193326Sed  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
285193326Sed    PrintRawCompoundStmt(CS);
286193326Sed    OS << "\n";
287193326Sed  } else {
288193326Sed    OS << "\n";
289193326Sed    PrintStmt(Node->getBody());
290193326Sed  }
291193326Sed}
292193326Sed
293193326Sedvoid StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
294193326Sed  Indent() << "goto " << Node->getLabel()->getName() << ";\n";
295193326Sed}
296193326Sed
297193326Sedvoid StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
298193326Sed  Indent() << "goto *";
299193326Sed  PrintExpr(Node->getTarget());
300193326Sed  OS << ";\n";
301193326Sed}
302193326Sed
303193326Sedvoid StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
304193326Sed  Indent() << "continue;\n";
305193326Sed}
306193326Sed
307193326Sedvoid StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
308193326Sed  Indent() << "break;\n";
309193326Sed}
310193326Sed
311193326Sed
312193326Sedvoid StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
313193326Sed  Indent() << "return";
314193326Sed  if (Node->getRetValue()) {
315193326Sed    OS << " ";
316193326Sed    PrintExpr(Node->getRetValue());
317193326Sed  }
318193326Sed  OS << ";\n";
319193326Sed}
320193326Sed
321193326Sed
322193326Sedvoid StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
323193326Sed  Indent() << "asm ";
324198092Srdivacky
325193326Sed  if (Node->isVolatile())
326193326Sed    OS << "volatile ";
327198092Srdivacky
328193326Sed  OS << "(";
329193326Sed  VisitStringLiteral(Node->getAsmString());
330198092Srdivacky
331193326Sed  // Outputs
332193326Sed  if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
333193326Sed      Node->getNumClobbers() != 0)
334193326Sed    OS << " : ";
335198092Srdivacky
336193326Sed  for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
337193326Sed    if (i != 0)
338193326Sed      OS << ", ";
339198092Srdivacky
340193326Sed    if (!Node->getOutputName(i).empty()) {
341193326Sed      OS << '[';
342193326Sed      OS << Node->getOutputName(i);
343193326Sed      OS << "] ";
344193326Sed    }
345198092Srdivacky
346193326Sed    VisitStringLiteral(Node->getOutputConstraintLiteral(i));
347193326Sed    OS << " ";
348193326Sed    Visit(Node->getOutputExpr(i));
349193326Sed  }
350198092Srdivacky
351193326Sed  // Inputs
352193326Sed  if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
353193326Sed    OS << " : ";
354198092Srdivacky
355193326Sed  for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
356193326Sed    if (i != 0)
357193326Sed      OS << ", ";
358198092Srdivacky
359193326Sed    if (!Node->getInputName(i).empty()) {
360193326Sed      OS << '[';
361193326Sed      OS << Node->getInputName(i);
362193326Sed      OS << "] ";
363193326Sed    }
364198092Srdivacky
365193326Sed    VisitStringLiteral(Node->getInputConstraintLiteral(i));
366193326Sed    OS << " ";
367193326Sed    Visit(Node->getInputExpr(i));
368193326Sed  }
369198092Srdivacky
370193326Sed  // Clobbers
371193326Sed  if (Node->getNumClobbers() != 0)
372193326Sed    OS << " : ";
373198092Srdivacky
374193326Sed  for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
375193326Sed    if (i != 0)
376193326Sed      OS << ", ";
377198092Srdivacky
378193326Sed    VisitStringLiteral(Node->getClobber(i));
379193326Sed  }
380198092Srdivacky
381193326Sed  OS << ");\n";
382193326Sed}
383193326Sed
384193326Sedvoid StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
385193326Sed  Indent() << "@try";
386193326Sed  if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
387193326Sed    PrintRawCompoundStmt(TS);
388193326Sed    OS << "\n";
389193326Sed  }
390198092Srdivacky
391198092Srdivacky  for (ObjCAtCatchStmt *catchStmt =
392193326Sed         static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts());
393198092Srdivacky       catchStmt;
394198092Srdivacky       catchStmt =
395193326Sed         static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) {
396193326Sed    Indent() << "@catch(";
397193326Sed    if (catchStmt->getCatchParamDecl()) {
398193326Sed      if (Decl *DS = catchStmt->getCatchParamDecl())
399193326Sed        PrintRawDecl(DS);
400193326Sed    }
401193326Sed    OS << ")";
402198092Srdivacky    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
403198092Srdivacky      PrintRawCompoundStmt(CS);
404198092Srdivacky      OS << "\n";
405198092Srdivacky    }
406193326Sed  }
407198092Srdivacky
408198092Srdivacky  if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>(
409198092Srdivacky        Node->getFinallyStmt())) {
410193326Sed    Indent() << "@finally";
411193326Sed    PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
412193326Sed    OS << "\n";
413198092Srdivacky  }
414193326Sed}
415193326Sed
416193326Sedvoid StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
417193326Sed}
418193326Sed
419193326Sedvoid StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
420193326Sed  Indent() << "@catch (...) { /* todo */ } \n";
421193326Sed}
422193326Sed
423193326Sedvoid StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
424193326Sed  Indent() << "@throw";
425193326Sed  if (Node->getThrowExpr()) {
426193326Sed    OS << " ";
427193326Sed    PrintExpr(Node->getThrowExpr());
428193326Sed  }
429193326Sed  OS << ";\n";
430193326Sed}
431193326Sed
432193326Sedvoid StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
433193326Sed  Indent() << "@synchronized (";
434193326Sed  PrintExpr(Node->getSynchExpr());
435193326Sed  OS << ")";
436193326Sed  PrintRawCompoundStmt(Node->getSynchBody());
437193326Sed  OS << "\n";
438193326Sed}
439193326Sed
440193326Sedvoid StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
441193326Sed  OS << "catch (";
442193326Sed  if (Decl *ExDecl = Node->getExceptionDecl())
443193326Sed    PrintRawDecl(ExDecl);
444193326Sed  else
445193326Sed    OS << "...";
446193326Sed  OS << ") ";
447193326Sed  PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
448193326Sed}
449193326Sed
450193326Sedvoid StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
451193326Sed  Indent();
452193326Sed  PrintRawCXXCatchStmt(Node);
453193326Sed  OS << "\n";
454193326Sed}
455193326Sed
456193326Sedvoid StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
457193326Sed  Indent() << "try ";
458193326Sed  PrintRawCompoundStmt(Node->getTryBlock());
459198092Srdivacky  for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
460193326Sed    OS << " ";
461193326Sed    PrintRawCXXCatchStmt(Node->getHandler(i));
462193326Sed  }
463193326Sed  OS << "\n";
464193326Sed}
465193326Sed
466193326Sed//===----------------------------------------------------------------------===//
467193326Sed//  Expr printing methods.
468193326Sed//===----------------------------------------------------------------------===//
469193326Sed
470193326Sedvoid StmtPrinter::VisitExpr(Expr *Node) {
471193326Sed  OS << "<<unknown expr type>>";
472193326Sed}
473193326Sed
474193326Sedvoid StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
475198893Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
476198893Srdivacky    Qualifier->print(OS, Policy);
477193326Sed  OS << Node->getDecl()->getNameAsString();
478198893Srdivacky  if (Node->hasExplicitTemplateArgumentList())
479198893Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
480198893Srdivacky                                                    Node->getTemplateArgs(),
481198893Srdivacky                                                    Node->getNumTemplateArgs(),
482198893Srdivacky                                                    Policy);
483193326Sed}
484193326Sed
485199990Srdivackyvoid StmtPrinter::VisitDependentScopeDeclRefExpr(
486199990Srdivacky                                           DependentScopeDeclRefExpr *Node) {
487193326Sed  Node->getQualifier()->print(OS, Policy);
488193326Sed  OS << Node->getDeclName().getAsString();
489199990Srdivacky  if (Node->hasExplicitTemplateArgs())
490199990Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
491199990Srdivacky                                                   Node->getTemplateArgs(),
492199990Srdivacky                                                   Node->getNumTemplateArgs(),
493199990Srdivacky                                                   Policy);
494193326Sed}
495193326Sed
496199990Srdivackyvoid StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
497195341Sed  if (Node->getQualifier())
498195341Sed    Node->getQualifier()->print(OS, Policy);
499199990Srdivacky  OS << Node->getName().getAsString();
500199990Srdivacky  if (Node->hasExplicitTemplateArgs())
501199990Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
502199990Srdivacky                                                   Node->getTemplateArgs(),
503195341Sed                                                   Node->getNumTemplateArgs(),
504199990Srdivacky                                                   Policy);
505195341Sed}
506195341Sed
507193326Sedvoid StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
508193326Sed  if (Node->getBase()) {
509193326Sed    PrintExpr(Node->getBase());
510193326Sed    OS << (Node->isArrow() ? "->" : ".");
511193326Sed  }
512193326Sed  OS << Node->getDecl()->getNameAsString();
513193326Sed}
514193326Sed
515193326Sedvoid StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
516193326Sed  if (Node->getBase()) {
517193326Sed    PrintExpr(Node->getBase());
518193326Sed    OS << ".";
519193326Sed  }
520193326Sed  OS << Node->getProperty()->getNameAsCString();
521193326Sed}
522193326Sed
523198092Srdivackyvoid StmtPrinter::VisitObjCImplicitSetterGetterRefExpr(
524198092Srdivacky                                        ObjCImplicitSetterGetterRefExpr *Node) {
525193326Sed  if (Node->getBase()) {
526193326Sed    PrintExpr(Node->getBase());
527193326Sed    OS << ".";
528193326Sed  }
529198092Srdivacky  if (Node->getGetterMethod())
530198092Srdivacky    OS << Node->getGetterMethod()->getNameAsString();
531198092Srdivacky
532193326Sed}
533193326Sed
534193326Sedvoid StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
535193326Sed  switch (Node->getIdentType()) {
536193326Sed    default:
537193326Sed      assert(0 && "unknown case");
538193326Sed    case PredefinedExpr::Func:
539193326Sed      OS << "__func__";
540193326Sed      break;
541193326Sed    case PredefinedExpr::Function:
542193326Sed      OS << "__FUNCTION__";
543193326Sed      break;
544193326Sed    case PredefinedExpr::PrettyFunction:
545193326Sed      OS << "__PRETTY_FUNCTION__";
546193326Sed      break;
547193326Sed  }
548193326Sed}
549193326Sed
550193326Sedvoid StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
551193326Sed  unsigned value = Node->getValue();
552193326Sed  if (Node->isWide())
553193326Sed    OS << "L";
554193326Sed  switch (value) {
555193326Sed  case '\\':
556193326Sed    OS << "'\\\\'";
557193326Sed    break;
558193326Sed  case '\'':
559193326Sed    OS << "'\\''";
560193326Sed    break;
561193326Sed  case '\a':
562193326Sed    // TODO: K&R: the meaning of '\\a' is different in traditional C
563193326Sed    OS << "'\\a'";
564193326Sed    break;
565193326Sed  case '\b':
566193326Sed    OS << "'\\b'";
567193326Sed    break;
568193326Sed  // Nonstandard escape sequence.
569193326Sed  /*case '\e':
570193326Sed    OS << "'\\e'";
571193326Sed    break;*/
572193326Sed  case '\f':
573193326Sed    OS << "'\\f'";
574193326Sed    break;
575193326Sed  case '\n':
576193326Sed    OS << "'\\n'";
577193326Sed    break;
578193326Sed  case '\r':
579193326Sed    OS << "'\\r'";
580193326Sed    break;
581193326Sed  case '\t':
582193326Sed    OS << "'\\t'";
583193326Sed    break;
584193326Sed  case '\v':
585193326Sed    OS << "'\\v'";
586193326Sed    break;
587193326Sed  default:
588193326Sed    if (value < 256 && isprint(value)) {
589193326Sed      OS << "'" << (char)value << "'";
590193326Sed    } else if (value < 256) {
591193326Sed      OS << "'\\x" << llvm::format("%x", value) << "'";
592193326Sed    } else {
593193326Sed      // FIXME what to really do here?
594193326Sed      OS << value;
595193326Sed    }
596193326Sed  }
597193326Sed}
598193326Sed
599193326Sedvoid StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
600193326Sed  bool isSigned = Node->getType()->isSignedIntegerType();
601193326Sed  OS << Node->getValue().toString(10, isSigned);
602198092Srdivacky
603193326Sed  // Emit suffixes.  Integer literals are always a builtin integer type.
604198092Srdivacky  switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
605193326Sed  default: assert(0 && "Unexpected type for integer literal!");
606193326Sed  case BuiltinType::Int:       break; // no suffix.
607193326Sed  case BuiltinType::UInt:      OS << 'U'; break;
608193326Sed  case BuiltinType::Long:      OS << 'L'; break;
609193326Sed  case BuiltinType::ULong:     OS << "UL"; break;
610193326Sed  case BuiltinType::LongLong:  OS << "LL"; break;
611193326Sed  case BuiltinType::ULongLong: OS << "ULL"; break;
612193326Sed  }
613193326Sed}
614193326Sedvoid StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
615193326Sed  // FIXME: print value more precisely.
616193326Sed  OS << Node->getValueAsApproximateDouble();
617193326Sed}
618193326Sed
619193326Sedvoid StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
620193326Sed  PrintExpr(Node->getSubExpr());
621193326Sed  OS << "i";
622193326Sed}
623193326Sed
624193326Sedvoid StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
625193326Sed  if (Str->isWide()) OS << 'L';
626193326Sed  OS << '"';
627193326Sed
628193326Sed  // FIXME: this doesn't print wstrings right.
629193326Sed  for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
630193326Sed    unsigned char Char = Str->getStrData()[i];
631198092Srdivacky
632193326Sed    switch (Char) {
633193326Sed    default:
634193326Sed      if (isprint(Char))
635193326Sed        OS << (char)Char;
636193326Sed      else  // Output anything hard as an octal escape.
637193326Sed        OS << '\\'
638193326Sed        << (char)('0'+ ((Char >> 6) & 7))
639193326Sed        << (char)('0'+ ((Char >> 3) & 7))
640193326Sed        << (char)('0'+ ((Char >> 0) & 7));
641193326Sed      break;
642193326Sed    // Handle some common non-printable cases to make dumps prettier.
643193326Sed    case '\\': OS << "\\\\"; break;
644193326Sed    case '"': OS << "\\\""; break;
645193326Sed    case '\n': OS << "\\n"; break;
646193326Sed    case '\t': OS << "\\t"; break;
647193326Sed    case '\a': OS << "\\a"; break;
648193326Sed    case '\b': OS << "\\b"; break;
649193326Sed    }
650193326Sed  }
651193326Sed  OS << '"';
652193326Sed}
653193326Sedvoid StmtPrinter::VisitParenExpr(ParenExpr *Node) {
654193326Sed  OS << "(";
655193326Sed  PrintExpr(Node->getSubExpr());
656193326Sed  OS << ")";
657193326Sed}
658193326Sedvoid StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
659193326Sed  if (!Node->isPostfix()) {
660193326Sed    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
661198092Srdivacky
662194613Sed    // Print a space if this is an "identifier operator" like __real, or if
663194613Sed    // it might be concatenated incorrectly like '+'.
664193326Sed    switch (Node->getOpcode()) {
665193326Sed    default: break;
666193326Sed    case UnaryOperator::Real:
667193326Sed    case UnaryOperator::Imag:
668193326Sed    case UnaryOperator::Extension:
669193326Sed      OS << ' ';
670193326Sed      break;
671194613Sed    case UnaryOperator::Plus:
672194613Sed    case UnaryOperator::Minus:
673194613Sed      if (isa<UnaryOperator>(Node->getSubExpr()))
674194613Sed        OS << ' ';
675194613Sed      break;
676193326Sed    }
677193326Sed  }
678193326Sed  PrintExpr(Node->getSubExpr());
679198092Srdivacky
680193326Sed  if (Node->isPostfix())
681193326Sed    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
682193326Sed}
683193326Sed
684193326Sedbool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
685193326Sed  if (isa<UnaryOperator>(E)) {
686193326Sed    // Base case, print the type and comma.
687193326Sed    OS << E->getType().getAsString() << ", ";
688193326Sed    return true;
689193326Sed  } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
690193326Sed    PrintOffsetOfDesignator(ASE->getLHS());
691193326Sed    OS << "[";
692193326Sed    PrintExpr(ASE->getRHS());
693193326Sed    OS << "]";
694193326Sed    return false;
695193326Sed  } else {
696193326Sed    MemberExpr *ME = cast<MemberExpr>(E);
697193326Sed    bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
698193326Sed    OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getNameAsString();
699193326Sed    return false;
700193326Sed  }
701193326Sed}
702193326Sed
703193326Sedvoid StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
704193326Sed  OS << "__builtin_offsetof(";
705193326Sed  PrintOffsetOfDesignator(Node->getSubExpr());
706193326Sed  OS << ")";
707193326Sed}
708193326Sed
709193326Sedvoid StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
710193326Sed  OS << (Node->isSizeOf() ? "sizeof" : "__alignof");
711193326Sed  if (Node->isArgumentType())
712193326Sed    OS << "(" << Node->getArgumentType().getAsString() << ")";
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
725193326Sedvoid StmtPrinter::VisitCallExpr(CallExpr *Call) {
726193326Sed  PrintExpr(Call->getCallee());
727193326Sed  OS << "(";
728193326Sed  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
729193326Sed    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
730193326Sed      // Don't print any defaulted arguments
731193326Sed      break;
732193326Sed    }
733193326Sed
734193326Sed    if (i) OS << ", ";
735193326Sed    PrintExpr(Call->getArg(i));
736193326Sed  }
737193326Sed  OS << ")";
738193326Sed}
739193326Sedvoid StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
740193326Sed  // FIXME: Suppress printing implicit bases (like "this")
741193326Sed  PrintExpr(Node->getBase());
742193326Sed  OS << (Node->isArrow() ? "->" : ".");
743193326Sed  // FIXME: Suppress printing references to unnamed objects
744193326Sed  // representing anonymous unions/structs
745198092Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
746198092Srdivacky    Qualifier->print(OS, Policy);
747198092Srdivacky
748193326Sed  OS << Node->getMemberDecl()->getNameAsString();
749198092Srdivacky
750198092Srdivacky  if (Node->hasExplicitTemplateArgumentList())
751198092Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
752198092Srdivacky                                                    Node->getTemplateArgs(),
753198092Srdivacky                                                    Node->getNumTemplateArgs(),
754198092Srdivacky                                                                Policy);
755193326Sed}
756198092Srdivackyvoid StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
757198092Srdivacky  PrintExpr(Node->getBase());
758198092Srdivacky  OS << (Node->isArrow() ? "->isa" : ".isa");
759198092Srdivacky}
760198092Srdivacky
761193326Sedvoid StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
762193326Sed  PrintExpr(Node->getBase());
763193326Sed  OS << ".";
764193326Sed  OS << Node->getAccessor().getName();
765193326Sed}
766193326Sedvoid StmtPrinter::VisitCastExpr(CastExpr *) {
767193326Sed  assert(0 && "CastExpr is an abstract class");
768193326Sed}
769193326Sedvoid StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) {
770193326Sed  assert(0 && "ExplicitCastExpr is an abstract class");
771193326Sed}
772193326Sedvoid StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
773193326Sed  OS << "(" << Node->getType().getAsString() << ")";
774193326Sed  PrintExpr(Node->getSubExpr());
775193326Sed}
776193326Sedvoid StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
777193326Sed  OS << "(" << Node->getType().getAsString() << ")";
778193326Sed  PrintExpr(Node->getInitializer());
779193326Sed}
780193326Sedvoid StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
781193326Sed  // No need to print anything, simply forward to the sub expression.
782193326Sed  PrintExpr(Node->getSubExpr());
783193326Sed}
784193326Sedvoid StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
785193326Sed  PrintExpr(Node->getLHS());
786193326Sed  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
787193326Sed  PrintExpr(Node->getRHS());
788193326Sed}
789193326Sedvoid StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
790193326Sed  PrintExpr(Node->getLHS());
791193326Sed  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
792193326Sed  PrintExpr(Node->getRHS());
793193326Sed}
794193326Sedvoid StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
795193326Sed  PrintExpr(Node->getCond());
796198092Srdivacky
797193326Sed  if (Node->getLHS()) {
798193326Sed    OS << " ? ";
799193326Sed    PrintExpr(Node->getLHS());
800193326Sed    OS << " : ";
801193326Sed  }
802193326Sed  else { // Handle GCC extension where LHS can be NULL.
803193326Sed    OS << " ?: ";
804193326Sed  }
805198092Srdivacky
806193326Sed  PrintExpr(Node->getRHS());
807193326Sed}
808193326Sed
809193326Sed// GNU extensions.
810193326Sed
811193326Sedvoid StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
812193326Sed  OS << "&&" << Node->getLabel()->getName();
813193326Sed}
814193326Sed
815193326Sedvoid StmtPrinter::VisitStmtExpr(StmtExpr *E) {
816193326Sed  OS << "(";
817193326Sed  PrintRawCompoundStmt(E->getSubStmt());
818193326Sed  OS << ")";
819193326Sed}
820193326Sed
821193326Sedvoid StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
822193326Sed  OS << "__builtin_types_compatible_p(";
823193326Sed  OS << Node->getArgType1().getAsString() << ",";
824193326Sed  OS << Node->getArgType2().getAsString() << ")";
825193326Sed}
826193326Sed
827193326Sedvoid StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
828193326Sed  OS << "__builtin_choose_expr(";
829193326Sed  PrintExpr(Node->getCond());
830193326Sed  OS << ", ";
831193326Sed  PrintExpr(Node->getLHS());
832193326Sed  OS << ", ";
833193326Sed  PrintExpr(Node->getRHS());
834193326Sed  OS << ")";
835193326Sed}
836193326Sed
837193326Sedvoid StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
838193326Sed  OS << "__null";
839193326Sed}
840193326Sed
841193326Sedvoid StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
842193326Sed  OS << "__builtin_shufflevector(";
843193326Sed  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
844193326Sed    if (i) OS << ", ";
845193326Sed    PrintExpr(Node->getExpr(i));
846193326Sed  }
847193326Sed  OS << ")";
848193326Sed}
849193326Sed
850193326Sedvoid StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
851193326Sed  if (Node->getSyntacticForm()) {
852193326Sed    Visit(Node->getSyntacticForm());
853193326Sed    return;
854193326Sed  }
855193326Sed
856193326Sed  OS << "{ ";
857193326Sed  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
858193326Sed    if (i) OS << ", ";
859193326Sed    if (Node->getInit(i))
860193326Sed      PrintExpr(Node->getInit(i));
861193326Sed    else
862193326Sed      OS << "0";
863193326Sed  }
864193326Sed  OS << " }";
865193326Sed}
866193326Sed
867198092Srdivackyvoid StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
868198092Srdivacky  OS << "( ";
869198092Srdivacky  for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
870198092Srdivacky    if (i) OS << ", ";
871198092Srdivacky    PrintExpr(Node->getExpr(i));
872198092Srdivacky  }
873198092Srdivacky  OS << " )";
874198092Srdivacky}
875198092Srdivacky
876193326Sedvoid StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
877193326Sed  for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(),
878193326Sed                      DEnd = Node->designators_end();
879193326Sed       D != DEnd; ++D) {
880193326Sed    if (D->isFieldDesignator()) {
881193326Sed      if (D->getDotLoc().isInvalid())
882193326Sed        OS << D->getFieldName()->getName() << ":";
883193326Sed      else
884193326Sed        OS << "." << D->getFieldName()->getName();
885193326Sed    } else {
886193326Sed      OS << "[";
887193326Sed      if (D->isArrayDesignator()) {
888193326Sed        PrintExpr(Node->getArrayIndex(*D));
889193326Sed      } else {
890193326Sed        PrintExpr(Node->getArrayRangeStart(*D));
891193326Sed        OS << " ... ";
892198092Srdivacky        PrintExpr(Node->getArrayRangeEnd(*D));
893193326Sed      }
894193326Sed      OS << "]";
895193326Sed    }
896193326Sed  }
897193326Sed
898193326Sed  OS << " = ";
899193326Sed  PrintExpr(Node->getInit());
900193326Sed}
901193326Sed
902193326Sedvoid StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
903195341Sed  if (Policy.LangOpts.CPlusPlus)
904193326Sed    OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()";
905193326Sed  else {
906193326Sed    OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")";
907193326Sed    if (Node->getType()->isRecordType())
908193326Sed      OS << "{}";
909193326Sed    else
910193326Sed      OS << 0;
911193326Sed  }
912193326Sed}
913193326Sed
914193326Sedvoid StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
915193326Sed  OS << "__builtin_va_arg(";
916193326Sed  PrintExpr(Node->getSubExpr());
917193326Sed  OS << ", ";
918193326Sed  OS << Node->getType().getAsString();
919193326Sed  OS << ")";
920193326Sed}
921193326Sed
922193326Sed// C++
923193326Sedvoid StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
924193326Sed  const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
925193326Sed    "",
926193326Sed#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
927193326Sed    Spelling,
928193326Sed#include "clang/Basic/OperatorKinds.def"
929193326Sed  };
930193326Sed
931193326Sed  OverloadedOperatorKind Kind = Node->getOperator();
932193326Sed  if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
933193326Sed    if (Node->getNumArgs() == 1) {
934193326Sed      OS << OpStrings[Kind] << ' ';
935193326Sed      PrintExpr(Node->getArg(0));
936193326Sed    } else {
937193326Sed      PrintExpr(Node->getArg(0));
938193326Sed      OS << ' ' << OpStrings[Kind];
939193326Sed    }
940193326Sed  } else if (Kind == OO_Call) {
941193326Sed    PrintExpr(Node->getArg(0));
942193326Sed    OS << '(';
943193326Sed    for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
944193326Sed      if (ArgIdx > 1)
945193326Sed        OS << ", ";
946193326Sed      if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
947193326Sed        PrintExpr(Node->getArg(ArgIdx));
948193326Sed    }
949193326Sed    OS << ')';
950193326Sed  } else if (Kind == OO_Subscript) {
951193326Sed    PrintExpr(Node->getArg(0));
952193326Sed    OS << '[';
953193326Sed    PrintExpr(Node->getArg(1));
954193326Sed    OS << ']';
955193326Sed  } else if (Node->getNumArgs() == 1) {
956193326Sed    OS << OpStrings[Kind] << ' ';
957193326Sed    PrintExpr(Node->getArg(0));
958193326Sed  } else if (Node->getNumArgs() == 2) {
959193326Sed    PrintExpr(Node->getArg(0));
960193326Sed    OS << ' ' << OpStrings[Kind] << ' ';
961193326Sed    PrintExpr(Node->getArg(1));
962193326Sed  } else {
963193326Sed    assert(false && "unknown overloaded operator");
964193326Sed  }
965193326Sed}
966193326Sed
967193326Sedvoid StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
968193326Sed  VisitCallExpr(cast<CallExpr>(Node));
969193326Sed}
970193326Sed
971193326Sedvoid StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
972193326Sed  OS << Node->getCastName() << '<';
973193326Sed  OS << Node->getTypeAsWritten().getAsString() << ">(";
974193326Sed  PrintExpr(Node->getSubExpr());
975193326Sed  OS << ")";
976193326Sed}
977193326Sed
978193326Sedvoid StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
979193326Sed  VisitCXXNamedCastExpr(Node);
980193326Sed}
981193326Sed
982193326Sedvoid StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
983193326Sed  VisitCXXNamedCastExpr(Node);
984193326Sed}
985193326Sed
986193326Sedvoid StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
987193326Sed  VisitCXXNamedCastExpr(Node);
988193326Sed}
989193326Sed
990193326Sedvoid StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
991193326Sed  VisitCXXNamedCastExpr(Node);
992193326Sed}
993193326Sed
994193326Sedvoid StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
995193326Sed  OS << "typeid(";
996193326Sed  if (Node->isTypeOperand()) {
997193326Sed    OS << Node->getTypeOperand().getAsString();
998193326Sed  } else {
999193326Sed    PrintExpr(Node->getExprOperand());
1000193326Sed  }
1001193326Sed  OS << ")";
1002193326Sed}
1003193326Sed
1004193326Sedvoid StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
1005193326Sed  OS << (Node->getValue() ? "true" : "false");
1006193326Sed}
1007193326Sed
1008193326Sedvoid StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
1009193326Sed  OS << "nullptr";
1010193326Sed}
1011193326Sed
1012193326Sedvoid StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
1013193326Sed  OS << "this";
1014193326Sed}
1015193326Sed
1016193326Sedvoid StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
1017193326Sed  if (Node->getSubExpr() == 0)
1018193326Sed    OS << "throw";
1019193326Sed  else {
1020193326Sed    OS << "throw ";
1021193326Sed    PrintExpr(Node->getSubExpr());
1022193326Sed  }
1023193326Sed}
1024193326Sed
1025193326Sedvoid StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
1026193326Sed  // Nothing to print: we picked up the default argument
1027193326Sed}
1028193326Sed
1029193326Sedvoid StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
1030193326Sed  OS << Node->getType().getAsString();
1031193326Sed  OS << "(";
1032193326Sed  PrintExpr(Node->getSubExpr());
1033193326Sed  OS << ")";
1034193326Sed}
1035193326Sed
1036193326Sedvoid StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
1037193326Sed  PrintExpr(Node->getSubExpr());
1038193326Sed}
1039193326Sed
1040193326Sedvoid StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
1041193326Sed  OS << Node->getType().getAsString();
1042193326Sed  OS << "(";
1043193326Sed  for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
1044198092Srdivacky                                         ArgEnd = Node->arg_end();
1045193326Sed       Arg != ArgEnd; ++Arg) {
1046193326Sed    if (Arg != Node->arg_begin())
1047193326Sed      OS << ", ";
1048193326Sed    PrintExpr(*Arg);
1049193326Sed  }
1050193326Sed  OS << ")";
1051193326Sed}
1052193326Sed
1053193326Sedvoid StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
1054193326Sed  OS << Node->getType().getAsString() << "()";
1055193326Sed}
1056193326Sed
1057193326Sedvoid StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
1058193326Sed  if (E->isGlobalNew())
1059193326Sed    OS << "::";
1060193326Sed  OS << "new ";
1061193326Sed  unsigned NumPlace = E->getNumPlacementArgs();
1062193326Sed  if (NumPlace > 0) {
1063193326Sed    OS << "(";
1064193326Sed    PrintExpr(E->getPlacementArg(0));
1065193326Sed    for (unsigned i = 1; i < NumPlace; ++i) {
1066193326Sed      OS << ", ";
1067193326Sed      PrintExpr(E->getPlacementArg(i));
1068193326Sed    }
1069193326Sed    OS << ") ";
1070193326Sed  }
1071193326Sed  if (E->isParenTypeId())
1072193326Sed    OS << "(";
1073193326Sed  std::string TypeS;
1074193326Sed  if (Expr *Size = E->getArraySize()) {
1075193326Sed    llvm::raw_string_ostream s(TypeS);
1076193326Sed    Size->printPretty(s, Context, Helper, Policy);
1077193326Sed    s.flush();
1078193326Sed    TypeS = "[" + TypeS + "]";
1079193326Sed  }
1080193326Sed  E->getAllocatedType().getAsStringInternal(TypeS, Policy);
1081193326Sed  OS << TypeS;
1082193326Sed  if (E->isParenTypeId())
1083193326Sed    OS << ")";
1084193326Sed
1085193326Sed  if (E->hasInitializer()) {
1086193326Sed    OS << "(";
1087193326Sed    unsigned NumCons = E->getNumConstructorArgs();
1088193326Sed    if (NumCons > 0) {
1089193326Sed      PrintExpr(E->getConstructorArg(0));
1090193326Sed      for (unsigned i = 1; i < NumCons; ++i) {
1091193326Sed        OS << ", ";
1092193326Sed        PrintExpr(E->getConstructorArg(i));
1093193326Sed      }
1094193326Sed    }
1095193326Sed    OS << ")";
1096193326Sed  }
1097193326Sed}
1098193326Sed
1099193326Sedvoid StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1100193326Sed  if (E->isGlobalDelete())
1101193326Sed    OS << "::";
1102193326Sed  OS << "delete ";
1103193326Sed  if (E->isArrayForm())
1104193326Sed    OS << "[] ";
1105193326Sed  PrintExpr(E->getArgument());
1106193326Sed}
1107193326Sed
1108198092Srdivackyvoid StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1109198092Srdivacky  PrintExpr(E->getBase());
1110198092Srdivacky  if (E->isArrow())
1111198092Srdivacky    OS << "->";
1112198092Srdivacky  else
1113198092Srdivacky    OS << '.';
1114198092Srdivacky  if (E->getQualifier())
1115198092Srdivacky    E->getQualifier()->print(OS, Policy);
1116198092Srdivacky
1117198092Srdivacky  std::string TypeS;
1118198092Srdivacky  E->getDestroyedType().getAsStringInternal(TypeS, Policy);
1119198092Srdivacky  OS << TypeS;
1120198092Srdivacky}
1121198092Srdivacky
1122193326Sedvoid StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
1123193326Sed  // Nothing to print.
1124193326Sed}
1125193326Sed
1126193326Sedvoid StmtPrinter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
1127193326Sed  // Just forward to the sub expression.
1128193326Sed  PrintExpr(E->getSubExpr());
1129193326Sed}
1130193326Sed
1131198092Srdivackyvoid
1132193326SedStmtPrinter::VisitCXXUnresolvedConstructExpr(
1133193326Sed                                           CXXUnresolvedConstructExpr *Node) {
1134193326Sed  OS << Node->getTypeAsWritten().getAsString();
1135193326Sed  OS << "(";
1136193326Sed  for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
1137198092Srdivacky                                             ArgEnd = Node->arg_end();
1138193326Sed       Arg != ArgEnd; ++Arg) {
1139193326Sed    if (Arg != Node->arg_begin())
1140193326Sed      OS << ", ";
1141193326Sed    PrintExpr(*Arg);
1142193326Sed  }
1143193326Sed  OS << ")";
1144193326Sed}
1145193326Sed
1146199990Srdivackyvoid StmtPrinter::VisitCXXDependentScopeMemberExpr(
1147199990Srdivacky                                         CXXDependentScopeMemberExpr *Node) {
1148200583Srdivacky  if (!Node->isImplicitAccess()) {
1149200583Srdivacky    PrintExpr(Node->getBase());
1150200583Srdivacky    OS << (Node->isArrow() ? "->" : ".");
1151200583Srdivacky  }
1152198092Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1153198092Srdivacky    Qualifier->print(OS, Policy);
1154200583Srdivacky  else if (Node->hasExplicitTemplateArgs())
1155198092Srdivacky    // FIXME: Track use of "template" keyword explicitly?
1156198092Srdivacky    OS << "template ";
1157198092Srdivacky
1158193326Sed  OS << Node->getMember().getAsString();
1159198092Srdivacky
1160200583Srdivacky  if (Node->hasExplicitTemplateArgs()) {
1161198092Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1162198092Srdivacky                                                    Node->getTemplateArgs(),
1163198092Srdivacky                                                    Node->getNumTemplateArgs(),
1164198092Srdivacky                                                    Policy);
1165198092Srdivacky  }
1166193326Sed}
1167193326Sed
1168199990Srdivackyvoid StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
1169200583Srdivacky  if (!Node->isImplicitAccess()) {
1170200583Srdivacky    PrintExpr(Node->getBase());
1171200583Srdivacky    OS << (Node->isArrow() ? "->" : ".");
1172200583Srdivacky  }
1173199990Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1174199990Srdivacky    Qualifier->print(OS, Policy);
1175199990Srdivacky
1176199990Srdivacky  // FIXME: this might originally have been written with 'template'
1177199990Srdivacky
1178199990Srdivacky  OS << Node->getMemberName().getAsString();
1179199990Srdivacky
1180199990Srdivacky  if (Node->hasExplicitTemplateArgs()) {
1181199990Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1182199990Srdivacky                                                    Node->getTemplateArgs(),
1183199990Srdivacky                                                    Node->getNumTemplateArgs(),
1184199990Srdivacky                                                    Policy);
1185199990Srdivacky  }
1186199990Srdivacky}
1187199990Srdivacky
1188193326Sedstatic const char *getTypeTraitName(UnaryTypeTrait UTT) {
1189193326Sed  switch (UTT) {
1190193326Sed  default: assert(false && "Unknown type trait");
1191193326Sed  case UTT_HasNothrowAssign:      return "__has_nothrow_assign";
1192193326Sed  case UTT_HasNothrowCopy:        return "__has_nothrow_copy";
1193193326Sed  case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
1194193326Sed  case UTT_HasTrivialAssign:      return "__has_trivial_assign";
1195193326Sed  case UTT_HasTrivialCopy:        return "__has_trivial_copy";
1196193326Sed  case UTT_HasTrivialConstructor: return "__has_trivial_constructor";
1197193326Sed  case UTT_HasTrivialDestructor:  return "__has_trivial_destructor";
1198193326Sed  case UTT_HasVirtualDestructor:  return "__has_virtual_destructor";
1199193326Sed  case UTT_IsAbstract:            return "__is_abstract";
1200193326Sed  case UTT_IsClass:               return "__is_class";
1201193326Sed  case UTT_IsEmpty:               return "__is_empty";
1202193326Sed  case UTT_IsEnum:                return "__is_enum";
1203193326Sed  case UTT_IsPOD:                 return "__is_pod";
1204193326Sed  case UTT_IsPolymorphic:         return "__is_polymorphic";
1205193326Sed  case UTT_IsUnion:               return "__is_union";
1206193326Sed  }
1207193326Sed}
1208193326Sed
1209193326Sedvoid StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1210193326Sed  OS << getTypeTraitName(E->getTrait()) << "("
1211193326Sed     << E->getQueriedType().getAsString() << ")";
1212193326Sed}
1213193326Sed
1214198092Srdivacky// Obj-C
1215193326Sed
1216193326Sedvoid StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
1217193326Sed  OS << "@";
1218193326Sed  VisitStringLiteral(Node->getString());
1219193326Sed}
1220193326Sed
1221193326Sedvoid StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
1222193326Sed  OS << "@encode(" << Node->getEncodedType().getAsString() << ')';
1223193326Sed}
1224193326Sed
1225193326Sedvoid StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
1226193326Sed  OS << "@selector(" << Node->getSelector().getAsString() << ')';
1227193326Sed}
1228193326Sed
1229193326Sedvoid StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
1230193326Sed  OS << "@protocol(" << Node->getProtocol()->getNameAsString() << ')';
1231193326Sed}
1232193326Sed
1233193326Sedvoid StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
1234193326Sed  OS << "[";
1235193326Sed  Expr *receiver = Mess->getReceiver();
1236193326Sed  if (receiver) PrintExpr(receiver);
1237193326Sed  else OS << Mess->getClassName()->getName();
1238193326Sed  OS << ' ';
1239193326Sed  Selector selector = Mess->getSelector();
1240193326Sed  if (selector.isUnarySelector()) {
1241193326Sed    OS << selector.getIdentifierInfoForSlot(0)->getName();
1242193326Sed  } else {
1243193326Sed    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
1244193326Sed      if (i < selector.getNumArgs()) {
1245193326Sed        if (i > 0) OS << ' ';
1246193326Sed        if (selector.getIdentifierInfoForSlot(i))
1247193326Sed          OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
1248193326Sed        else
1249193326Sed           OS << ":";
1250193326Sed      }
1251193326Sed      else OS << ", "; // Handle variadic methods.
1252198092Srdivacky
1253193326Sed      PrintExpr(Mess->getArg(i));
1254193326Sed    }
1255193326Sed  }
1256193326Sed  OS << "]";
1257193326Sed}
1258193326Sed
1259193326Sedvoid StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) {
1260193326Sed  OS << "super";
1261193326Sed}
1262193326Sed
1263193326Sedvoid StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
1264193326Sed  BlockDecl *BD = Node->getBlockDecl();
1265193326Sed  OS << "^";
1266198092Srdivacky
1267193326Sed  const FunctionType *AFT = Node->getFunctionType();
1268198092Srdivacky
1269193326Sed  if (isa<FunctionNoProtoType>(AFT)) {
1270193326Sed    OS << "()";
1271193326Sed  } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
1272193326Sed    OS << '(';
1273193326Sed    std::string ParamStr;
1274193326Sed    for (BlockDecl::param_iterator AI = BD->param_begin(),
1275193326Sed         E = BD->param_end(); AI != E; ++AI) {
1276193326Sed      if (AI != BD->param_begin()) OS << ", ";
1277193326Sed      ParamStr = (*AI)->getNameAsString();
1278193326Sed      (*AI)->getType().getAsStringInternal(ParamStr, Policy);
1279193326Sed      OS << ParamStr;
1280193326Sed    }
1281198092Srdivacky
1282193326Sed    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
1283193326Sed    if (FT->isVariadic()) {
1284193326Sed      if (!BD->param_empty()) OS << ", ";
1285193326Sed      OS << "...";
1286193326Sed    }
1287193326Sed    OS << ')';
1288193326Sed  }
1289193326Sed}
1290193326Sed
1291193326Sedvoid StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
1292193326Sed  OS << Node->getDecl()->getNameAsString();
1293193326Sed}
1294193326Sed//===----------------------------------------------------------------------===//
1295193326Sed// Stmt method implementations
1296193326Sed//===----------------------------------------------------------------------===//
1297193326Sed
1298193326Sedvoid Stmt::dumpPretty(ASTContext& Context) const {
1299195341Sed  printPretty(llvm::errs(), Context, 0,
1300195341Sed              PrintingPolicy(Context.getLangOptions()));
1301193326Sed}
1302193326Sed
1303193326Sedvoid Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,
1304193326Sed                       PrinterHelper* Helper,
1305193326Sed                       const PrintingPolicy &Policy,
1306193326Sed                       unsigned Indentation) const {
1307193326Sed  if (this == 0) {
1308193326Sed    OS << "<NULL>";
1309193326Sed    return;
1310193326Sed  }
1311193326Sed
1312198398Srdivacky  if (Policy.Dump && &Context) {
1313198092Srdivacky    dump(Context.getSourceManager());
1314193326Sed    return;
1315193326Sed  }
1316198092Srdivacky
1317193326Sed  StmtPrinter P(OS, Context, Helper, Policy, Indentation);
1318193326Sed  P.Visit(const_cast<Stmt*>(this));
1319193326Sed}
1320193326Sed
1321193326Sed//===----------------------------------------------------------------------===//
1322193326Sed// PrinterHelper
1323193326Sed//===----------------------------------------------------------------------===//
1324193326Sed
1325193326Sed// Implement virtual destructor.
1326193326SedPrinterHelper::~PrinterHelper() {}
1327