StmtPrinter.cpp revision 224145
1193326Sed//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
11193326Sed// pretty print the AST back out to C code.
12193326Sed//
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed
15193326Sed#include "clang/AST/StmtVisitor.h"
16193326Sed#include "clang/AST/DeclCXX.h"
17193326Sed#include "clang/AST/DeclObjC.h"
18218893Sdim#include "clang/AST/DeclTemplate.h"
19193326Sed#include "clang/AST/PrettyPrinter.h"
20193326Sed#include "llvm/Support/Format.h"
21207619Srdivacky#include "clang/AST/Expr.h"
22218893Sdim#include "clang/AST/ExprCXX.h"
23193326Sedusing namespace clang;
24193326Sed
25193326Sed//===----------------------------------------------------------------------===//
26193326Sed// StmtPrinter Visitor
27193326Sed//===----------------------------------------------------------------------===//
28193326Sed
29193326Sednamespace  {
30199990Srdivacky  class StmtPrinter : public StmtVisitor<StmtPrinter> {
31193326Sed    llvm::raw_ostream &OS;
32193326Sed    ASTContext &Context;
33193326Sed    unsigned IndentLevel;
34193326Sed    clang::PrinterHelper* Helper;
35193326Sed    PrintingPolicy Policy;
36193326Sed
37193326Sed  public:
38198092Srdivacky    StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper,
39195341Sed                const PrintingPolicy &Policy,
40193326Sed                unsigned Indentation = 0)
41193326Sed      : OS(os), Context(C), IndentLevel(Indentation), Helper(helper),
42193326Sed        Policy(Policy) {}
43198092Srdivacky
44193326Sed    void PrintStmt(Stmt *S) {
45193326Sed      PrintStmt(S, Policy.Indentation);
46193326Sed    }
47193326Sed
48193326Sed    void PrintStmt(Stmt *S, int SubIndent) {
49193326Sed      IndentLevel += SubIndent;
50193326Sed      if (S && isa<Expr>(S)) {
51193326Sed        // If this is an expr used in a stmt context, indent and newline it.
52193326Sed        Indent();
53193326Sed        Visit(S);
54193326Sed        OS << ";\n";
55193326Sed      } else if (S) {
56193326Sed        Visit(S);
57193326Sed      } else {
58193326Sed        Indent() << "<<<NULL STATEMENT>>>\n";
59193326Sed      }
60193326Sed      IndentLevel -= SubIndent;
61193326Sed    }
62193326Sed
63193326Sed    void PrintRawCompoundStmt(CompoundStmt *S);
64193326Sed    void PrintRawDecl(Decl *D);
65193326Sed    void PrintRawDeclStmt(DeclStmt *S);
66193326Sed    void PrintRawIfStmt(IfStmt *If);
67193326Sed    void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
68218893Sdim    void PrintCallArgs(CallExpr *E);
69221345Sdim    void PrintRawSEHExceptHandler(SEHExceptStmt *S);
70221345Sdim    void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
71198092Srdivacky
72193326Sed    void PrintExpr(Expr *E) {
73193326Sed      if (E)
74193326Sed        Visit(E);
75193326Sed      else
76193326Sed        OS << "<null expr>";
77193326Sed    }
78198092Srdivacky
79193326Sed    llvm::raw_ostream &Indent(int Delta = 0) {
80193326Sed      for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
81193326Sed        OS << "  ";
82193326Sed      return OS;
83193326Sed    }
84198092Srdivacky
85198092Srdivacky    void Visit(Stmt* S) {
86193326Sed      if (Helper && Helper->handledStmt(S,OS))
87193326Sed          return;
88193326Sed      else StmtVisitor<StmtPrinter>::Visit(S);
89193326Sed    }
90212904Sdim
91218893Sdim    void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
92212904Sdim      Indent() << "<<unknown stmt type>>\n";
93212904Sdim    }
94218893Sdim    void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED {
95212904Sdim      OS << "<<unknown expr type>>";
96212904Sdim    }
97212904Sdim    void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
98198092Srdivacky
99212904Sdim#define ABSTRACT_STMT(CLASS)
100193326Sed#define STMT(CLASS, PARENT) \
101193326Sed    void Visit##CLASS(CLASS *Node);
102208600Srdivacky#include "clang/AST/StmtNodes.inc"
103193326Sed  };
104193326Sed}
105193326Sed
106193326Sed//===----------------------------------------------------------------------===//
107193326Sed//  Stmt printing methods.
108193326Sed//===----------------------------------------------------------------------===//
109193326Sed
110193326Sed/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
111193326Sed/// with no newline after the }.
112193326Sedvoid StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
113193326Sed  OS << "{\n";
114193326Sed  for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
115193326Sed       I != E; ++I)
116193326Sed    PrintStmt(*I);
117198092Srdivacky
118193326Sed  Indent() << "}";
119193326Sed}
120193326Sed
121193326Sedvoid StmtPrinter::PrintRawDecl(Decl *D) {
122195341Sed  D->print(OS, Policy, IndentLevel);
123193326Sed}
124193326Sed
125193326Sedvoid StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
126193326Sed  DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end();
127193326Sed  llvm::SmallVector<Decl*, 2> Decls;
128198092Srdivacky  for ( ; Begin != End; ++Begin)
129193326Sed    Decls.push_back(*Begin);
130193326Sed
131195341Sed  Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
132193326Sed}
133193326Sed
134193326Sedvoid StmtPrinter::VisitNullStmt(NullStmt *Node) {
135193326Sed  Indent() << ";\n";
136193326Sed}
137193326Sed
138193326Sedvoid StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
139193326Sed  Indent();
140193326Sed  PrintRawDeclStmt(Node);
141193326Sed  OS << ";\n";
142193326Sed}
143193326Sed
144193326Sedvoid StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
145193326Sed  Indent();
146193326Sed  PrintRawCompoundStmt(Node);
147193326Sed  OS << "\n";
148193326Sed}
149193326Sed
150193326Sedvoid StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
151193326Sed  Indent(-1) << "case ";
152193326Sed  PrintExpr(Node->getLHS());
153193326Sed  if (Node->getRHS()) {
154193326Sed    OS << " ... ";
155193326Sed    PrintExpr(Node->getRHS());
156193326Sed  }
157193326Sed  OS << ":\n";
158198092Srdivacky
159193326Sed  PrintStmt(Node->getSubStmt(), 0);
160193326Sed}
161193326Sed
162193326Sedvoid StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
163193326Sed  Indent(-1) << "default:\n";
164193326Sed  PrintStmt(Node->getSubStmt(), 0);
165193326Sed}
166193326Sed
167193326Sedvoid StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
168193326Sed  Indent(-1) << Node->getName() << ":\n";
169193326Sed  PrintStmt(Node->getSubStmt(), 0);
170193326Sed}
171193326Sed
172193326Sedvoid StmtPrinter::PrintRawIfStmt(IfStmt *If) {
173193326Sed  OS << "if (";
174193326Sed  PrintExpr(If->getCond());
175193326Sed  OS << ')';
176198092Srdivacky
177193326Sed  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
178193326Sed    OS << ' ';
179193326Sed    PrintRawCompoundStmt(CS);
180193326Sed    OS << (If->getElse() ? ' ' : '\n');
181193326Sed  } else {
182193326Sed    OS << '\n';
183193326Sed    PrintStmt(If->getThen());
184193326Sed    if (If->getElse()) Indent();
185193326Sed  }
186198092Srdivacky
187193326Sed  if (Stmt *Else = If->getElse()) {
188193326Sed    OS << "else";
189198092Srdivacky
190193326Sed    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
191193326Sed      OS << ' ';
192193326Sed      PrintRawCompoundStmt(CS);
193193326Sed      OS << '\n';
194193326Sed    } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
195193326Sed      OS << ' ';
196193326Sed      PrintRawIfStmt(ElseIf);
197193326Sed    } else {
198193326Sed      OS << '\n';
199193326Sed      PrintStmt(If->getElse());
200193326Sed    }
201193326Sed  }
202193326Sed}
203193326Sed
204193326Sedvoid StmtPrinter::VisitIfStmt(IfStmt *If) {
205193326Sed  Indent();
206193326Sed  PrintRawIfStmt(If);
207193326Sed}
208193326Sed
209193326Sedvoid StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
210193326Sed  Indent() << "switch (";
211193326Sed  PrintExpr(Node->getCond());
212193326Sed  OS << ")";
213198092Srdivacky
214193326Sed  // Pretty print compoundstmt bodies (very common).
215193326Sed  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
216193326Sed    OS << " ";
217193326Sed    PrintRawCompoundStmt(CS);
218193326Sed    OS << "\n";
219193326Sed  } else {
220193326Sed    OS << "\n";
221193326Sed    PrintStmt(Node->getBody());
222193326Sed  }
223193326Sed}
224193326Sed
225193326Sedvoid StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
226193326Sed  Indent() << "while (";
227193326Sed  PrintExpr(Node->getCond());
228193326Sed  OS << ")\n";
229193326Sed  PrintStmt(Node->getBody());
230193326Sed}
231193326Sed
232193326Sedvoid StmtPrinter::VisitDoStmt(DoStmt *Node) {
233193326Sed  Indent() << "do ";
234193326Sed  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
235193326Sed    PrintRawCompoundStmt(CS);
236193326Sed    OS << " ";
237193326Sed  } else {
238193326Sed    OS << "\n";
239193326Sed    PrintStmt(Node->getBody());
240193326Sed    Indent();
241193326Sed  }
242198092Srdivacky
243193326Sed  OS << "while (";
244193326Sed  PrintExpr(Node->getCond());
245193326Sed  OS << ");\n";
246193326Sed}
247193326Sed
248193326Sedvoid StmtPrinter::VisitForStmt(ForStmt *Node) {
249193326Sed  Indent() << "for (";
250193326Sed  if (Node->getInit()) {
251193326Sed    if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
252193326Sed      PrintRawDeclStmt(DS);
253193326Sed    else
254193326Sed      PrintExpr(cast<Expr>(Node->getInit()));
255193326Sed  }
256193326Sed  OS << ";";
257193326Sed  if (Node->getCond()) {
258193326Sed    OS << " ";
259193326Sed    PrintExpr(Node->getCond());
260193326Sed  }
261193326Sed  OS << ";";
262193326Sed  if (Node->getInc()) {
263193326Sed    OS << " ";
264193326Sed    PrintExpr(Node->getInc());
265193326Sed  }
266193326Sed  OS << ") ";
267198092Srdivacky
268193326Sed  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
269193326Sed    PrintRawCompoundStmt(CS);
270193326Sed    OS << "\n";
271193326Sed  } else {
272193326Sed    OS << "\n";
273193326Sed    PrintStmt(Node->getBody());
274193326Sed  }
275193326Sed}
276193326Sed
277193326Sedvoid StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
278193326Sed  Indent() << "for (";
279193326Sed  if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
280193326Sed    PrintRawDeclStmt(DS);
281193326Sed  else
282193326Sed    PrintExpr(cast<Expr>(Node->getElement()));
283193326Sed  OS << " in ";
284193326Sed  PrintExpr(Node->getCollection());
285193326Sed  OS << ") ";
286198092Srdivacky
287193326Sed  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
288193326Sed    PrintRawCompoundStmt(CS);
289193326Sed    OS << "\n";
290193326Sed  } else {
291193326Sed    OS << "\n";
292193326Sed    PrintStmt(Node->getBody());
293193326Sed  }
294193326Sed}
295193326Sed
296221345Sdimvoid StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {
297221345Sdim  Indent() << "for (";
298221345Sdim  PrintingPolicy SubPolicy(Policy);
299221345Sdim  SubPolicy.SuppressInitializers = true;
300221345Sdim  Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel);
301221345Sdim  OS << " : ";
302221345Sdim  PrintExpr(Node->getRangeInit());
303221345Sdim  OS << ") {\n";
304221345Sdim  PrintStmt(Node->getBody());
305221345Sdim  Indent() << "}\n";
306221345Sdim}
307221345Sdim
308193326Sedvoid StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
309193326Sed  Indent() << "goto " << Node->getLabel()->getName() << ";\n";
310193326Sed}
311193326Sed
312193326Sedvoid StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
313193326Sed  Indent() << "goto *";
314193326Sed  PrintExpr(Node->getTarget());
315193326Sed  OS << ";\n";
316193326Sed}
317193326Sed
318193326Sedvoid StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
319193326Sed  Indent() << "continue;\n";
320193326Sed}
321193326Sed
322193326Sedvoid StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
323193326Sed  Indent() << "break;\n";
324193326Sed}
325193326Sed
326193326Sed
327193326Sedvoid StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
328193326Sed  Indent() << "return";
329193326Sed  if (Node->getRetValue()) {
330193326Sed    OS << " ";
331193326Sed    PrintExpr(Node->getRetValue());
332193326Sed  }
333193326Sed  OS << ";\n";
334193326Sed}
335193326Sed
336193326Sed
337193326Sedvoid StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
338193326Sed  Indent() << "asm ";
339198092Srdivacky
340193326Sed  if (Node->isVolatile())
341193326Sed    OS << "volatile ";
342198092Srdivacky
343193326Sed  OS << "(";
344193326Sed  VisitStringLiteral(Node->getAsmString());
345198092Srdivacky
346193326Sed  // Outputs
347193326Sed  if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
348193326Sed      Node->getNumClobbers() != 0)
349193326Sed    OS << " : ";
350198092Srdivacky
351193326Sed  for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
352193326Sed    if (i != 0)
353193326Sed      OS << ", ";
354198092Srdivacky
355193326Sed    if (!Node->getOutputName(i).empty()) {
356193326Sed      OS << '[';
357193326Sed      OS << Node->getOutputName(i);
358193326Sed      OS << "] ";
359193326Sed    }
360198092Srdivacky
361193326Sed    VisitStringLiteral(Node->getOutputConstraintLiteral(i));
362193326Sed    OS << " ";
363193326Sed    Visit(Node->getOutputExpr(i));
364193326Sed  }
365198092Srdivacky
366193326Sed  // Inputs
367193326Sed  if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
368193326Sed    OS << " : ";
369198092Srdivacky
370193326Sed  for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
371193326Sed    if (i != 0)
372193326Sed      OS << ", ";
373198092Srdivacky
374193326Sed    if (!Node->getInputName(i).empty()) {
375193326Sed      OS << '[';
376193326Sed      OS << Node->getInputName(i);
377193326Sed      OS << "] ";
378193326Sed    }
379198092Srdivacky
380193326Sed    VisitStringLiteral(Node->getInputConstraintLiteral(i));
381193326Sed    OS << " ";
382193326Sed    Visit(Node->getInputExpr(i));
383193326Sed  }
384198092Srdivacky
385193326Sed  // Clobbers
386193326Sed  if (Node->getNumClobbers() != 0)
387193326Sed    OS << " : ";
388198092Srdivacky
389193326Sed  for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
390193326Sed    if (i != 0)
391193326Sed      OS << ", ";
392198092Srdivacky
393193326Sed    VisitStringLiteral(Node->getClobber(i));
394193326Sed  }
395198092Srdivacky
396193326Sed  OS << ");\n";
397193326Sed}
398193326Sed
399193326Sedvoid StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
400193326Sed  Indent() << "@try";
401193326Sed  if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
402193326Sed    PrintRawCompoundStmt(TS);
403193326Sed    OS << "\n";
404193326Sed  }
405198092Srdivacky
406207619Srdivacky  for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) {
407207619Srdivacky    ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I);
408193326Sed    Indent() << "@catch(";
409193326Sed    if (catchStmt->getCatchParamDecl()) {
410193326Sed      if (Decl *DS = catchStmt->getCatchParamDecl())
411193326Sed        PrintRawDecl(DS);
412193326Sed    }
413193326Sed    OS << ")";
414198092Srdivacky    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
415198092Srdivacky      PrintRawCompoundStmt(CS);
416198092Srdivacky      OS << "\n";
417198092Srdivacky    }
418193326Sed  }
419198092Srdivacky
420198092Srdivacky  if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>(
421198092Srdivacky        Node->getFinallyStmt())) {
422193326Sed    Indent() << "@finally";
423193326Sed    PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
424193326Sed    OS << "\n";
425198092Srdivacky  }
426193326Sed}
427193326Sed
428193326Sedvoid StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
429193326Sed}
430193326Sed
431193326Sedvoid StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
432193326Sed  Indent() << "@catch (...) { /* todo */ } \n";
433193326Sed}
434193326Sed
435193326Sedvoid StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
436193326Sed  Indent() << "@throw";
437193326Sed  if (Node->getThrowExpr()) {
438193326Sed    OS << " ";
439193326Sed    PrintExpr(Node->getThrowExpr());
440193326Sed  }
441193326Sed  OS << ";\n";
442193326Sed}
443193326Sed
444193326Sedvoid StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
445193326Sed  Indent() << "@synchronized (";
446193326Sed  PrintExpr(Node->getSynchExpr());
447193326Sed  OS << ")";
448193326Sed  PrintRawCompoundStmt(Node->getSynchBody());
449193326Sed  OS << "\n";
450193326Sed}
451193326Sed
452224145Sdimvoid StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) {
453224145Sdim  Indent() << "@autoreleasepool";
454224145Sdim  PrintRawCompoundStmt(dyn_cast<CompoundStmt>(Node->getSubStmt()));
455224145Sdim  OS << "\n";
456224145Sdim}
457224145Sdim
458193326Sedvoid StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
459193326Sed  OS << "catch (";
460193326Sed  if (Decl *ExDecl = Node->getExceptionDecl())
461193326Sed    PrintRawDecl(ExDecl);
462193326Sed  else
463193326Sed    OS << "...";
464193326Sed  OS << ") ";
465193326Sed  PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
466193326Sed}
467193326Sed
468193326Sedvoid StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
469193326Sed  Indent();
470193326Sed  PrintRawCXXCatchStmt(Node);
471193326Sed  OS << "\n";
472193326Sed}
473193326Sed
474193326Sedvoid StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
475193326Sed  Indent() << "try ";
476193326Sed  PrintRawCompoundStmt(Node->getTryBlock());
477198092Srdivacky  for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
478193326Sed    OS << " ";
479193326Sed    PrintRawCXXCatchStmt(Node->getHandler(i));
480193326Sed  }
481193326Sed  OS << "\n";
482193326Sed}
483193326Sed
484221345Sdimvoid StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) {
485221345Sdim  Indent() << (Node->getIsCXXTry() ? "try " : "__try ");
486221345Sdim  PrintRawCompoundStmt(Node->getTryBlock());
487221345Sdim  SEHExceptStmt *E = Node->getExceptHandler();
488221345Sdim  SEHFinallyStmt *F = Node->getFinallyHandler();
489221345Sdim  if(E)
490221345Sdim    PrintRawSEHExceptHandler(E);
491221345Sdim  else {
492221345Sdim    assert(F && "Must have a finally block...");
493221345Sdim    PrintRawSEHFinallyStmt(F);
494221345Sdim  }
495221345Sdim  OS << "\n";
496221345Sdim}
497221345Sdim
498221345Sdimvoid StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {
499221345Sdim  OS << "__finally ";
500221345Sdim  PrintRawCompoundStmt(Node->getBlock());
501221345Sdim  OS << "\n";
502221345Sdim}
503221345Sdim
504221345Sdimvoid StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) {
505221345Sdim  OS << "__except (";
506221345Sdim  VisitExpr(Node->getFilterExpr());
507221345Sdim  OS << ")\n";
508221345Sdim  PrintRawCompoundStmt(Node->getBlock());
509221345Sdim  OS << "\n";
510221345Sdim}
511221345Sdim
512221345Sdimvoid StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) {
513221345Sdim  Indent();
514221345Sdim  PrintRawSEHExceptHandler(Node);
515221345Sdim  OS << "\n";
516221345Sdim}
517221345Sdim
518221345Sdimvoid StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {
519221345Sdim  Indent();
520221345Sdim  PrintRawSEHFinallyStmt(Node);
521221345Sdim  OS << "\n";
522221345Sdim}
523221345Sdim
524193326Sed//===----------------------------------------------------------------------===//
525193326Sed//  Expr printing methods.
526193326Sed//===----------------------------------------------------------------------===//
527193326Sed
528193326Sedvoid StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
529198893Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
530198893Srdivacky    Qualifier->print(OS, Policy);
531212904Sdim  OS << Node->getNameInfo();
532212904Sdim  if (Node->hasExplicitTemplateArgs())
533198893Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
534198893Srdivacky                                                    Node->getTemplateArgs(),
535198893Srdivacky                                                    Node->getNumTemplateArgs(),
536198893Srdivacky                                                    Policy);
537193326Sed}
538193326Sed
539199990Srdivackyvoid StmtPrinter::VisitDependentScopeDeclRefExpr(
540199990Srdivacky                                           DependentScopeDeclRefExpr *Node) {
541218893Sdim  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
542218893Sdim    Qualifier->print(OS, Policy);
543212904Sdim  OS << Node->getNameInfo();
544199990Srdivacky  if (Node->hasExplicitTemplateArgs())
545199990Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
546199990Srdivacky                                                   Node->getTemplateArgs(),
547199990Srdivacky                                                   Node->getNumTemplateArgs(),
548199990Srdivacky                                                   Policy);
549193326Sed}
550193326Sed
551199990Srdivackyvoid StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
552195341Sed  if (Node->getQualifier())
553195341Sed    Node->getQualifier()->print(OS, Policy);
554212904Sdim  OS << Node->getNameInfo();
555199990Srdivacky  if (Node->hasExplicitTemplateArgs())
556199990Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
557199990Srdivacky                                                   Node->getTemplateArgs(),
558195341Sed                                                   Node->getNumTemplateArgs(),
559199990Srdivacky                                                   Policy);
560195341Sed}
561195341Sed
562193326Sedvoid StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
563193326Sed  if (Node->getBase()) {
564193326Sed    PrintExpr(Node->getBase());
565193326Sed    OS << (Node->isArrow() ? "->" : ".");
566193326Sed  }
567207619Srdivacky  OS << Node->getDecl();
568193326Sed}
569193326Sed
570193326Sedvoid StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
571218893Sdim  if (Node->isSuperReceiver())
572218893Sdim    OS << "super.";
573218893Sdim  else if (Node->getBase()) {
574193326Sed    PrintExpr(Node->getBase());
575193326Sed    OS << ".";
576193326Sed  }
577193326Sed
578218893Sdim  if (Node->isImplicitProperty())
579218893Sdim    OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
580218893Sdim  else
581218893Sdim    OS << Node->getExplicitProperty()->getName();
582193326Sed}
583193326Sed
584193326Sedvoid StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
585193326Sed  switch (Node->getIdentType()) {
586193326Sed    default:
587193326Sed      assert(0 && "unknown case");
588193326Sed    case PredefinedExpr::Func:
589193326Sed      OS << "__func__";
590193326Sed      break;
591193326Sed    case PredefinedExpr::Function:
592193326Sed      OS << "__FUNCTION__";
593193326Sed      break;
594193326Sed    case PredefinedExpr::PrettyFunction:
595193326Sed      OS << "__PRETTY_FUNCTION__";
596193326Sed      break;
597193326Sed  }
598193326Sed}
599193326Sed
600193326Sedvoid StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
601193326Sed  unsigned value = Node->getValue();
602193326Sed  if (Node->isWide())
603193326Sed    OS << "L";
604193326Sed  switch (value) {
605193326Sed  case '\\':
606193326Sed    OS << "'\\\\'";
607193326Sed    break;
608193326Sed  case '\'':
609193326Sed    OS << "'\\''";
610193326Sed    break;
611193326Sed  case '\a':
612193326Sed    // TODO: K&R: the meaning of '\\a' is different in traditional C
613193326Sed    OS << "'\\a'";
614193326Sed    break;
615193326Sed  case '\b':
616193326Sed    OS << "'\\b'";
617193326Sed    break;
618193326Sed  // Nonstandard escape sequence.
619193326Sed  /*case '\e':
620193326Sed    OS << "'\\e'";
621193326Sed    break;*/
622193326Sed  case '\f':
623193326Sed    OS << "'\\f'";
624193326Sed    break;
625193326Sed  case '\n':
626193326Sed    OS << "'\\n'";
627193326Sed    break;
628193326Sed  case '\r':
629193326Sed    OS << "'\\r'";
630193326Sed    break;
631193326Sed  case '\t':
632193326Sed    OS << "'\\t'";
633193326Sed    break;
634193326Sed  case '\v':
635193326Sed    OS << "'\\v'";
636193326Sed    break;
637193326Sed  default:
638193326Sed    if (value < 256 && isprint(value)) {
639193326Sed      OS << "'" << (char)value << "'";
640193326Sed    } else if (value < 256) {
641193326Sed      OS << "'\\x" << llvm::format("%x", value) << "'";
642193326Sed    } else {
643193326Sed      // FIXME what to really do here?
644193326Sed      OS << value;
645193326Sed    }
646193326Sed  }
647193326Sed}
648193326Sed
649193326Sedvoid StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
650193326Sed  bool isSigned = Node->getType()->isSignedIntegerType();
651193326Sed  OS << Node->getValue().toString(10, isSigned);
652198092Srdivacky
653193326Sed  // Emit suffixes.  Integer literals are always a builtin integer type.
654198092Srdivacky  switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
655193326Sed  default: assert(0 && "Unexpected type for integer literal!");
656193326Sed  case BuiltinType::Int:       break; // no suffix.
657193326Sed  case BuiltinType::UInt:      OS << 'U'; break;
658193326Sed  case BuiltinType::Long:      OS << 'L'; break;
659193326Sed  case BuiltinType::ULong:     OS << "UL"; break;
660193326Sed  case BuiltinType::LongLong:  OS << "LL"; break;
661193326Sed  case BuiltinType::ULongLong: OS << "ULL"; break;
662193326Sed  }
663193326Sed}
664193326Sedvoid StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
665193326Sed  // FIXME: print value more precisely.
666193326Sed  OS << Node->getValueAsApproximateDouble();
667193326Sed}
668193326Sed
669193326Sedvoid StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
670193326Sed  PrintExpr(Node->getSubExpr());
671193326Sed  OS << "i";
672193326Sed}
673193326Sed
674193326Sedvoid StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
675193326Sed  if (Str->isWide()) OS << 'L';
676193326Sed  OS << '"';
677193326Sed
678193326Sed  // FIXME: this doesn't print wstrings right.
679212904Sdim  llvm::StringRef StrData = Str->getString();
680212904Sdim  for (llvm::StringRef::iterator I = StrData.begin(), E = StrData.end();
681212904Sdim                                                             I != E; ++I) {
682212904Sdim    unsigned char Char = *I;
683198092Srdivacky
684193326Sed    switch (Char) {
685193326Sed    default:
686193326Sed      if (isprint(Char))
687193326Sed        OS << (char)Char;
688193326Sed      else  // Output anything hard as an octal escape.
689193326Sed        OS << '\\'
690193326Sed        << (char)('0'+ ((Char >> 6) & 7))
691193326Sed        << (char)('0'+ ((Char >> 3) & 7))
692193326Sed        << (char)('0'+ ((Char >> 0) & 7));
693193326Sed      break;
694193326Sed    // Handle some common non-printable cases to make dumps prettier.
695193326Sed    case '\\': OS << "\\\\"; break;
696193326Sed    case '"': OS << "\\\""; break;
697193326Sed    case '\n': OS << "\\n"; break;
698193326Sed    case '\t': OS << "\\t"; break;
699193326Sed    case '\a': OS << "\\a"; break;
700193326Sed    case '\b': OS << "\\b"; break;
701193326Sed    }
702193326Sed  }
703193326Sed  OS << '"';
704193326Sed}
705193326Sedvoid StmtPrinter::VisitParenExpr(ParenExpr *Node) {
706193326Sed  OS << "(";
707193326Sed  PrintExpr(Node->getSubExpr());
708193326Sed  OS << ")";
709193326Sed}
710193326Sedvoid StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
711193326Sed  if (!Node->isPostfix()) {
712193326Sed    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
713198092Srdivacky
714194613Sed    // Print a space if this is an "identifier operator" like __real, or if
715194613Sed    // it might be concatenated incorrectly like '+'.
716193326Sed    switch (Node->getOpcode()) {
717193326Sed    default: break;
718212904Sdim    case UO_Real:
719212904Sdim    case UO_Imag:
720212904Sdim    case UO_Extension:
721193326Sed      OS << ' ';
722193326Sed      break;
723212904Sdim    case UO_Plus:
724212904Sdim    case UO_Minus:
725194613Sed      if (isa<UnaryOperator>(Node->getSubExpr()))
726194613Sed        OS << ' ';
727194613Sed      break;
728193326Sed    }
729193326Sed  }
730193326Sed  PrintExpr(Node->getSubExpr());
731198092Srdivacky
732193326Sed  if (Node->isPostfix())
733193326Sed    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
734193326Sed}
735193326Sed
736207619Srdivackyvoid StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
737207619Srdivacky  OS << "__builtin_offsetof(";
738210299Sed  OS << Node->getTypeSourceInfo()->getType().getAsString(Policy) << ", ";
739207619Srdivacky  bool PrintedSomething = false;
740207619Srdivacky  for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
741207619Srdivacky    OffsetOfExpr::OffsetOfNode ON = Node->getComponent(i);
742207619Srdivacky    if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Array) {
743207619Srdivacky      // Array node
744207619Srdivacky      OS << "[";
745207619Srdivacky      PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
746207619Srdivacky      OS << "]";
747207619Srdivacky      PrintedSomething = true;
748207619Srdivacky      continue;
749207619Srdivacky    }
750207619Srdivacky
751207619Srdivacky    // Skip implicit base indirections.
752207619Srdivacky    if (ON.getKind() == OffsetOfExpr::OffsetOfNode::Base)
753207619Srdivacky      continue;
754207619Srdivacky
755207619Srdivacky    // Field or identifier node.
756207619Srdivacky    IdentifierInfo *Id = ON.getFieldName();
757207619Srdivacky    if (!Id)
758207619Srdivacky      continue;
759207619Srdivacky
760207619Srdivacky    if (PrintedSomething)
761207619Srdivacky      OS << ".";
762207619Srdivacky    else
763207619Srdivacky      PrintedSomething = true;
764207619Srdivacky    OS << Id->getName();
765207619Srdivacky  }
766207619Srdivacky  OS << ")";
767207619Srdivacky}
768207619Srdivacky
769221345Sdimvoid StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){
770221345Sdim  switch(Node->getKind()) {
771221345Sdim  case UETT_SizeOf:
772221345Sdim    OS << "sizeof";
773221345Sdim    break;
774221345Sdim  case UETT_AlignOf:
775221345Sdim    OS << "__alignof";
776221345Sdim    break;
777221345Sdim  case UETT_VecStep:
778221345Sdim    OS << "vec_step";
779221345Sdim    break;
780221345Sdim  }
781193326Sed  if (Node->isArgumentType())
782210299Sed    OS << "(" << Node->getArgumentType().getAsString(Policy) << ")";
783193326Sed  else {
784193326Sed    OS << " ";
785193326Sed    PrintExpr(Node->getArgumentExpr());
786193326Sed  }
787193326Sed}
788221345Sdim
789221345Sdimvoid StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
790221345Sdim  OS << "_Generic(";
791221345Sdim  PrintExpr(Node->getControllingExpr());
792221345Sdim  for (unsigned i = 0; i != Node->getNumAssocs(); ++i) {
793221345Sdim    OS << ", ";
794221345Sdim    QualType T = Node->getAssocType(i);
795221345Sdim    if (T.isNull())
796221345Sdim      OS << "default";
797221345Sdim    else
798221345Sdim      OS << T.getAsString(Policy);
799221345Sdim    OS << ": ";
800221345Sdim    PrintExpr(Node->getAssocExpr(i));
801221345Sdim  }
802221345Sdim  OS << ")";
803221345Sdim}
804221345Sdim
805193326Sedvoid StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
806193326Sed  PrintExpr(Node->getLHS());
807193326Sed  OS << "[";
808193326Sed  PrintExpr(Node->getRHS());
809193326Sed  OS << "]";
810193326Sed}
811193326Sed
812218893Sdimvoid StmtPrinter::PrintCallArgs(CallExpr *Call) {
813193326Sed  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
814193326Sed    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
815193326Sed      // Don't print any defaulted arguments
816193326Sed      break;
817193326Sed    }
818193326Sed
819193326Sed    if (i) OS << ", ";
820193326Sed    PrintExpr(Call->getArg(i));
821193326Sed  }
822218893Sdim}
823218893Sdim
824218893Sdimvoid StmtPrinter::VisitCallExpr(CallExpr *Call) {
825218893Sdim  PrintExpr(Call->getCallee());
826218893Sdim  OS << "(";
827218893Sdim  PrintCallArgs(Call);
828193326Sed  OS << ")";
829193326Sed}
830193326Sedvoid StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
831193326Sed  // FIXME: Suppress printing implicit bases (like "this")
832193326Sed  PrintExpr(Node->getBase());
833202379Srdivacky  if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
834202379Srdivacky    if (FD->isAnonymousStructOrUnion())
835202379Srdivacky      return;
836193326Sed  OS << (Node->isArrow() ? "->" : ".");
837198092Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
838198092Srdivacky    Qualifier->print(OS, Policy);
839198092Srdivacky
840212904Sdim  OS << Node->getMemberNameInfo();
841198092Srdivacky
842212904Sdim  if (Node->hasExplicitTemplateArgs())
843198092Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
844198092Srdivacky                                                    Node->getTemplateArgs(),
845198092Srdivacky                                                    Node->getNumTemplateArgs(),
846198092Srdivacky                                                                Policy);
847193326Sed}
848198092Srdivackyvoid StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
849198092Srdivacky  PrintExpr(Node->getBase());
850198092Srdivacky  OS << (Node->isArrow() ? "->isa" : ".isa");
851198092Srdivacky}
852198092Srdivacky
853193326Sedvoid StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
854193326Sed  PrintExpr(Node->getBase());
855193326Sed  OS << ".";
856193326Sed  OS << Node->getAccessor().getName();
857193326Sed}
858193326Sedvoid StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
859210299Sed  OS << "(" << Node->getType().getAsString(Policy) << ")";
860193326Sed  PrintExpr(Node->getSubExpr());
861193326Sed}
862193326Sedvoid StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
863210299Sed  OS << "(" << Node->getType().getAsString(Policy) << ")";
864193326Sed  PrintExpr(Node->getInitializer());
865193326Sed}
866193326Sedvoid StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
867193326Sed  // No need to print anything, simply forward to the sub expression.
868193326Sed  PrintExpr(Node->getSubExpr());
869193326Sed}
870193326Sedvoid StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
871193326Sed  PrintExpr(Node->getLHS());
872193326Sed  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
873193326Sed  PrintExpr(Node->getRHS());
874193326Sed}
875193326Sedvoid StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
876193326Sed  PrintExpr(Node->getLHS());
877193326Sed  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
878193326Sed  PrintExpr(Node->getRHS());
879193326Sed}
880193326Sedvoid StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
881193326Sed  PrintExpr(Node->getCond());
882218893Sdim  OS << " ? ";
883218893Sdim  PrintExpr(Node->getLHS());
884218893Sdim  OS << " : ";
885193326Sed  PrintExpr(Node->getRHS());
886193326Sed}
887193326Sed
888193326Sed// GNU extensions.
889193326Sed
890218893Sdimvoid
891218893SdimStmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
892218893Sdim  PrintExpr(Node->getCommon());
893218893Sdim  OS << " ?: ";
894218893Sdim  PrintExpr(Node->getFalseExpr());
895218893Sdim}
896193326Sedvoid StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
897193326Sed  OS << "&&" << Node->getLabel()->getName();
898193326Sed}
899193326Sed
900193326Sedvoid StmtPrinter::VisitStmtExpr(StmtExpr *E) {
901193326Sed  OS << "(";
902193326Sed  PrintRawCompoundStmt(E->getSubStmt());
903193326Sed  OS << ")";
904193326Sed}
905193326Sed
906193326Sedvoid StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
907193326Sed  OS << "__builtin_choose_expr(";
908193326Sed  PrintExpr(Node->getCond());
909193326Sed  OS << ", ";
910193326Sed  PrintExpr(Node->getLHS());
911193326Sed  OS << ", ";
912193326Sed  PrintExpr(Node->getRHS());
913193326Sed  OS << ")";
914193326Sed}
915193326Sed
916193326Sedvoid StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
917193326Sed  OS << "__null";
918193326Sed}
919193326Sed
920193326Sedvoid StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
921193326Sed  OS << "__builtin_shufflevector(";
922193326Sed  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
923193326Sed    if (i) OS << ", ";
924193326Sed    PrintExpr(Node->getExpr(i));
925193326Sed  }
926193326Sed  OS << ")";
927193326Sed}
928193326Sed
929193326Sedvoid StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
930193326Sed  if (Node->getSyntacticForm()) {
931193326Sed    Visit(Node->getSyntacticForm());
932193326Sed    return;
933193326Sed  }
934193326Sed
935193326Sed  OS << "{ ";
936193326Sed  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
937193326Sed    if (i) OS << ", ";
938193326Sed    if (Node->getInit(i))
939193326Sed      PrintExpr(Node->getInit(i));
940193326Sed    else
941193326Sed      OS << "0";
942193326Sed  }
943193326Sed  OS << " }";
944193326Sed}
945193326Sed
946198092Srdivackyvoid StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
947198092Srdivacky  OS << "( ";
948198092Srdivacky  for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
949198092Srdivacky    if (i) OS << ", ";
950198092Srdivacky    PrintExpr(Node->getExpr(i));
951198092Srdivacky  }
952198092Srdivacky  OS << " )";
953198092Srdivacky}
954198092Srdivacky
955193326Sedvoid StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
956193326Sed  for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(),
957193326Sed                      DEnd = Node->designators_end();
958193326Sed       D != DEnd; ++D) {
959193326Sed    if (D->isFieldDesignator()) {
960193326Sed      if (D->getDotLoc().isInvalid())
961193326Sed        OS << D->getFieldName()->getName() << ":";
962193326Sed      else
963193326Sed        OS << "." << D->getFieldName()->getName();
964193326Sed    } else {
965193326Sed      OS << "[";
966193326Sed      if (D->isArrayDesignator()) {
967193326Sed        PrintExpr(Node->getArrayIndex(*D));
968193326Sed      } else {
969193326Sed        PrintExpr(Node->getArrayRangeStart(*D));
970193326Sed        OS << " ... ";
971198092Srdivacky        PrintExpr(Node->getArrayRangeEnd(*D));
972193326Sed      }
973193326Sed      OS << "]";
974193326Sed    }
975193326Sed  }
976193326Sed
977193326Sed  OS << " = ";
978193326Sed  PrintExpr(Node->getInit());
979193326Sed}
980193326Sed
981193326Sedvoid StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
982195341Sed  if (Policy.LangOpts.CPlusPlus)
983193326Sed    OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()";
984193326Sed  else {
985193326Sed    OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")";
986193326Sed    if (Node->getType()->isRecordType())
987193326Sed      OS << "{}";
988193326Sed    else
989193326Sed      OS << 0;
990193326Sed  }
991193326Sed}
992193326Sed
993193326Sedvoid StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
994193326Sed  OS << "__builtin_va_arg(";
995193326Sed  PrintExpr(Node->getSubExpr());
996193326Sed  OS << ", ";
997210299Sed  OS << Node->getType().getAsString(Policy);
998193326Sed  OS << ")";
999193326Sed}
1000193326Sed
1001193326Sed// C++
1002193326Sedvoid StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
1003193326Sed  const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
1004193326Sed    "",
1005193326Sed#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1006193326Sed    Spelling,
1007193326Sed#include "clang/Basic/OperatorKinds.def"
1008193326Sed  };
1009193326Sed
1010193326Sed  OverloadedOperatorKind Kind = Node->getOperator();
1011193326Sed  if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
1012193326Sed    if (Node->getNumArgs() == 1) {
1013193326Sed      OS << OpStrings[Kind] << ' ';
1014193326Sed      PrintExpr(Node->getArg(0));
1015193326Sed    } else {
1016193326Sed      PrintExpr(Node->getArg(0));
1017193326Sed      OS << ' ' << OpStrings[Kind];
1018193326Sed    }
1019193326Sed  } else if (Kind == OO_Call) {
1020193326Sed    PrintExpr(Node->getArg(0));
1021193326Sed    OS << '(';
1022193326Sed    for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
1023193326Sed      if (ArgIdx > 1)
1024193326Sed        OS << ", ";
1025193326Sed      if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
1026193326Sed        PrintExpr(Node->getArg(ArgIdx));
1027193326Sed    }
1028193326Sed    OS << ')';
1029193326Sed  } else if (Kind == OO_Subscript) {
1030193326Sed    PrintExpr(Node->getArg(0));
1031193326Sed    OS << '[';
1032193326Sed    PrintExpr(Node->getArg(1));
1033193326Sed    OS << ']';
1034193326Sed  } else if (Node->getNumArgs() == 1) {
1035193326Sed    OS << OpStrings[Kind] << ' ';
1036193326Sed    PrintExpr(Node->getArg(0));
1037193326Sed  } else if (Node->getNumArgs() == 2) {
1038193326Sed    PrintExpr(Node->getArg(0));
1039193326Sed    OS << ' ' << OpStrings[Kind] << ' ';
1040193326Sed    PrintExpr(Node->getArg(1));
1041193326Sed  } else {
1042193326Sed    assert(false && "unknown overloaded operator");
1043193326Sed  }
1044193326Sed}
1045193326Sed
1046193326Sedvoid StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
1047193326Sed  VisitCallExpr(cast<CallExpr>(Node));
1048193326Sed}
1049193326Sed
1050218893Sdimvoid StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
1051218893Sdim  PrintExpr(Node->getCallee());
1052218893Sdim  OS << "<<<";
1053218893Sdim  PrintCallArgs(Node->getConfig());
1054218893Sdim  OS << ">>>(";
1055218893Sdim  PrintCallArgs(Node);
1056218893Sdim  OS << ")";
1057218893Sdim}
1058218893Sdim
1059193326Sedvoid StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
1060193326Sed  OS << Node->getCastName() << '<';
1061210299Sed  OS << Node->getTypeAsWritten().getAsString(Policy) << ">(";
1062193326Sed  PrintExpr(Node->getSubExpr());
1063193326Sed  OS << ")";
1064193326Sed}
1065193326Sed
1066193326Sedvoid StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
1067193326Sed  VisitCXXNamedCastExpr(Node);
1068193326Sed}
1069193326Sed
1070193326Sedvoid StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
1071193326Sed  VisitCXXNamedCastExpr(Node);
1072193326Sed}
1073193326Sed
1074193326Sedvoid StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
1075193326Sed  VisitCXXNamedCastExpr(Node);
1076193326Sed}
1077193326Sed
1078193326Sedvoid StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
1079193326Sed  VisitCXXNamedCastExpr(Node);
1080193326Sed}
1081193326Sed
1082193326Sedvoid StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
1083193326Sed  OS << "typeid(";
1084193326Sed  if (Node->isTypeOperand()) {
1085210299Sed    OS << Node->getTypeOperand().getAsString(Policy);
1086193326Sed  } else {
1087193326Sed    PrintExpr(Node->getExprOperand());
1088193326Sed  }
1089193326Sed  OS << ")";
1090193326Sed}
1091193326Sed
1092218893Sdimvoid StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
1093218893Sdim  OS << "__uuidof(";
1094218893Sdim  if (Node->isTypeOperand()) {
1095218893Sdim    OS << Node->getTypeOperand().getAsString(Policy);
1096218893Sdim  } else {
1097218893Sdim    PrintExpr(Node->getExprOperand());
1098218893Sdim  }
1099218893Sdim  OS << ")";
1100218893Sdim}
1101218893Sdim
1102193326Sedvoid StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
1103193326Sed  OS << (Node->getValue() ? "true" : "false");
1104193326Sed}
1105193326Sed
1106193326Sedvoid StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
1107193326Sed  OS << "nullptr";
1108193326Sed}
1109193326Sed
1110193326Sedvoid StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
1111193326Sed  OS << "this";
1112193326Sed}
1113193326Sed
1114193326Sedvoid StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
1115193326Sed  if (Node->getSubExpr() == 0)
1116193326Sed    OS << "throw";
1117193326Sed  else {
1118193326Sed    OS << "throw ";
1119193326Sed    PrintExpr(Node->getSubExpr());
1120193326Sed  }
1121193326Sed}
1122193326Sed
1123193326Sedvoid StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
1124193326Sed  // Nothing to print: we picked up the default argument
1125193326Sed}
1126193326Sed
1127193326Sedvoid StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
1128210299Sed  OS << Node->getType().getAsString(Policy);
1129193326Sed  OS << "(";
1130193326Sed  PrintExpr(Node->getSubExpr());
1131193326Sed  OS << ")";
1132193326Sed}
1133193326Sed
1134193326Sedvoid StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
1135193326Sed  PrintExpr(Node->getSubExpr());
1136193326Sed}
1137193326Sed
1138193326Sedvoid StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
1139210299Sed  OS << Node->getType().getAsString(Policy);
1140193326Sed  OS << "(";
1141193326Sed  for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
1142198092Srdivacky                                         ArgEnd = Node->arg_end();
1143193326Sed       Arg != ArgEnd; ++Arg) {
1144193326Sed    if (Arg != Node->arg_begin())
1145193326Sed      OS << ", ";
1146193326Sed    PrintExpr(*Arg);
1147193326Sed  }
1148193326Sed  OS << ")";
1149193326Sed}
1150193326Sed
1151210299Sedvoid StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
1152218893Sdim  if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
1153218893Sdim    OS << TSInfo->getType().getAsString(Policy) << "()";
1154218893Sdim  else
1155218893Sdim    OS << Node->getType().getAsString(Policy) << "()";
1156193326Sed}
1157193326Sed
1158193326Sedvoid StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
1159193326Sed  if (E->isGlobalNew())
1160193326Sed    OS << "::";
1161193326Sed  OS << "new ";
1162193326Sed  unsigned NumPlace = E->getNumPlacementArgs();
1163193326Sed  if (NumPlace > 0) {
1164193326Sed    OS << "(";
1165193326Sed    PrintExpr(E->getPlacementArg(0));
1166193326Sed    for (unsigned i = 1; i < NumPlace; ++i) {
1167193326Sed      OS << ", ";
1168193326Sed      PrintExpr(E->getPlacementArg(i));
1169193326Sed    }
1170193326Sed    OS << ") ";
1171193326Sed  }
1172193326Sed  if (E->isParenTypeId())
1173193326Sed    OS << "(";
1174193326Sed  std::string TypeS;
1175193326Sed  if (Expr *Size = E->getArraySize()) {
1176193326Sed    llvm::raw_string_ostream s(TypeS);
1177193326Sed    Size->printPretty(s, Context, Helper, Policy);
1178193326Sed    s.flush();
1179193326Sed    TypeS = "[" + TypeS + "]";
1180193326Sed  }
1181193326Sed  E->getAllocatedType().getAsStringInternal(TypeS, Policy);
1182193326Sed  OS << TypeS;
1183193326Sed  if (E->isParenTypeId())
1184193326Sed    OS << ")";
1185193326Sed
1186193326Sed  if (E->hasInitializer()) {
1187193326Sed    OS << "(";
1188193326Sed    unsigned NumCons = E->getNumConstructorArgs();
1189193326Sed    if (NumCons > 0) {
1190193326Sed      PrintExpr(E->getConstructorArg(0));
1191193326Sed      for (unsigned i = 1; i < NumCons; ++i) {
1192193326Sed        OS << ", ";
1193193326Sed        PrintExpr(E->getConstructorArg(i));
1194193326Sed      }
1195193326Sed    }
1196193326Sed    OS << ")";
1197193326Sed  }
1198193326Sed}
1199193326Sed
1200193326Sedvoid StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1201193326Sed  if (E->isGlobalDelete())
1202193326Sed    OS << "::";
1203193326Sed  OS << "delete ";
1204193326Sed  if (E->isArrayForm())
1205193326Sed    OS << "[] ";
1206193326Sed  PrintExpr(E->getArgument());
1207193326Sed}
1208193326Sed
1209198092Srdivackyvoid StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1210198092Srdivacky  PrintExpr(E->getBase());
1211198092Srdivacky  if (E->isArrow())
1212198092Srdivacky    OS << "->";
1213198092Srdivacky  else
1214198092Srdivacky    OS << '.';
1215198092Srdivacky  if (E->getQualifier())
1216198092Srdivacky    E->getQualifier()->print(OS, Policy);
1217198092Srdivacky
1218198092Srdivacky  std::string TypeS;
1219204643Srdivacky  if (IdentifierInfo *II = E->getDestroyedTypeIdentifier())
1220204643Srdivacky    OS << II->getName();
1221204643Srdivacky  else
1222204643Srdivacky    E->getDestroyedType().getAsStringInternal(TypeS, Policy);
1223198092Srdivacky  OS << TypeS;
1224198092Srdivacky}
1225198092Srdivacky
1226193326Sedvoid StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
1227218893Sdim  for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
1228218893Sdim    if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
1229218893Sdim      // Don't print any defaulted arguments
1230218893Sdim      break;
1231218893Sdim    }
1232218893Sdim
1233218893Sdim    if (i) OS << ", ";
1234218893Sdim    PrintExpr(E->getArg(i));
1235202379Srdivacky  }
1236193326Sed}
1237193326Sed
1238218893Sdimvoid StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
1239193326Sed  // Just forward to the sub expression.
1240193326Sed  PrintExpr(E->getSubExpr());
1241193326Sed}
1242193326Sed
1243198092Srdivackyvoid
1244193326SedStmtPrinter::VisitCXXUnresolvedConstructExpr(
1245193326Sed                                           CXXUnresolvedConstructExpr *Node) {
1246210299Sed  OS << Node->getTypeAsWritten().getAsString(Policy);
1247193326Sed  OS << "(";
1248193326Sed  for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
1249198092Srdivacky                                             ArgEnd = Node->arg_end();
1250193326Sed       Arg != ArgEnd; ++Arg) {
1251193326Sed    if (Arg != Node->arg_begin())
1252193326Sed      OS << ", ";
1253193326Sed    PrintExpr(*Arg);
1254193326Sed  }
1255193326Sed  OS << ")";
1256193326Sed}
1257193326Sed
1258199990Srdivackyvoid StmtPrinter::VisitCXXDependentScopeMemberExpr(
1259199990Srdivacky                                         CXXDependentScopeMemberExpr *Node) {
1260200583Srdivacky  if (!Node->isImplicitAccess()) {
1261200583Srdivacky    PrintExpr(Node->getBase());
1262200583Srdivacky    OS << (Node->isArrow() ? "->" : ".");
1263200583Srdivacky  }
1264198092Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1265198092Srdivacky    Qualifier->print(OS, Policy);
1266200583Srdivacky  else if (Node->hasExplicitTemplateArgs())
1267198092Srdivacky    // FIXME: Track use of "template" keyword explicitly?
1268198092Srdivacky    OS << "template ";
1269198092Srdivacky
1270212904Sdim  OS << Node->getMemberNameInfo();
1271198092Srdivacky
1272200583Srdivacky  if (Node->hasExplicitTemplateArgs()) {
1273198092Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1274198092Srdivacky                                                    Node->getTemplateArgs(),
1275198092Srdivacky                                                    Node->getNumTemplateArgs(),
1276198092Srdivacky                                                    Policy);
1277198092Srdivacky  }
1278193326Sed}
1279193326Sed
1280199990Srdivackyvoid StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
1281200583Srdivacky  if (!Node->isImplicitAccess()) {
1282200583Srdivacky    PrintExpr(Node->getBase());
1283200583Srdivacky    OS << (Node->isArrow() ? "->" : ".");
1284200583Srdivacky  }
1285199990Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1286199990Srdivacky    Qualifier->print(OS, Policy);
1287199990Srdivacky
1288199990Srdivacky  // FIXME: this might originally have been written with 'template'
1289199990Srdivacky
1290212904Sdim  OS << Node->getMemberNameInfo();
1291199990Srdivacky
1292199990Srdivacky  if (Node->hasExplicitTemplateArgs()) {
1293199990Srdivacky    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1294199990Srdivacky                                                    Node->getTemplateArgs(),
1295199990Srdivacky                                                    Node->getNumTemplateArgs(),
1296199990Srdivacky                                                    Policy);
1297199990Srdivacky  }
1298199990Srdivacky}
1299199990Srdivacky
1300193326Sedstatic const char *getTypeTraitName(UnaryTypeTrait UTT) {
1301193326Sed  switch (UTT) {
1302193326Sed  case UTT_HasNothrowAssign:      return "__has_nothrow_assign";
1303193326Sed  case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
1304221345Sdim  case UTT_HasNothrowCopy:          return "__has_nothrow_copy";
1305193326Sed  case UTT_HasTrivialAssign:      return "__has_trivial_assign";
1306223017Sdim  case UTT_HasTrivialDefaultConstructor: return "__has_trivial_constructor";
1307221345Sdim  case UTT_HasTrivialCopy:          return "__has_trivial_copy";
1308193326Sed  case UTT_HasTrivialDestructor:  return "__has_trivial_destructor";
1309193326Sed  case UTT_HasVirtualDestructor:  return "__has_virtual_destructor";
1310193326Sed  case UTT_IsAbstract:            return "__is_abstract";
1311221345Sdim  case UTT_IsArithmetic:            return "__is_arithmetic";
1312221345Sdim  case UTT_IsArray:                 return "__is_array";
1313193326Sed  case UTT_IsClass:               return "__is_class";
1314221345Sdim  case UTT_IsCompleteType:          return "__is_complete_type";
1315221345Sdim  case UTT_IsCompound:              return "__is_compound";
1316221345Sdim  case UTT_IsConst:                 return "__is_const";
1317193326Sed  case UTT_IsEmpty:               return "__is_empty";
1318193326Sed  case UTT_IsEnum:                return "__is_enum";
1319221345Sdim  case UTT_IsFloatingPoint:         return "__is_floating_point";
1320221345Sdim  case UTT_IsFunction:              return "__is_function";
1321221345Sdim  case UTT_IsFundamental:           return "__is_fundamental";
1322221345Sdim  case UTT_IsIntegral:              return "__is_integral";
1323221345Sdim  case UTT_IsLiteral:               return "__is_literal";
1324221345Sdim  case UTT_IsLvalueReference:       return "__is_lvalue_reference";
1325221345Sdim  case UTT_IsMemberFunctionPointer: return "__is_member_function_pointer";
1326221345Sdim  case UTT_IsMemberObjectPointer:   return "__is_member_object_pointer";
1327221345Sdim  case UTT_IsMemberPointer:         return "__is_member_pointer";
1328221345Sdim  case UTT_IsObject:                return "__is_object";
1329193326Sed  case UTT_IsPOD:                 return "__is_pod";
1330221345Sdim  case UTT_IsPointer:               return "__is_pointer";
1331193326Sed  case UTT_IsPolymorphic:         return "__is_polymorphic";
1332221345Sdim  case UTT_IsReference:             return "__is_reference";
1333221345Sdim  case UTT_IsRvalueReference:       return "__is_rvalue_reference";
1334221345Sdim  case UTT_IsScalar:                return "__is_scalar";
1335221345Sdim  case UTT_IsSigned:                return "__is_signed";
1336221345Sdim  case UTT_IsStandardLayout:        return "__is_standard_layout";
1337221345Sdim  case UTT_IsTrivial:               return "__is_trivial";
1338223017Sdim  case UTT_IsTriviallyCopyable:     return "__is_trivially_copyable";
1339193326Sed  case UTT_IsUnion:               return "__is_union";
1340221345Sdim  case UTT_IsUnsigned:              return "__is_unsigned";
1341221345Sdim  case UTT_IsVoid:                  return "__is_void";
1342221345Sdim  case UTT_IsVolatile:              return "__is_volatile";
1343193326Sed  }
1344221345Sdim  llvm_unreachable("Type trait not covered by switch statement");
1345193326Sed}
1346193326Sed
1347218893Sdimstatic const char *getTypeTraitName(BinaryTypeTrait BTT) {
1348218893Sdim  switch (BTT) {
1349218893Sdim  case BTT_IsBaseOf:         return "__is_base_of";
1350221345Sdim  case BTT_IsConvertible:    return "__is_convertible";
1351221345Sdim  case BTT_IsSame:           return "__is_same";
1352218893Sdim  case BTT_TypeCompatible:   return "__builtin_types_compatible_p";
1353218893Sdim  case BTT_IsConvertibleTo:  return "__is_convertible_to";
1354218893Sdim  }
1355221345Sdim  llvm_unreachable("Binary type trait not covered by switch");
1356218893Sdim}
1357218893Sdim
1358221345Sdimstatic const char *getTypeTraitName(ArrayTypeTrait ATT) {
1359221345Sdim  switch (ATT) {
1360221345Sdim  case ATT_ArrayRank:        return "__array_rank";
1361221345Sdim  case ATT_ArrayExtent:      return "__array_extent";
1362221345Sdim  }
1363221345Sdim  llvm_unreachable("Array type trait not covered by switch");
1364221345Sdim}
1365221345Sdim
1366221345Sdimstatic const char *getExpressionTraitName(ExpressionTrait ET) {
1367221345Sdim  switch (ET) {
1368221345Sdim  case ET_IsLValueExpr:      return "__is_lvalue_expr";
1369221345Sdim  case ET_IsRValueExpr:      return "__is_rvalue_expr";
1370221345Sdim  }
1371221345Sdim  llvm_unreachable("Expression type trait not covered by switch");
1372221345Sdim}
1373221345Sdim
1374193326Sedvoid StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1375193326Sed  OS << getTypeTraitName(E->getTrait()) << "("
1376210299Sed     << E->getQueriedType().getAsString(Policy) << ")";
1377193326Sed}
1378193326Sed
1379218893Sdimvoid StmtPrinter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
1380218893Sdim  OS << getTypeTraitName(E->getTrait()) << "("
1381218893Sdim     << E->getLhsType().getAsString(Policy) << ","
1382218893Sdim     << E->getRhsType().getAsString(Policy) << ")";
1383218893Sdim}
1384218893Sdim
1385221345Sdimvoid StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
1386221345Sdim  OS << getTypeTraitName(E->getTrait()) << "("
1387221345Sdim     << E->getQueriedType().getAsString(Policy) << ")";
1388221345Sdim}
1389221345Sdim
1390221345Sdimvoid StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
1391221345Sdim    OS << getExpressionTraitName(E->getTrait()) << "(";
1392221345Sdim    PrintExpr(E->getQueriedExpression());
1393221345Sdim    OS << ")";
1394221345Sdim}
1395221345Sdim
1396218893Sdimvoid StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
1397218893Sdim  OS << "noexcept(";
1398218893Sdim  PrintExpr(E->getOperand());
1399218893Sdim  OS << ")";
1400218893Sdim}
1401218893Sdim
1402218893Sdimvoid StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
1403218893Sdim  PrintExpr(E->getPattern());
1404218893Sdim  OS << "...";
1405218893Sdim}
1406218893Sdim
1407218893Sdimvoid StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
1408218893Sdim  OS << "sizeof...(" << E->getPack()->getNameAsString() << ")";
1409218893Sdim}
1410218893Sdim
1411218893Sdimvoid StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
1412218893Sdim                                       SubstNonTypeTemplateParmPackExpr *Node) {
1413218893Sdim  OS << Node->getParameterPack()->getNameAsString();
1414218893Sdim}
1415218893Sdim
1416224145Sdimvoid StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
1417224145Sdim                                       SubstNonTypeTemplateParmExpr *Node) {
1418224145Sdim  Visit(Node->getReplacement());
1419224145Sdim}
1420224145Sdim
1421224145Sdimvoid StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
1422224145Sdim  PrintExpr(Node->GetTemporaryExpr());
1423224145Sdim}
1424224145Sdim
1425198092Srdivacky// Obj-C
1426193326Sed
1427193326Sedvoid StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
1428193326Sed  OS << "@";
1429193326Sed  VisitStringLiteral(Node->getString());
1430193326Sed}
1431193326Sed
1432193326Sedvoid StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
1433210299Sed  OS << "@encode(" << Node->getEncodedType().getAsString(Policy) << ')';
1434193326Sed}
1435193326Sed
1436193326Sedvoid StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
1437193326Sed  OS << "@selector(" << Node->getSelector().getAsString() << ')';
1438193326Sed}
1439193326Sed
1440193326Sedvoid StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
1441207619Srdivacky  OS << "@protocol(" << Node->getProtocol() << ')';
1442193326Sed}
1443193326Sed
1444193326Sedvoid StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
1445193326Sed  OS << "[";
1446207619Srdivacky  switch (Mess->getReceiverKind()) {
1447207619Srdivacky  case ObjCMessageExpr::Instance:
1448207619Srdivacky    PrintExpr(Mess->getInstanceReceiver());
1449207619Srdivacky    break;
1450207619Srdivacky
1451207619Srdivacky  case ObjCMessageExpr::Class:
1452207619Srdivacky    OS << Mess->getClassReceiver().getAsString(Policy);
1453207619Srdivacky    break;
1454207619Srdivacky
1455207619Srdivacky  case ObjCMessageExpr::SuperInstance:
1456207619Srdivacky  case ObjCMessageExpr::SuperClass:
1457207619Srdivacky    OS << "Super";
1458207619Srdivacky    break;
1459207619Srdivacky  }
1460207619Srdivacky
1461193326Sed  OS << ' ';
1462193326Sed  Selector selector = Mess->getSelector();
1463193326Sed  if (selector.isUnarySelector()) {
1464218893Sdim    OS << selector.getNameForSlot(0);
1465193326Sed  } else {
1466193326Sed    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
1467193326Sed      if (i < selector.getNumArgs()) {
1468193326Sed        if (i > 0) OS << ' ';
1469193326Sed        if (selector.getIdentifierInfoForSlot(i))
1470193326Sed          OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
1471193326Sed        else
1472193326Sed           OS << ":";
1473193326Sed      }
1474193326Sed      else OS << ", "; // Handle variadic methods.
1475198092Srdivacky
1476193326Sed      PrintExpr(Mess->getArg(i));
1477193326Sed    }
1478193326Sed  }
1479193326Sed  OS << "]";
1480193326Sed}
1481193326Sed
1482224145Sdimvoid
1483224145SdimStmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
1484224145Sdim  PrintExpr(E->getSubExpr());
1485224145Sdim}
1486193326Sed
1487224145Sdimvoid
1488224145SdimStmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
1489224145Sdim  OS << "(" << E->getBridgeKindName() << E->getType().getAsString(Policy)
1490224145Sdim     << ")";
1491224145Sdim  PrintExpr(E->getSubExpr());
1492224145Sdim}
1493224145Sdim
1494193326Sedvoid StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
1495193326Sed  BlockDecl *BD = Node->getBlockDecl();
1496193326Sed  OS << "^";
1497198092Srdivacky
1498193326Sed  const FunctionType *AFT = Node->getFunctionType();
1499198092Srdivacky
1500193326Sed  if (isa<FunctionNoProtoType>(AFT)) {
1501193326Sed    OS << "()";
1502193326Sed  } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
1503193326Sed    OS << '(';
1504193326Sed    std::string ParamStr;
1505193326Sed    for (BlockDecl::param_iterator AI = BD->param_begin(),
1506193326Sed         E = BD->param_end(); AI != E; ++AI) {
1507193326Sed      if (AI != BD->param_begin()) OS << ", ";
1508193326Sed      ParamStr = (*AI)->getNameAsString();
1509193326Sed      (*AI)->getType().getAsStringInternal(ParamStr, Policy);
1510193326Sed      OS << ParamStr;
1511193326Sed    }
1512198092Srdivacky
1513193326Sed    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
1514193326Sed    if (FT->isVariadic()) {
1515193326Sed      if (!BD->param_empty()) OS << ", ";
1516193326Sed      OS << "...";
1517193326Sed    }
1518193326Sed    OS << ')';
1519193326Sed  }
1520193326Sed}
1521193326Sed
1522193326Sedvoid StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
1523207619Srdivacky  OS << Node->getDecl();
1524193326Sed}
1525218893Sdim
1526218893Sdimvoid StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {}
1527218893Sdim
1528223017Sdimvoid StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
1529223017Sdim  OS << "__builtin_astype(";
1530223017Sdim  PrintExpr(Node->getSrcExpr());
1531223017Sdim  OS << ", " << Node->getType().getAsString();
1532223017Sdim  OS << ")";
1533223017Sdim}
1534223017Sdim
1535193326Sed//===----------------------------------------------------------------------===//
1536193326Sed// Stmt method implementations
1537193326Sed//===----------------------------------------------------------------------===//
1538193326Sed
1539193326Sedvoid Stmt::dumpPretty(ASTContext& Context) const {
1540195341Sed  printPretty(llvm::errs(), Context, 0,
1541195341Sed              PrintingPolicy(Context.getLangOptions()));
1542193326Sed}
1543193326Sed
1544193326Sedvoid Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,
1545193326Sed                       PrinterHelper* Helper,
1546193326Sed                       const PrintingPolicy &Policy,
1547193326Sed                       unsigned Indentation) const {
1548193326Sed  if (this == 0) {
1549193326Sed    OS << "<NULL>";
1550193326Sed    return;
1551193326Sed  }
1552193326Sed
1553198398Srdivacky  if (Policy.Dump && &Context) {
1554212904Sdim    dump(OS, Context.getSourceManager());
1555193326Sed    return;
1556193326Sed  }
1557198092Srdivacky
1558193326Sed  StmtPrinter P(OS, Context, Helper, Policy, Indentation);
1559193326Sed  P.Visit(const_cast<Stmt*>(this));
1560193326Sed}
1561193326Sed
1562193326Sed//===----------------------------------------------------------------------===//
1563193326Sed// PrinterHelper
1564193326Sed//===----------------------------------------------------------------------===//
1565193326Sed
1566193326Sed// Implement virtual destructor.
1567193326SedPrinterHelper::~PrinterHelper() {}
1568