StmtPrinter.cpp revision 202379
152419Sjulian//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===//
252419Sjulian//
352419Sjulian//                     The LLVM Compiler Infrastructure
452419Sjulian//
552419Sjulian// This file is distributed under the University of Illinois Open Source
652419Sjulian// License. See LICENSE.TXT for details.
752419Sjulian//
852419Sjulian//===----------------------------------------------------------------------===//
952419Sjulian//
1052419Sjulian// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
1152419Sjulian// pretty print the AST back out to C code.
1252419Sjulian//
1352419Sjulian//===----------------------------------------------------------------------===//
1452419Sjulian
1552419Sjulian#include "clang/AST/StmtVisitor.h"
1652419Sjulian#include "clang/AST/DeclCXX.h"
1752419Sjulian#include "clang/AST/DeclObjC.h"
1852419Sjulian#include "clang/AST/PrettyPrinter.h"
1952419Sjulian#include "llvm/Support/Format.h"
2052419Sjulianusing namespace clang;
2152419Sjulian
2252419Sjulian//===----------------------------------------------------------------------===//
2352419Sjulian// StmtPrinter Visitor
2452419Sjulian//===----------------------------------------------------------------------===//
2552419Sjulian
2652419Sjuliannamespace  {
2752419Sjulian  class StmtPrinter : public StmtVisitor<StmtPrinter> {
2852419Sjulian    llvm::raw_ostream &OS;
2952419Sjulian    ASTContext &Context;
3052419Sjulian    unsigned IndentLevel;
3152419Sjulian    clang::PrinterHelper* Helper;
3252419Sjulian    PrintingPolicy Policy;
3352419Sjulian
3452419Sjulian  public:
3552419Sjulian    StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper,
3652419Sjulian                const PrintingPolicy &Policy,
3752419Sjulian                unsigned Indentation = 0)
3852419Sjulian      : OS(os), Context(C), IndentLevel(Indentation), Helper(helper),
3952419Sjulian        Policy(Policy) {}
4052419Sjulian
4152419Sjulian    void PrintStmt(Stmt *S) {
4252419Sjulian      PrintStmt(S, Policy.Indentation);
4352419Sjulian    }
4453913Sarchie
4552419Sjulian    void PrintStmt(Stmt *S, int SubIndent) {
4653913Sarchie      IndentLevel += SubIndent;
4753913Sarchie      if (S && isa<Expr>(S)) {
4853913Sarchie        // If this is an expr used in a stmt context, indent and newline it.
4953913Sarchie        Indent();
5052419Sjulian        Visit(S);
5152419Sjulian        OS << ";\n";
5252419Sjulian      } else if (S) {
5352419Sjulian        Visit(S);
5452419Sjulian      } else {
5552419Sjulian        Indent() << "<<<NULL STATEMENT>>>\n";
5653913Sarchie      }
5753913Sarchie      IndentLevel -= SubIndent;
5852419Sjulian    }
5953913Sarchie
6053913Sarchie    void PrintRawCompoundStmt(CompoundStmt *S);
6152419Sjulian    void PrintRawDecl(Decl *D);
6253913Sarchie    void PrintRawDeclStmt(DeclStmt *S);
6353913Sarchie    void PrintRawIfStmt(IfStmt *If);
6453913Sarchie    void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
6552419Sjulian
6653913Sarchie    void PrintExpr(Expr *E) {
6753913Sarchie      if (E)
6853913Sarchie        Visit(E);
6953913Sarchie      else
7053913Sarchie        OS << "<null expr>";
7152419Sjulian    }
7253913Sarchie
7353913Sarchie    llvm::raw_ostream &Indent(int Delta = 0) {
7453913Sarchie      for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
7553913Sarchie        OS << "  ";
7653913Sarchie      return OS;
7753913Sarchie    }
7853913Sarchie
7953913Sarchie    bool PrintOffsetOfDesignator(Expr *E);
8053913Sarchie    void VisitUnaryOffsetOf(UnaryOperator *Node);
8153913Sarchie
8253913Sarchie    void Visit(Stmt* S) {
8352419Sjulian      if (Helper && Helper->handledStmt(S,OS))
8452419Sjulian          return;
8552419Sjulian      else StmtVisitor<StmtPrinter>::Visit(S);
8652419Sjulian    }
8752419Sjulian
8852419Sjulian    void VisitStmt(Stmt *Node);
8952419Sjulian#define STMT(CLASS, PARENT) \
9052419Sjulian    void Visit##CLASS(CLASS *Node);
9152419Sjulian#include "clang/AST/StmtNodes.def"
9252419Sjulian  };
9352419Sjulian}
9453913Sarchie
9553913Sarchie//===----------------------------------------------------------------------===//
9653913Sarchie//  Stmt printing methods.
9753913Sarchie//===----------------------------------------------------------------------===//
9853913Sarchie
9953913Sarchievoid StmtPrinter::VisitStmt(Stmt *Node) {
10053913Sarchie  Indent() << "<<unknown stmt type>>\n";
10153913Sarchie}
10253913Sarchie
10353913Sarchie/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
10453913Sarchie/// with no newline after the }.
10553913Sarchievoid StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
10654098Sarchie  OS << "{\n";
10753913Sarchie  for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
10853913Sarchie       I != E; ++I)
10953913Sarchie    PrintStmt(*I);
11053913Sarchie
11153913Sarchie  Indent() << "}";
11253913Sarchie}
11353913Sarchie
11453913Sarchievoid StmtPrinter::PrintRawDecl(Decl *D) {
11553913Sarchie  D->print(OS, Policy, IndentLevel);
11653913Sarchie}
11753913Sarchie
11853913Sarchievoid StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
11953913Sarchie  DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end();
12053913Sarchie  llvm::SmallVector<Decl*, 2> Decls;
12153913Sarchie  for ( ; Begin != End; ++Begin)
12253913Sarchie    Decls.push_back(*Begin);
12353913Sarchie
12453913Sarchie  Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
12553913Sarchie}
12653913Sarchie
12753913Sarchievoid StmtPrinter::VisitNullStmt(NullStmt *Node) {
12853913Sarchie  Indent() << ";\n";
12953913Sarchie}
13053913Sarchie
13153913Sarchievoid StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
13253913Sarchie  Indent();
13353913Sarchie  PrintRawDeclStmt(Node);
13452419Sjulian  OS << ";\n";
13552419Sjulian}
13652419Sjulian
13752419Sjulianvoid StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
13852419Sjulian  Indent();
13952419Sjulian  PrintRawCompoundStmt(Node);
14052419Sjulian  OS << "\n";
14152419Sjulian}
14252419Sjulian
14352419Sjulianvoid StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
14452419Sjulian  Indent(-1) << "case ";
14552419Sjulian  PrintExpr(Node->getLHS());
14652419Sjulian  if (Node->getRHS()) {
14752419Sjulian    OS << " ... ";
14852419Sjulian    PrintExpr(Node->getRHS());
14952419Sjulian  }
15052419Sjulian  OS << ":\n";
15152419Sjulian
15252419Sjulian  PrintStmt(Node->getSubStmt(), 0);
15352419Sjulian}
15452419Sjulian
15552419Sjulianvoid StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
15652419Sjulian  Indent(-1) << "default:\n";
15752419Sjulian  PrintStmt(Node->getSubStmt(), 0);
15852419Sjulian}
15952419Sjulian
16052419Sjulianvoid StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
16152419Sjulian  Indent(-1) << Node->getName() << ":\n";
16252419Sjulian  PrintStmt(Node->getSubStmt(), 0);
16352419Sjulian}
16453913Sarchie
16552419Sjulianvoid StmtPrinter::PrintRawIfStmt(IfStmt *If) {
16652419Sjulian  OS << "if (";
16752419Sjulian  PrintExpr(If->getCond());
16852419Sjulian  OS << ')';
16952419Sjulian
17053913Sarchie  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
17153913Sarchie    OS << ' ';
17252419Sjulian    PrintRawCompoundStmt(CS);
17352419Sjulian    OS << (If->getElse() ? ' ' : '\n');
17452419Sjulian  } else {
17552419Sjulian    OS << '\n';
17653913Sarchie    PrintStmt(If->getThen());
17752419Sjulian    if (If->getElse()) Indent();
17853913Sarchie  }
17953913Sarchie
18053913Sarchie  if (Stmt *Else = If->getElse()) {
18153913Sarchie    OS << "else";
18253913Sarchie
18353913Sarchie    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
18453913Sarchie      OS << ' ';
18553913Sarchie      PrintRawCompoundStmt(CS);
18653913Sarchie      OS << '\n';
18753913Sarchie    } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
18852419Sjulian      OS << ' ';
18952419Sjulian      PrintRawIfStmt(ElseIf);
19052419Sjulian    } else {
19152419Sjulian      OS << '\n';
19253913Sarchie      PrintStmt(If->getElse());
19353913Sarchie    }
19453913Sarchie  }
19552419Sjulian}
19653913Sarchie
19753913Sarchievoid StmtPrinter::VisitIfStmt(IfStmt *If) {
19853913Sarchie  Indent();
19952419Sjulian  PrintRawIfStmt(If);
20053913Sarchie}
20153913Sarchie
20253913Sarchievoid StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
20353913Sarchie  Indent() << "switch (";
20452419Sjulian  PrintExpr(Node->getCond());
20553913Sarchie  OS << ")";
20653913Sarchie
20753913Sarchie  // Pretty print compoundstmt bodies (very common).
20852419Sjulian  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
20953913Sarchie    OS << " ";
21053913Sarchie    PrintRawCompoundStmt(CS);
21153913Sarchie    OS << "\n";
21253913Sarchie  } else {
21353913Sarchie    OS << "\n";
21453913Sarchie    PrintStmt(Node->getBody());
21553913Sarchie  }
21653913Sarchie}
21753913Sarchie
21853913Sarchievoid StmtPrinter::VisitSwitchCase(SwitchCase*) {
21953913Sarchie  assert(0 && "SwitchCase is an abstract class");
22053913Sarchie}
22153913Sarchie
22253913Sarchievoid StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
22353913Sarchie  Indent() << "while (";
22453913Sarchie  PrintExpr(Node->getCond());
22553913Sarchie  OS << ")\n";
22653913Sarchie  PrintStmt(Node->getBody());
22753913Sarchie}
22853913Sarchie
22953913Sarchievoid StmtPrinter::VisitDoStmt(DoStmt *Node) {
23053913Sarchie  Indent() << "do ";
23153913Sarchie  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
23253913Sarchie    PrintRawCompoundStmt(CS);
23353913Sarchie    OS << " ";
23453913Sarchie  } else {
23553913Sarchie    OS << "\n";
23653913Sarchie    PrintStmt(Node->getBody());
23753913Sarchie    Indent();
23853913Sarchie  }
23953913Sarchie
24052419Sjulian  OS << "while (";
24152419Sjulian  PrintExpr(Node->getCond());
24252419Sjulian  OS << ");\n";
24353913Sarchie}
24452419Sjulian
24553913Sarchievoid StmtPrinter::VisitForStmt(ForStmt *Node) {
24653913Sarchie  Indent() << "for (";
24752419Sjulian  if (Node->getInit()) {
24853913Sarchie    if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
24952419Sjulian      PrintRawDeclStmt(DS);
25053913Sarchie    else
25153913Sarchie      PrintExpr(cast<Expr>(Node->getInit()));
25253913Sarchie  }
25352419Sjulian  OS << ";";
25453913Sarchie  if (Node->getCond()) {
25552419Sjulian    OS << " ";
25652419Sjulian    PrintExpr(Node->getCond());
25752419Sjulian  }
25852419Sjulian  OS << ";";
25952419Sjulian  if (Node->getInc()) {
26052419Sjulian    OS << " ";
26153913Sarchie    PrintExpr(Node->getInc());
26252419Sjulian  }
26352419Sjulian  OS << ") ";
26452419Sjulian
26552419Sjulian  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
26652419Sjulian    PrintRawCompoundStmt(CS);
26752419Sjulian    OS << "\n";
26852419Sjulian  } else {
26952419Sjulian    OS << "\n";
27052419Sjulian    PrintStmt(Node->getBody());
27152419Sjulian  }
27252419Sjulian}
27352419Sjulian
27452419Sjulianvoid StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
27552419Sjulian  Indent() << "for (";
27652419Sjulian  if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
27752419Sjulian    PrintRawDeclStmt(DS);
27852419Sjulian  else
27952419Sjulian    PrintExpr(cast<Expr>(Node->getElement()));
28052419Sjulian  OS << " in ";
28152419Sjulian  PrintExpr(Node->getCollection());
28252419Sjulian  OS << ") ";
28352419Sjulian
28452419Sjulian  if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
28552419Sjulian    PrintRawCompoundStmt(CS);
28652419Sjulian    OS << "\n";
28752419Sjulian  } else {
28852419Sjulian    OS << "\n";
28952419Sjulian    PrintStmt(Node->getBody());
29052419Sjulian  }
29152419Sjulian}
29252419Sjulian
29352419Sjulianvoid StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
29452419Sjulian  Indent() << "goto " << Node->getLabel()->getName() << ";\n";
29552419Sjulian}
29652419Sjulian
29752419Sjulianvoid StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
298  Indent() << "goto *";
299  PrintExpr(Node->getTarget());
300  OS << ";\n";
301}
302
303void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
304  Indent() << "continue;\n";
305}
306
307void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
308  Indent() << "break;\n";
309}
310
311
312void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
313  Indent() << "return";
314  if (Node->getRetValue()) {
315    OS << " ";
316    PrintExpr(Node->getRetValue());
317  }
318  OS << ";\n";
319}
320
321
322void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
323  Indent() << "asm ";
324
325  if (Node->isVolatile())
326    OS << "volatile ";
327
328  OS << "(";
329  VisitStringLiteral(Node->getAsmString());
330
331  // Outputs
332  if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
333      Node->getNumClobbers() != 0)
334    OS << " : ";
335
336  for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
337    if (i != 0)
338      OS << ", ";
339
340    if (!Node->getOutputName(i).empty()) {
341      OS << '[';
342      OS << Node->getOutputName(i);
343      OS << "] ";
344    }
345
346    VisitStringLiteral(Node->getOutputConstraintLiteral(i));
347    OS << " ";
348    Visit(Node->getOutputExpr(i));
349  }
350
351  // Inputs
352  if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
353    OS << " : ";
354
355  for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
356    if (i != 0)
357      OS << ", ";
358
359    if (!Node->getInputName(i).empty()) {
360      OS << '[';
361      OS << Node->getInputName(i);
362      OS << "] ";
363    }
364
365    VisitStringLiteral(Node->getInputConstraintLiteral(i));
366    OS << " ";
367    Visit(Node->getInputExpr(i));
368  }
369
370  // Clobbers
371  if (Node->getNumClobbers() != 0)
372    OS << " : ";
373
374  for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
375    if (i != 0)
376      OS << ", ";
377
378    VisitStringLiteral(Node->getClobber(i));
379  }
380
381  OS << ");\n";
382}
383
384void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
385  Indent() << "@try";
386  if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
387    PrintRawCompoundStmt(TS);
388    OS << "\n";
389  }
390
391  for (ObjCAtCatchStmt *catchStmt =
392         static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts());
393       catchStmt;
394       catchStmt =
395         static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) {
396    Indent() << "@catch(";
397    if (catchStmt->getCatchParamDecl()) {
398      if (Decl *DS = catchStmt->getCatchParamDecl())
399        PrintRawDecl(DS);
400    }
401    OS << ")";
402    if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
403      PrintRawCompoundStmt(CS);
404      OS << "\n";
405    }
406  }
407
408  if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>(
409        Node->getFinallyStmt())) {
410    Indent() << "@finally";
411    PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
412    OS << "\n";
413  }
414}
415
416void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
417}
418
419void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
420  Indent() << "@catch (...) { /* todo */ } \n";
421}
422
423void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
424  Indent() << "@throw";
425  if (Node->getThrowExpr()) {
426    OS << " ";
427    PrintExpr(Node->getThrowExpr());
428  }
429  OS << ";\n";
430}
431
432void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
433  Indent() << "@synchronized (";
434  PrintExpr(Node->getSynchExpr());
435  OS << ")";
436  PrintRawCompoundStmt(Node->getSynchBody());
437  OS << "\n";
438}
439
440void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
441  OS << "catch (";
442  if (Decl *ExDecl = Node->getExceptionDecl())
443    PrintRawDecl(ExDecl);
444  else
445    OS << "...";
446  OS << ") ";
447  PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
448}
449
450void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
451  Indent();
452  PrintRawCXXCatchStmt(Node);
453  OS << "\n";
454}
455
456void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
457  Indent() << "try ";
458  PrintRawCompoundStmt(Node->getTryBlock());
459  for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
460    OS << " ";
461    PrintRawCXXCatchStmt(Node->getHandler(i));
462  }
463  OS << "\n";
464}
465
466//===----------------------------------------------------------------------===//
467//  Expr printing methods.
468//===----------------------------------------------------------------------===//
469
470void StmtPrinter::VisitExpr(Expr *Node) {
471  OS << "<<unknown expr type>>";
472}
473
474void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
475  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
476    Qualifier->print(OS, Policy);
477  OS << Node->getDecl()->getNameAsString();
478  if (Node->hasExplicitTemplateArgumentList())
479    OS << TemplateSpecializationType::PrintTemplateArgumentList(
480                                                    Node->getTemplateArgs(),
481                                                    Node->getNumTemplateArgs(),
482                                                    Policy);
483}
484
485void StmtPrinter::VisitDependentScopeDeclRefExpr(
486                                           DependentScopeDeclRefExpr *Node) {
487  Node->getQualifier()->print(OS, Policy);
488  OS << Node->getDeclName().getAsString();
489  if (Node->hasExplicitTemplateArgs())
490    OS << TemplateSpecializationType::PrintTemplateArgumentList(
491                                                   Node->getTemplateArgs(),
492                                                   Node->getNumTemplateArgs(),
493                                                   Policy);
494}
495
496void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
497  if (Node->getQualifier())
498    Node->getQualifier()->print(OS, Policy);
499  OS << Node->getName().getAsString();
500  if (Node->hasExplicitTemplateArgs())
501    OS << TemplateSpecializationType::PrintTemplateArgumentList(
502                                                   Node->getTemplateArgs(),
503                                                   Node->getNumTemplateArgs(),
504                                                   Policy);
505}
506
507void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
508  if (Node->getBase()) {
509    PrintExpr(Node->getBase());
510    OS << (Node->isArrow() ? "->" : ".");
511  }
512  OS << Node->getDecl()->getNameAsString();
513}
514
515void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
516  if (Node->getBase()) {
517    PrintExpr(Node->getBase());
518    OS << ".";
519  }
520  OS << Node->getProperty()->getNameAsCString();
521}
522
523void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr(
524                                        ObjCImplicitSetterGetterRefExpr *Node) {
525  if (Node->getBase()) {
526    PrintExpr(Node->getBase());
527    OS << ".";
528  }
529  if (Node->getGetterMethod())
530    OS << Node->getGetterMethod()->getNameAsString();
531
532}
533
534void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
535  switch (Node->getIdentType()) {
536    default:
537      assert(0 && "unknown case");
538    case PredefinedExpr::Func:
539      OS << "__func__";
540      break;
541    case PredefinedExpr::Function:
542      OS << "__FUNCTION__";
543      break;
544    case PredefinedExpr::PrettyFunction:
545      OS << "__PRETTY_FUNCTION__";
546      break;
547  }
548}
549
550void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
551  unsigned value = Node->getValue();
552  if (Node->isWide())
553    OS << "L";
554  switch (value) {
555  case '\\':
556    OS << "'\\\\'";
557    break;
558  case '\'':
559    OS << "'\\''";
560    break;
561  case '\a':
562    // TODO: K&R: the meaning of '\\a' is different in traditional C
563    OS << "'\\a'";
564    break;
565  case '\b':
566    OS << "'\\b'";
567    break;
568  // Nonstandard escape sequence.
569  /*case '\e':
570    OS << "'\\e'";
571    break;*/
572  case '\f':
573    OS << "'\\f'";
574    break;
575  case '\n':
576    OS << "'\\n'";
577    break;
578  case '\r':
579    OS << "'\\r'";
580    break;
581  case '\t':
582    OS << "'\\t'";
583    break;
584  case '\v':
585    OS << "'\\v'";
586    break;
587  default:
588    if (value < 256 && isprint(value)) {
589      OS << "'" << (char)value << "'";
590    } else if (value < 256) {
591      OS << "'\\x" << llvm::format("%x", value) << "'";
592    } else {
593      // FIXME what to really do here?
594      OS << value;
595    }
596  }
597}
598
599void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
600  bool isSigned = Node->getType()->isSignedIntegerType();
601  OS << Node->getValue().toString(10, isSigned);
602
603  // Emit suffixes.  Integer literals are always a builtin integer type.
604  switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
605  default: assert(0 && "Unexpected type for integer literal!");
606  case BuiltinType::Int:       break; // no suffix.
607  case BuiltinType::UInt:      OS << 'U'; break;
608  case BuiltinType::Long:      OS << 'L'; break;
609  case BuiltinType::ULong:     OS << "UL"; break;
610  case BuiltinType::LongLong:  OS << "LL"; break;
611  case BuiltinType::ULongLong: OS << "ULL"; break;
612  }
613}
614void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
615  // FIXME: print value more precisely.
616  OS << Node->getValueAsApproximateDouble();
617}
618
619void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
620  PrintExpr(Node->getSubExpr());
621  OS << "i";
622}
623
624void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
625  if (Str->isWide()) OS << 'L';
626  OS << '"';
627
628  // FIXME: this doesn't print wstrings right.
629  for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
630    unsigned char Char = Str->getStrData()[i];
631
632    switch (Char) {
633    default:
634      if (isprint(Char))
635        OS << (char)Char;
636      else  // Output anything hard as an octal escape.
637        OS << '\\'
638        << (char)('0'+ ((Char >> 6) & 7))
639        << (char)('0'+ ((Char >> 3) & 7))
640        << (char)('0'+ ((Char >> 0) & 7));
641      break;
642    // Handle some common non-printable cases to make dumps prettier.
643    case '\\': OS << "\\\\"; break;
644    case '"': OS << "\\\""; break;
645    case '\n': OS << "\\n"; break;
646    case '\t': OS << "\\t"; break;
647    case '\a': OS << "\\a"; break;
648    case '\b': OS << "\\b"; break;
649    }
650  }
651  OS << '"';
652}
653void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
654  OS << "(";
655  PrintExpr(Node->getSubExpr());
656  OS << ")";
657}
658void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
659  if (!Node->isPostfix()) {
660    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
661
662    // Print a space if this is an "identifier operator" like __real, or if
663    // it might be concatenated incorrectly like '+'.
664    switch (Node->getOpcode()) {
665    default: break;
666    case UnaryOperator::Real:
667    case UnaryOperator::Imag:
668    case UnaryOperator::Extension:
669      OS << ' ';
670      break;
671    case UnaryOperator::Plus:
672    case UnaryOperator::Minus:
673      if (isa<UnaryOperator>(Node->getSubExpr()))
674        OS << ' ';
675      break;
676    }
677  }
678  PrintExpr(Node->getSubExpr());
679
680  if (Node->isPostfix())
681    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
682}
683
684bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
685  if (isa<UnaryOperator>(E)) {
686    // Base case, print the type and comma.
687    OS << E->getType().getAsString() << ", ";
688    return true;
689  } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
690    PrintOffsetOfDesignator(ASE->getLHS());
691    OS << "[";
692    PrintExpr(ASE->getRHS());
693    OS << "]";
694    return false;
695  } else {
696    MemberExpr *ME = cast<MemberExpr>(E);
697    bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
698    OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getNameAsString();
699    return false;
700  }
701}
702
703void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
704  OS << "__builtin_offsetof(";
705  PrintOffsetOfDesignator(Node->getSubExpr());
706  OS << ")";
707}
708
709void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
710  OS << (Node->isSizeOf() ? "sizeof" : "__alignof");
711  if (Node->isArgumentType())
712    OS << "(" << Node->getArgumentType().getAsString() << ")";
713  else {
714    OS << " ";
715    PrintExpr(Node->getArgumentExpr());
716  }
717}
718void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
719  PrintExpr(Node->getLHS());
720  OS << "[";
721  PrintExpr(Node->getRHS());
722  OS << "]";
723}
724
725void StmtPrinter::VisitCallExpr(CallExpr *Call) {
726  PrintExpr(Call->getCallee());
727  OS << "(";
728  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
729    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
730      // Don't print any defaulted arguments
731      break;
732    }
733
734    if (i) OS << ", ";
735    PrintExpr(Call->getArg(i));
736  }
737  OS << ")";
738}
739void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
740  // FIXME: Suppress printing implicit bases (like "this")
741  PrintExpr(Node->getBase());
742  if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
743    if (FD->isAnonymousStructOrUnion())
744      return;
745  OS << (Node->isArrow() ? "->" : ".");
746  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
747    Qualifier->print(OS, Policy);
748
749  OS << Node->getMemberDecl()->getNameAsString();
750
751  if (Node->hasExplicitTemplateArgumentList())
752    OS << TemplateSpecializationType::PrintTemplateArgumentList(
753                                                    Node->getTemplateArgs(),
754                                                    Node->getNumTemplateArgs(),
755                                                                Policy);
756}
757void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
758  PrintExpr(Node->getBase());
759  OS << (Node->isArrow() ? "->isa" : ".isa");
760}
761
762void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
763  PrintExpr(Node->getBase());
764  OS << ".";
765  OS << Node->getAccessor().getName();
766}
767void StmtPrinter::VisitCastExpr(CastExpr *) {
768  assert(0 && "CastExpr is an abstract class");
769}
770void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) {
771  assert(0 && "ExplicitCastExpr is an abstract class");
772}
773void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
774  OS << "(" << Node->getType().getAsString() << ")";
775  PrintExpr(Node->getSubExpr());
776}
777void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
778  OS << "(" << Node->getType().getAsString() << ")";
779  PrintExpr(Node->getInitializer());
780}
781void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
782  // No need to print anything, simply forward to the sub expression.
783  PrintExpr(Node->getSubExpr());
784}
785void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
786  PrintExpr(Node->getLHS());
787  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
788  PrintExpr(Node->getRHS());
789}
790void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
791  PrintExpr(Node->getLHS());
792  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
793  PrintExpr(Node->getRHS());
794}
795void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
796  PrintExpr(Node->getCond());
797
798  if (Node->getLHS()) {
799    OS << " ? ";
800    PrintExpr(Node->getLHS());
801    OS << " : ";
802  }
803  else { // Handle GCC extension where LHS can be NULL.
804    OS << " ?: ";
805  }
806
807  PrintExpr(Node->getRHS());
808}
809
810// GNU extensions.
811
812void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
813  OS << "&&" << Node->getLabel()->getName();
814}
815
816void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
817  OS << "(";
818  PrintRawCompoundStmt(E->getSubStmt());
819  OS << ")";
820}
821
822void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
823  OS << "__builtin_types_compatible_p(";
824  OS << Node->getArgType1().getAsString() << ",";
825  OS << Node->getArgType2().getAsString() << ")";
826}
827
828void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
829  OS << "__builtin_choose_expr(";
830  PrintExpr(Node->getCond());
831  OS << ", ";
832  PrintExpr(Node->getLHS());
833  OS << ", ";
834  PrintExpr(Node->getRHS());
835  OS << ")";
836}
837
838void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
839  OS << "__null";
840}
841
842void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
843  OS << "__builtin_shufflevector(";
844  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
845    if (i) OS << ", ";
846    PrintExpr(Node->getExpr(i));
847  }
848  OS << ")";
849}
850
851void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
852  if (Node->getSyntacticForm()) {
853    Visit(Node->getSyntacticForm());
854    return;
855  }
856
857  OS << "{ ";
858  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
859    if (i) OS << ", ";
860    if (Node->getInit(i))
861      PrintExpr(Node->getInit(i));
862    else
863      OS << "0";
864  }
865  OS << " }";
866}
867
868void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
869  OS << "( ";
870  for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
871    if (i) OS << ", ";
872    PrintExpr(Node->getExpr(i));
873  }
874  OS << " )";
875}
876
877void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
878  for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(),
879                      DEnd = Node->designators_end();
880       D != DEnd; ++D) {
881    if (D->isFieldDesignator()) {
882      if (D->getDotLoc().isInvalid())
883        OS << D->getFieldName()->getName() << ":";
884      else
885        OS << "." << D->getFieldName()->getName();
886    } else {
887      OS << "[";
888      if (D->isArrayDesignator()) {
889        PrintExpr(Node->getArrayIndex(*D));
890      } else {
891        PrintExpr(Node->getArrayRangeStart(*D));
892        OS << " ... ";
893        PrintExpr(Node->getArrayRangeEnd(*D));
894      }
895      OS << "]";
896    }
897  }
898
899  OS << " = ";
900  PrintExpr(Node->getInit());
901}
902
903void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
904  if (Policy.LangOpts.CPlusPlus)
905    OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()";
906  else {
907    OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")";
908    if (Node->getType()->isRecordType())
909      OS << "{}";
910    else
911      OS << 0;
912  }
913}
914
915void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
916  OS << "__builtin_va_arg(";
917  PrintExpr(Node->getSubExpr());
918  OS << ", ";
919  OS << Node->getType().getAsString();
920  OS << ")";
921}
922
923// C++
924void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
925  const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
926    "",
927#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
928    Spelling,
929#include "clang/Basic/OperatorKinds.def"
930  };
931
932  OverloadedOperatorKind Kind = Node->getOperator();
933  if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
934    if (Node->getNumArgs() == 1) {
935      OS << OpStrings[Kind] << ' ';
936      PrintExpr(Node->getArg(0));
937    } else {
938      PrintExpr(Node->getArg(0));
939      OS << ' ' << OpStrings[Kind];
940    }
941  } else if (Kind == OO_Call) {
942    PrintExpr(Node->getArg(0));
943    OS << '(';
944    for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
945      if (ArgIdx > 1)
946        OS << ", ";
947      if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
948        PrintExpr(Node->getArg(ArgIdx));
949    }
950    OS << ')';
951  } else if (Kind == OO_Subscript) {
952    PrintExpr(Node->getArg(0));
953    OS << '[';
954    PrintExpr(Node->getArg(1));
955    OS << ']';
956  } else if (Node->getNumArgs() == 1) {
957    OS << OpStrings[Kind] << ' ';
958    PrintExpr(Node->getArg(0));
959  } else if (Node->getNumArgs() == 2) {
960    PrintExpr(Node->getArg(0));
961    OS << ' ' << OpStrings[Kind] << ' ';
962    PrintExpr(Node->getArg(1));
963  } else {
964    assert(false && "unknown overloaded operator");
965  }
966}
967
968void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
969  VisitCallExpr(cast<CallExpr>(Node));
970}
971
972void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
973  OS << Node->getCastName() << '<';
974  OS << Node->getTypeAsWritten().getAsString() << ">(";
975  PrintExpr(Node->getSubExpr());
976  OS << ")";
977}
978
979void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
980  VisitCXXNamedCastExpr(Node);
981}
982
983void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
984  VisitCXXNamedCastExpr(Node);
985}
986
987void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
988  VisitCXXNamedCastExpr(Node);
989}
990
991void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
992  VisitCXXNamedCastExpr(Node);
993}
994
995void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
996  OS << "typeid(";
997  if (Node->isTypeOperand()) {
998    OS << Node->getTypeOperand().getAsString();
999  } else {
1000    PrintExpr(Node->getExprOperand());
1001  }
1002  OS << ")";
1003}
1004
1005void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
1006  OS << (Node->getValue() ? "true" : "false");
1007}
1008
1009void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
1010  OS << "nullptr";
1011}
1012
1013void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
1014  OS << "this";
1015}
1016
1017void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
1018  if (Node->getSubExpr() == 0)
1019    OS << "throw";
1020  else {
1021    OS << "throw ";
1022    PrintExpr(Node->getSubExpr());
1023  }
1024}
1025
1026void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
1027  // Nothing to print: we picked up the default argument
1028}
1029
1030void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
1031  OS << Node->getType().getAsString();
1032  OS << "(";
1033  PrintExpr(Node->getSubExpr());
1034  OS << ")";
1035}
1036
1037void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
1038  PrintExpr(Node->getSubExpr());
1039}
1040
1041void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
1042  OS << Node->getType().getAsString();
1043  OS << "(";
1044  for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
1045                                         ArgEnd = Node->arg_end();
1046       Arg != ArgEnd; ++Arg) {
1047    if (Arg != Node->arg_begin())
1048      OS << ", ";
1049    PrintExpr(*Arg);
1050  }
1051  OS << ")";
1052}
1053
1054void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
1055  OS << Node->getType().getAsString() << "()";
1056}
1057
1058void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
1059  if (E->isGlobalNew())
1060    OS << "::";
1061  OS << "new ";
1062  unsigned NumPlace = E->getNumPlacementArgs();
1063  if (NumPlace > 0) {
1064    OS << "(";
1065    PrintExpr(E->getPlacementArg(0));
1066    for (unsigned i = 1; i < NumPlace; ++i) {
1067      OS << ", ";
1068      PrintExpr(E->getPlacementArg(i));
1069    }
1070    OS << ") ";
1071  }
1072  if (E->isParenTypeId())
1073    OS << "(";
1074  std::string TypeS;
1075  if (Expr *Size = E->getArraySize()) {
1076    llvm::raw_string_ostream s(TypeS);
1077    Size->printPretty(s, Context, Helper, Policy);
1078    s.flush();
1079    TypeS = "[" + TypeS + "]";
1080  }
1081  E->getAllocatedType().getAsStringInternal(TypeS, Policy);
1082  OS << TypeS;
1083  if (E->isParenTypeId())
1084    OS << ")";
1085
1086  if (E->hasInitializer()) {
1087    OS << "(";
1088    unsigned NumCons = E->getNumConstructorArgs();
1089    if (NumCons > 0) {
1090      PrintExpr(E->getConstructorArg(0));
1091      for (unsigned i = 1; i < NumCons; ++i) {
1092        OS << ", ";
1093        PrintExpr(E->getConstructorArg(i));
1094      }
1095    }
1096    OS << ")";
1097  }
1098}
1099
1100void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1101  if (E->isGlobalDelete())
1102    OS << "::";
1103  OS << "delete ";
1104  if (E->isArrayForm())
1105    OS << "[] ";
1106  PrintExpr(E->getArgument());
1107}
1108
1109void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1110  PrintExpr(E->getBase());
1111  if (E->isArrow())
1112    OS << "->";
1113  else
1114    OS << '.';
1115  if (E->getQualifier())
1116    E->getQualifier()->print(OS, Policy);
1117
1118  std::string TypeS;
1119  E->getDestroyedType().getAsStringInternal(TypeS, Policy);
1120  OS << TypeS;
1121}
1122
1123void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
1124  // FIXME. For now we just print a trivial constructor call expression,
1125  // constructing its first argument object.
1126  if (E->getNumArgs() == 1) {
1127    CXXConstructorDecl *CD = E->getConstructor();
1128    if (CD->isTrivial())
1129      PrintExpr(E->getArg(0));
1130  }
1131  // Nothing to print.
1132}
1133
1134void StmtPrinter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
1135  // Just forward to the sub expression.
1136  PrintExpr(E->getSubExpr());
1137}
1138
1139void
1140StmtPrinter::VisitCXXUnresolvedConstructExpr(
1141                                           CXXUnresolvedConstructExpr *Node) {
1142  OS << Node->getTypeAsWritten().getAsString();
1143  OS << "(";
1144  for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
1145                                             ArgEnd = Node->arg_end();
1146       Arg != ArgEnd; ++Arg) {
1147    if (Arg != Node->arg_begin())
1148      OS << ", ";
1149    PrintExpr(*Arg);
1150  }
1151  OS << ")";
1152}
1153
1154void StmtPrinter::VisitCXXDependentScopeMemberExpr(
1155                                         CXXDependentScopeMemberExpr *Node) {
1156  if (!Node->isImplicitAccess()) {
1157    PrintExpr(Node->getBase());
1158    OS << (Node->isArrow() ? "->" : ".");
1159  }
1160  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1161    Qualifier->print(OS, Policy);
1162  else if (Node->hasExplicitTemplateArgs())
1163    // FIXME: Track use of "template" keyword explicitly?
1164    OS << "template ";
1165
1166  OS << Node->getMember().getAsString();
1167
1168  if (Node->hasExplicitTemplateArgs()) {
1169    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1170                                                    Node->getTemplateArgs(),
1171                                                    Node->getNumTemplateArgs(),
1172                                                    Policy);
1173  }
1174}
1175
1176void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
1177  if (!Node->isImplicitAccess()) {
1178    PrintExpr(Node->getBase());
1179    OS << (Node->isArrow() ? "->" : ".");
1180  }
1181  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1182    Qualifier->print(OS, Policy);
1183
1184  // FIXME: this might originally have been written with 'template'
1185
1186  OS << Node->getMemberName().getAsString();
1187
1188  if (Node->hasExplicitTemplateArgs()) {
1189    OS << TemplateSpecializationType::PrintTemplateArgumentList(
1190                                                    Node->getTemplateArgs(),
1191                                                    Node->getNumTemplateArgs(),
1192                                                    Policy);
1193  }
1194}
1195
1196static const char *getTypeTraitName(UnaryTypeTrait UTT) {
1197  switch (UTT) {
1198  default: assert(false && "Unknown type trait");
1199  case UTT_HasNothrowAssign:      return "__has_nothrow_assign";
1200  case UTT_HasNothrowCopy:        return "__has_nothrow_copy";
1201  case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
1202  case UTT_HasTrivialAssign:      return "__has_trivial_assign";
1203  case UTT_HasTrivialCopy:        return "__has_trivial_copy";
1204  case UTT_HasTrivialConstructor: return "__has_trivial_constructor";
1205  case UTT_HasTrivialDestructor:  return "__has_trivial_destructor";
1206  case UTT_HasVirtualDestructor:  return "__has_virtual_destructor";
1207  case UTT_IsAbstract:            return "__is_abstract";
1208  case UTT_IsClass:               return "__is_class";
1209  case UTT_IsEmpty:               return "__is_empty";
1210  case UTT_IsEnum:                return "__is_enum";
1211  case UTT_IsPOD:                 return "__is_pod";
1212  case UTT_IsPolymorphic:         return "__is_polymorphic";
1213  case UTT_IsUnion:               return "__is_union";
1214  }
1215}
1216
1217void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1218  OS << getTypeTraitName(E->getTrait()) << "("
1219     << E->getQueriedType().getAsString() << ")";
1220}
1221
1222// Obj-C
1223
1224void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
1225  OS << "@";
1226  VisitStringLiteral(Node->getString());
1227}
1228
1229void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
1230  OS << "@encode(" << Node->getEncodedType().getAsString() << ')';
1231}
1232
1233void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
1234  OS << "@selector(" << Node->getSelector().getAsString() << ')';
1235}
1236
1237void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
1238  OS << "@protocol(" << Node->getProtocol()->getNameAsString() << ')';
1239}
1240
1241void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
1242  OS << "[";
1243  Expr *receiver = Mess->getReceiver();
1244  if (receiver) PrintExpr(receiver);
1245  else OS << Mess->getClassName()->getName();
1246  OS << ' ';
1247  Selector selector = Mess->getSelector();
1248  if (selector.isUnarySelector()) {
1249    OS << selector.getIdentifierInfoForSlot(0)->getName();
1250  } else {
1251    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
1252      if (i < selector.getNumArgs()) {
1253        if (i > 0) OS << ' ';
1254        if (selector.getIdentifierInfoForSlot(i))
1255          OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
1256        else
1257           OS << ":";
1258      }
1259      else OS << ", "; // Handle variadic methods.
1260
1261      PrintExpr(Mess->getArg(i));
1262    }
1263  }
1264  OS << "]";
1265}
1266
1267void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) {
1268  OS << "super";
1269}
1270
1271void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
1272  BlockDecl *BD = Node->getBlockDecl();
1273  OS << "^";
1274
1275  const FunctionType *AFT = Node->getFunctionType();
1276
1277  if (isa<FunctionNoProtoType>(AFT)) {
1278    OS << "()";
1279  } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
1280    OS << '(';
1281    std::string ParamStr;
1282    for (BlockDecl::param_iterator AI = BD->param_begin(),
1283         E = BD->param_end(); AI != E; ++AI) {
1284      if (AI != BD->param_begin()) OS << ", ";
1285      ParamStr = (*AI)->getNameAsString();
1286      (*AI)->getType().getAsStringInternal(ParamStr, Policy);
1287      OS << ParamStr;
1288    }
1289
1290    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
1291    if (FT->isVariadic()) {
1292      if (!BD->param_empty()) OS << ", ";
1293      OS << "...";
1294    }
1295    OS << ')';
1296  }
1297}
1298
1299void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
1300  OS << Node->getDecl()->getNameAsString();
1301}
1302//===----------------------------------------------------------------------===//
1303// Stmt method implementations
1304//===----------------------------------------------------------------------===//
1305
1306void Stmt::dumpPretty(ASTContext& Context) const {
1307  printPretty(llvm::errs(), Context, 0,
1308              PrintingPolicy(Context.getLangOptions()));
1309}
1310
1311void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,
1312                       PrinterHelper* Helper,
1313                       const PrintingPolicy &Policy,
1314                       unsigned Indentation) const {
1315  if (this == 0) {
1316    OS << "<NULL>";
1317    return;
1318  }
1319
1320  if (Policy.Dump && &Context) {
1321    dump(Context.getSourceManager());
1322    return;
1323  }
1324
1325  StmtPrinter P(OS, Context, Helper, Policy, Indentation);
1326  P.Visit(const_cast<Stmt*>(this));
1327}
1328
1329//===----------------------------------------------------------------------===//
1330// PrinterHelper
1331//===----------------------------------------------------------------------===//
1332
1333// Implement virtual destructor.
1334PrinterHelper::~PrinterHelper() {}
1335