1249261Sdim//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
2249261Sdim//
3249261Sdim//                     The LLVM Compiler Infrastructure
4249261Sdim//
5249261Sdim// This file is distributed under the University of Illinois Open Source
6249261Sdim// License. See LICENSE.TXT for details.
7249261Sdim//
8249261Sdim//===----------------------------------------------------------------------===//
9249261Sdim//
10249261Sdim// This file implements the AST dump methods, which dump out the
11249261Sdim// AST in a form that exposes type details and other fields.
12249261Sdim//
13249261Sdim//===----------------------------------------------------------------------===//
14249261Sdim
15249261Sdim#include "clang/AST/ASTContext.h"
16249261Sdim#include "clang/AST/Attr.h"
17249261Sdim#include "clang/AST/CommentVisitor.h"
18249261Sdim#include "clang/AST/DeclCXX.h"
19249261Sdim#include "clang/AST/DeclObjC.h"
20249261Sdim#include "clang/AST/DeclVisitor.h"
21249261Sdim#include "clang/AST/StmtVisitor.h"
22249261Sdim#include "clang/Basic/Module.h"
23249261Sdim#include "clang/Basic/SourceManager.h"
24249261Sdim#include "llvm/Support/raw_ostream.h"
25249261Sdimusing namespace clang;
26249261Sdimusing namespace clang::comments;
27249261Sdim
28249261Sdim//===----------------------------------------------------------------------===//
29249261Sdim// ASTDumper Visitor
30249261Sdim//===----------------------------------------------------------------------===//
31249261Sdim
32249261Sdimnamespace  {
33249261Sdim  // Colors used for various parts of the AST dump
34249261Sdim
35249261Sdim  struct TerminalColor {
36249261Sdim    raw_ostream::Colors Color;
37249261Sdim    bool Bold;
38249261Sdim  };
39249261Sdim
40249261Sdim  // Decl kind names (VarDecl, FunctionDecl, etc)
41249261Sdim  static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true };
42249261Sdim  // Attr names (CleanupAttr, GuardedByAttr, etc)
43249261Sdim  static const TerminalColor AttrColor = { raw_ostream::BLUE, true };
44249261Sdim  // Statement names (DeclStmt, ImplicitCastExpr, etc)
45249261Sdim  static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true };
46249261Sdim  // Comment names (FullComment, ParagraphComment, TextComment, etc)
47249261Sdim  static const TerminalColor CommentColor = { raw_ostream::YELLOW, true };
48249261Sdim
49249261Sdim  // Type names (int, float, etc, plus user defined types)
50249261Sdim  static const TerminalColor TypeColor = { raw_ostream::GREEN, false };
51249261Sdim
52249261Sdim  // Pointer address
53249261Sdim  static const TerminalColor AddressColor = { raw_ostream::YELLOW, false };
54249261Sdim  // Source locations
55249261Sdim  static const TerminalColor LocationColor = { raw_ostream::YELLOW, false };
56249261Sdim
57249261Sdim  // lvalue/xvalue
58249261Sdim  static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false };
59249261Sdim  // bitfield/objcproperty/objcsubscript/vectorcomponent
60249261Sdim  static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false };
61249261Sdim
62249261Sdim  // Null statements
63249261Sdim  static const TerminalColor NullColor = { raw_ostream::BLUE, false };
64249261Sdim
65249261Sdim  // CastKind from CastExpr's
66249261Sdim  static const TerminalColor CastColor = { raw_ostream::RED, false };
67249261Sdim
68249261Sdim  // Value of the statement
69249261Sdim  static const TerminalColor ValueColor = { raw_ostream::CYAN, true };
70249261Sdim  // Decl names
71249261Sdim  static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true };
72249261Sdim
73249261Sdim  // Indents ( `, -. | )
74249261Sdim  static const TerminalColor IndentColor = { raw_ostream::BLUE, false };
75249261Sdim
76249261Sdim  class ASTDumper
77249261Sdim      : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>,
78249261Sdim        public ConstCommentVisitor<ASTDumper> {
79249261Sdim    raw_ostream &OS;
80249261Sdim    const CommandTraits *Traits;
81249261Sdim    const SourceManager *SM;
82249261Sdim    bool IsFirstLine;
83249261Sdim
84249261Sdim    // Indicates whether more child are expected at the current tree depth
85249261Sdim    enum IndentType { IT_Child, IT_LastChild };
86249261Sdim
87249261Sdim    /// Indents[i] indicates if another child exists at level i.
88249261Sdim    /// Used by Indent() to print the tree structure.
89249261Sdim    llvm::SmallVector<IndentType, 32> Indents;
90249261Sdim
91249261Sdim    /// Indicates that more children will be needed at this indent level.
92249261Sdim    /// If true, prevents lastChild() from marking the node as the last child.
93249261Sdim    /// This is used when there are multiple collections of children to be
94249261Sdim    /// dumped as well as during conditional node dumping.
95249261Sdim    bool MoreChildren;
96249261Sdim
97249261Sdim    /// Keep track of the last location we print out so that we can
98249261Sdim    /// print out deltas from then on out.
99249261Sdim    const char *LastLocFilename;
100249261Sdim    unsigned LastLocLine;
101249261Sdim
102249261Sdim    /// The \c FullComment parent of the comment being dumped.
103249261Sdim    const FullComment *FC;
104249261Sdim
105249261Sdim    bool ShowColors;
106249261Sdim
107249261Sdim    class IndentScope {
108249261Sdim      ASTDumper &Dumper;
109249261Sdim      // Preserve the Dumper's MoreChildren value from the previous IndentScope
110249261Sdim      bool MoreChildren;
111249261Sdim    public:
112249261Sdim      IndentScope(ASTDumper &Dumper) : Dumper(Dumper) {
113249261Sdim        MoreChildren = Dumper.hasMoreChildren();
114249261Sdim        Dumper.setMoreChildren(false);
115249261Sdim        Dumper.indent();
116249261Sdim      }
117249261Sdim      ~IndentScope() {
118249261Sdim        Dumper.setMoreChildren(MoreChildren);
119249261Sdim        Dumper.unindent();
120249261Sdim      }
121249261Sdim    };
122249261Sdim
123249261Sdim    class ColorScope {
124249261Sdim      ASTDumper &Dumper;
125249261Sdim    public:
126249261Sdim      ColorScope(ASTDumper &Dumper, TerminalColor Color)
127249261Sdim        : Dumper(Dumper) {
128249261Sdim        if (Dumper.ShowColors)
129249261Sdim          Dumper.OS.changeColor(Color.Color, Color.Bold);
130249261Sdim      }
131249261Sdim      ~ColorScope() {
132249261Sdim        if (Dumper.ShowColors)
133249261Sdim          Dumper.OS.resetColor();
134249261Sdim      }
135249261Sdim    };
136249261Sdim
137249261Sdim  public:
138249261Sdim    ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
139249261Sdim              const SourceManager *SM)
140249261Sdim      : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false),
141249261Sdim        LastLocFilename(""), LastLocLine(~0U), FC(0),
142249261Sdim        ShowColors(SM && SM->getDiagnostics().getShowColors()) { }
143249261Sdim
144249261Sdim    ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
145249261Sdim              const SourceManager *SM, bool ShowColors)
146249261Sdim      : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false),
147249261Sdim        LastLocFilename(""), LastLocLine(~0U),
148249261Sdim        ShowColors(ShowColors) { }
149249261Sdim
150249261Sdim    ~ASTDumper() {
151249261Sdim      OS << "\n";
152249261Sdim    }
153249261Sdim
154249261Sdim    void dumpDecl(const Decl *D);
155249261Sdim    void dumpStmt(const Stmt *S);
156249261Sdim    void dumpFullComment(const FullComment *C);
157249261Sdim
158249261Sdim    // Formatting
159249261Sdim    void indent();
160249261Sdim    void unindent();
161249261Sdim    void lastChild();
162249261Sdim    bool hasMoreChildren();
163249261Sdim    void setMoreChildren(bool Value);
164249261Sdim
165249261Sdim    // Utilities
166249261Sdim    void dumpPointer(const void *Ptr);
167249261Sdim    void dumpSourceRange(SourceRange R);
168249261Sdim    void dumpLocation(SourceLocation Loc);
169249261Sdim    void dumpBareType(QualType T);
170249261Sdim    void dumpType(QualType T);
171249261Sdim    void dumpBareDeclRef(const Decl *Node);
172249261Sdim    void dumpDeclRef(const Decl *Node, const char *Label = 0);
173249261Sdim    void dumpName(const NamedDecl *D);
174249261Sdim    bool hasNodes(const DeclContext *DC);
175249261Sdim    void dumpDeclContext(const DeclContext *DC);
176249261Sdim    void dumpAttr(const Attr *A);
177249261Sdim
178249261Sdim    // C++ Utilities
179249261Sdim    void dumpAccessSpecifier(AccessSpecifier AS);
180249261Sdim    void dumpCXXCtorInitializer(const CXXCtorInitializer *Init);
181249261Sdim    void dumpTemplateParameters(const TemplateParameterList *TPL);
182249261Sdim    void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
183249261Sdim    void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A);
184249261Sdim    void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
185249261Sdim    void dumpTemplateArgument(const TemplateArgument &A,
186249261Sdim                              SourceRange R = SourceRange());
187249261Sdim
188249261Sdim    // Decls
189249261Sdim    void VisitLabelDecl(const LabelDecl *D);
190249261Sdim    void VisitTypedefDecl(const TypedefDecl *D);
191249261Sdim    void VisitEnumDecl(const EnumDecl *D);
192249261Sdim    void VisitRecordDecl(const RecordDecl *D);
193249261Sdim    void VisitEnumConstantDecl(const EnumConstantDecl *D);
194249261Sdim    void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
195249261Sdim    void VisitFunctionDecl(const FunctionDecl *D);
196249261Sdim    void VisitFieldDecl(const FieldDecl *D);
197249261Sdim    void VisitVarDecl(const VarDecl *D);
198249261Sdim    void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D);
199249261Sdim    void VisitImportDecl(const ImportDecl *D);
200249261Sdim
201249261Sdim    // C++ Decls
202249261Sdim    void VisitNamespaceDecl(const NamespaceDecl *D);
203249261Sdim    void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
204249261Sdim    void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
205249261Sdim    void VisitTypeAliasDecl(const TypeAliasDecl *D);
206249261Sdim    void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
207249261Sdim    void VisitCXXRecordDecl(const CXXRecordDecl *D);
208249261Sdim    void VisitStaticAssertDecl(const StaticAssertDecl *D);
209249261Sdim    void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
210249261Sdim    void VisitClassTemplateDecl(const ClassTemplateDecl *D);
211249261Sdim    void VisitClassTemplateSpecializationDecl(
212249261Sdim        const ClassTemplateSpecializationDecl *D);
213249261Sdim    void VisitClassTemplatePartialSpecializationDecl(
214249261Sdim        const ClassTemplatePartialSpecializationDecl *D);
215249261Sdim    void VisitClassScopeFunctionSpecializationDecl(
216249261Sdim        const ClassScopeFunctionSpecializationDecl *D);
217249261Sdim    void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
218249261Sdim    void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
219249261Sdim    void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
220249261Sdim    void VisitUsingDecl(const UsingDecl *D);
221249261Sdim    void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
222249261Sdim    void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
223249261Sdim    void VisitUsingShadowDecl(const UsingShadowDecl *D);
224249261Sdim    void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
225249261Sdim    void VisitAccessSpecDecl(const AccessSpecDecl *D);
226249261Sdim    void VisitFriendDecl(const FriendDecl *D);
227249261Sdim
228249261Sdim    // ObjC Decls
229249261Sdim    void VisitObjCIvarDecl(const ObjCIvarDecl *D);
230249261Sdim    void VisitObjCMethodDecl(const ObjCMethodDecl *D);
231249261Sdim    void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
232249261Sdim    void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
233249261Sdim    void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
234249261Sdim    void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
235249261Sdim    void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
236249261Sdim    void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
237249261Sdim    void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
238249261Sdim    void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
239249261Sdim    void VisitBlockDecl(const BlockDecl *D);
240249261Sdim
241249261Sdim    // Stmts.
242249261Sdim    void VisitStmt(const Stmt *Node);
243249261Sdim    void VisitDeclStmt(const DeclStmt *Node);
244249261Sdim    void VisitAttributedStmt(const AttributedStmt *Node);
245249261Sdim    void VisitLabelStmt(const LabelStmt *Node);
246249261Sdim    void VisitGotoStmt(const GotoStmt *Node);
247249261Sdim
248249261Sdim    // Exprs
249249261Sdim    void VisitExpr(const Expr *Node);
250249261Sdim    void VisitCastExpr(const CastExpr *Node);
251249261Sdim    void VisitDeclRefExpr(const DeclRefExpr *Node);
252249261Sdim    void VisitPredefinedExpr(const PredefinedExpr *Node);
253249261Sdim    void VisitCharacterLiteral(const CharacterLiteral *Node);
254249261Sdim    void VisitIntegerLiteral(const IntegerLiteral *Node);
255249261Sdim    void VisitFloatingLiteral(const FloatingLiteral *Node);
256249261Sdim    void VisitStringLiteral(const StringLiteral *Str);
257249261Sdim    void VisitUnaryOperator(const UnaryOperator *Node);
258249261Sdim    void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
259249261Sdim    void VisitMemberExpr(const MemberExpr *Node);
260249261Sdim    void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
261249261Sdim    void VisitBinaryOperator(const BinaryOperator *Node);
262249261Sdim    void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
263249261Sdim    void VisitAddrLabelExpr(const AddrLabelExpr *Node);
264249261Sdim    void VisitBlockExpr(const BlockExpr *Node);
265249261Sdim    void VisitOpaqueValueExpr(const OpaqueValueExpr *Node);
266249261Sdim
267249261Sdim    // C++
268249261Sdim    void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
269249261Sdim    void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
270249261Sdim    void VisitCXXThisExpr(const CXXThisExpr *Node);
271249261Sdim    void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
272249261Sdim    void VisitCXXConstructExpr(const CXXConstructExpr *Node);
273249261Sdim    void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
274249261Sdim    void VisitExprWithCleanups(const ExprWithCleanups *Node);
275249261Sdim    void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
276249261Sdim    void dumpCXXTemporary(const CXXTemporary *Temporary);
277249261Sdim
278249261Sdim    // ObjC
279249261Sdim    void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
280249261Sdim    void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
281249261Sdim    void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
282249261Sdim    void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
283249261Sdim    void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
284249261Sdim    void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
285249261Sdim    void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
286249261Sdim    void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
287249261Sdim    void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
288249261Sdim    void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
289249261Sdim
290249261Sdim    // Comments.
291249261Sdim    const char *getCommandName(unsigned CommandID);
292249261Sdim    void dumpComment(const Comment *C);
293249261Sdim
294249261Sdim    // Inline comments.
295249261Sdim    void visitTextComment(const TextComment *C);
296249261Sdim    void visitInlineCommandComment(const InlineCommandComment *C);
297249261Sdim    void visitHTMLStartTagComment(const HTMLStartTagComment *C);
298249261Sdim    void visitHTMLEndTagComment(const HTMLEndTagComment *C);
299249261Sdim
300249261Sdim    // Block comments.
301249261Sdim    void visitBlockCommandComment(const BlockCommandComment *C);
302249261Sdim    void visitParamCommandComment(const ParamCommandComment *C);
303249261Sdim    void visitTParamCommandComment(const TParamCommandComment *C);
304249261Sdim    void visitVerbatimBlockComment(const VerbatimBlockComment *C);
305249261Sdim    void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
306249261Sdim    void visitVerbatimLineComment(const VerbatimLineComment *C);
307249261Sdim  };
308249261Sdim}
309249261Sdim
310249261Sdim//===----------------------------------------------------------------------===//
311249261Sdim//  Utilities
312249261Sdim//===----------------------------------------------------------------------===//
313249261Sdim
314249261Sdim// Print out the appropriate tree structure using the Indents vector.
315249261Sdim// Example of tree and the Indents vector at each level.
316249261Sdim// A        { }
317249261Sdim// |-B      { IT_Child }
318249261Sdim// | `-C    { IT_Child,     IT_LastChild }
319249261Sdim// `-D      { IT_LastChild }
320249261Sdim//   |-E    { IT_LastChild, IT_Child }
321249261Sdim//   `-F    { IT_LastChild, IT_LastChild }
322249261Sdim// Type            non-last element, last element
323249261Sdim// IT_Child        "| "              "|-"
324249261Sdim// IT_LastChild    "  "              "`-"
325249261Sdimvoid ASTDumper::indent() {
326249261Sdim  if (IsFirstLine)
327249261Sdim    IsFirstLine = false;
328249261Sdim  else
329249261Sdim    OS << "\n";
330249261Sdim
331249261Sdim  ColorScope Color(*this, IndentColor);
332249261Sdim  for (llvm::SmallVector<IndentType, 32>::const_iterator I = Indents.begin(),
333249261Sdim                                                         E = Indents.end();
334249261Sdim       I != E; ++I) {
335249261Sdim    switch (*I) {
336249261Sdim    case IT_Child:
337249261Sdim      if (I == E - 1)
338249261Sdim        OS << "|-";
339249261Sdim      else
340249261Sdim        OS << "| ";
341249261Sdim      continue;
342249261Sdim    case IT_LastChild:
343249261Sdim      if (I == E - 1)
344249261Sdim        OS << "`-";
345249261Sdim      else
346249261Sdim        OS << "  ";
347249261Sdim      continue;
348249261Sdim    }
349249261Sdim    llvm_unreachable("Invalid IndentType");
350249261Sdim  }
351249261Sdim  Indents.push_back(IT_Child);
352249261Sdim}
353249261Sdim
354249261Sdimvoid ASTDumper::unindent() {
355249261Sdim  Indents.pop_back();
356249261Sdim}
357249261Sdim
358249261Sdim// Call before each potential last child node is to be dumped.  If MoreChildren
359249261Sdim// is false, then this is the last child, otherwise treat as a regular node.
360249261Sdimvoid ASTDumper::lastChild() {
361249261Sdim  if (!hasMoreChildren())
362249261Sdim    Indents.back() = IT_LastChild;
363249261Sdim}
364249261Sdim
365249261Sdim// MoreChildren should be set before calling another function that may print
366249261Sdim// additional nodes to prevent conflicting final child nodes.
367249261Sdimbool ASTDumper::hasMoreChildren() {
368249261Sdim  return MoreChildren;
369249261Sdim}
370249261Sdim
371249261Sdimvoid ASTDumper::setMoreChildren(bool Value) {
372249261Sdim  MoreChildren = Value;
373249261Sdim}
374249261Sdim
375249261Sdimvoid ASTDumper::dumpPointer(const void *Ptr) {
376249261Sdim  ColorScope Color(*this, AddressColor);
377249261Sdim  OS << ' ' << Ptr;
378249261Sdim}
379249261Sdim
380249261Sdimvoid ASTDumper::dumpLocation(SourceLocation Loc) {
381249261Sdim  ColorScope Color(*this, LocationColor);
382249261Sdim  SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
383249261Sdim
384249261Sdim  // The general format we print out is filename:line:col, but we drop pieces
385249261Sdim  // that haven't changed since the last loc printed.
386249261Sdim  PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
387249261Sdim
388249261Sdim  if (PLoc.isInvalid()) {
389249261Sdim    OS << "<invalid sloc>";
390249261Sdim    return;
391249261Sdim  }
392249261Sdim
393249261Sdim  if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
394249261Sdim    OS << PLoc.getFilename() << ':' << PLoc.getLine()
395249261Sdim       << ':' << PLoc.getColumn();
396249261Sdim    LastLocFilename = PLoc.getFilename();
397249261Sdim    LastLocLine = PLoc.getLine();
398249261Sdim  } else if (PLoc.getLine() != LastLocLine) {
399249261Sdim    OS << "line" << ':' << PLoc.getLine()
400249261Sdim       << ':' << PLoc.getColumn();
401249261Sdim    LastLocLine = PLoc.getLine();
402249261Sdim  } else {
403249261Sdim    OS << "col" << ':' << PLoc.getColumn();
404249261Sdim  }
405249261Sdim}
406249261Sdim
407249261Sdimvoid ASTDumper::dumpSourceRange(SourceRange R) {
408249261Sdim  // Can't translate locations if a SourceManager isn't available.
409249261Sdim  if (!SM)
410249261Sdim    return;
411249261Sdim
412249261Sdim  OS << " <";
413249261Sdim  dumpLocation(R.getBegin());
414249261Sdim  if (R.getBegin() != R.getEnd()) {
415249261Sdim    OS << ", ";
416249261Sdim    dumpLocation(R.getEnd());
417249261Sdim  }
418249261Sdim  OS << ">";
419249261Sdim
420249261Sdim  // <t2.c:123:421[blah], t2.c:412:321>
421249261Sdim
422249261Sdim}
423249261Sdim
424249261Sdimvoid ASTDumper::dumpBareType(QualType T) {
425249261Sdim  ColorScope Color(*this, TypeColor);
426249261Sdim
427249261Sdim  SplitQualType T_split = T.split();
428249261Sdim  OS << "'" << QualType::getAsString(T_split) << "'";
429249261Sdim
430249261Sdim  if (!T.isNull()) {
431249261Sdim    // If the type is sugared, also dump a (shallow) desugared type.
432249261Sdim    SplitQualType D_split = T.getSplitDesugaredType();
433249261Sdim    if (T_split != D_split)
434249261Sdim      OS << ":'" << QualType::getAsString(D_split) << "'";
435249261Sdim  }
436249261Sdim}
437249261Sdim
438249261Sdimvoid ASTDumper::dumpType(QualType T) {
439249261Sdim  OS << ' ';
440249261Sdim  dumpBareType(T);
441249261Sdim}
442249261Sdim
443249261Sdimvoid ASTDumper::dumpBareDeclRef(const Decl *D) {
444249261Sdim  {
445249261Sdim    ColorScope Color(*this, DeclKindNameColor);
446249261Sdim    OS << D->getDeclKindName();
447249261Sdim  }
448249261Sdim  dumpPointer(D);
449249261Sdim
450249261Sdim  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
451249261Sdim    ColorScope Color(*this, DeclNameColor);
452249261Sdim    OS << " '";
453249261Sdim    ND->getDeclName().printName(OS);
454249261Sdim    OS << "'";
455249261Sdim  }
456249261Sdim
457249261Sdim  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
458249261Sdim    dumpType(VD->getType());
459249261Sdim}
460249261Sdim
461249261Sdimvoid ASTDumper::dumpDeclRef(const Decl *D, const char *Label) {
462249261Sdim  if (!D)
463249261Sdim    return;
464249261Sdim
465249261Sdim  IndentScope Indent(*this);
466249261Sdim  if (Label)
467249261Sdim    OS << Label << ' ';
468249261Sdim  dumpBareDeclRef(D);
469249261Sdim}
470249261Sdim
471249261Sdimvoid ASTDumper::dumpName(const NamedDecl *ND) {
472249261Sdim  if (ND->getDeclName()) {
473249261Sdim    ColorScope Color(*this, DeclNameColor);
474249261Sdim    OS << ' ' << ND->getNameAsString();
475249261Sdim  }
476249261Sdim}
477249261Sdim
478249261Sdimbool ASTDumper::hasNodes(const DeclContext *DC) {
479249261Sdim  if (!DC)
480249261Sdim    return false;
481249261Sdim
482249261Sdim  return DC->decls_begin() != DC->decls_end();
483249261Sdim}
484249261Sdim
485249261Sdimvoid ASTDumper::dumpDeclContext(const DeclContext *DC) {
486249261Sdim  if (!DC)
487249261Sdim    return;
488249261Sdim  for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
489249261Sdim       I != E; ++I) {
490249261Sdim    DeclContext::decl_iterator Next = I;
491249261Sdim    ++Next;
492249261Sdim    if (Next == E)
493249261Sdim      lastChild();
494249261Sdim    dumpDecl(*I);
495249261Sdim  }
496249261Sdim}
497249261Sdim
498249261Sdimvoid ASTDumper::dumpAttr(const Attr *A) {
499249261Sdim  IndentScope Indent(*this);
500249261Sdim  {
501249261Sdim    ColorScope Color(*this, AttrColor);
502249261Sdim    switch (A->getKind()) {
503249261Sdim#define ATTR(X) case attr::X: OS << #X; break;
504249261Sdim#include "clang/Basic/AttrList.inc"
505249261Sdim    default: llvm_unreachable("unexpected attribute kind");
506249261Sdim    }
507249261Sdim    OS << "Attr";
508249261Sdim  }
509249261Sdim  dumpPointer(A);
510249261Sdim  dumpSourceRange(A->getRange());
511249261Sdim#include "clang/AST/AttrDump.inc"
512249261Sdim}
513249261Sdim
514249261Sdimstatic Decl *getPreviousDeclImpl(...) {
515249261Sdim  return 0;
516249261Sdim}
517249261Sdim
518249261Sdimtemplate<typename T>
519249261Sdimstatic const Decl *getPreviousDeclImpl(const Redeclarable<T> *D) {
520249261Sdim  return D->getPreviousDecl();
521249261Sdim}
522249261Sdim
523249261Sdim/// Get the previous declaration in the redeclaration chain for a declaration.
524249261Sdimstatic const Decl *getPreviousDecl(const Decl *D) {
525249261Sdim  switch (D->getKind()) {
526249261Sdim#define DECL(DERIVED, BASE) \
527249261Sdim  case Decl::DERIVED: \
528249261Sdim    return getPreviousDeclImpl(cast<DERIVED##Decl>(D));
529249261Sdim#define ABSTRACT_DECL(DECL)
530249261Sdim#include "clang/AST/DeclNodes.inc"
531249261Sdim  }
532249261Sdim  llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
533249261Sdim}
534249261Sdim
535249261Sdim//===----------------------------------------------------------------------===//
536249261Sdim//  C++ Utilities
537249261Sdim//===----------------------------------------------------------------------===//
538249261Sdim
539249261Sdimvoid ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) {
540249261Sdim  switch (AS) {
541249261Sdim  case AS_none:
542249261Sdim    break;
543249261Sdim  case AS_public:
544249261Sdim    OS << "public";
545249261Sdim    break;
546249261Sdim  case AS_protected:
547249261Sdim    OS << "protected";
548249261Sdim    break;
549249261Sdim  case AS_private:
550249261Sdim    OS << "private";
551249261Sdim    break;
552249261Sdim  }
553249261Sdim}
554249261Sdim
555249261Sdimvoid ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) {
556249261Sdim  IndentScope Indent(*this);
557249261Sdim  OS << "CXXCtorInitializer";
558249261Sdim  if (Init->isAnyMemberInitializer()) {
559249261Sdim    OS << ' ';
560249261Sdim    dumpBareDeclRef(Init->getAnyMember());
561249261Sdim  } else {
562249261Sdim    dumpType(QualType(Init->getBaseClass(), 0));
563249261Sdim  }
564249261Sdim  dumpStmt(Init->getInit());
565249261Sdim}
566249261Sdim
567249261Sdimvoid ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) {
568249261Sdim  if (!TPL)
569249261Sdim    return;
570249261Sdim
571249261Sdim  for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end();
572249261Sdim       I != E; ++I)
573249261Sdim    dumpDecl(*I);
574249261Sdim}
575249261Sdim
576249261Sdimvoid ASTDumper::dumpTemplateArgumentListInfo(
577249261Sdim    const TemplateArgumentListInfo &TALI) {
578249261Sdim  for (unsigned i = 0, e = TALI.size(); i < e; ++i) {
579249261Sdim    if (i + 1 == e)
580249261Sdim      lastChild();
581249261Sdim    dumpTemplateArgumentLoc(TALI[i]);
582249261Sdim  }
583249261Sdim}
584249261Sdim
585249261Sdimvoid ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) {
586249261Sdim  dumpTemplateArgument(A.getArgument(), A.getSourceRange());
587249261Sdim}
588249261Sdim
589249261Sdimvoid ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
590249261Sdim  for (unsigned i = 0, e = TAL.size(); i < e; ++i)
591249261Sdim    dumpTemplateArgument(TAL[i]);
592249261Sdim}
593249261Sdim
594249261Sdimvoid ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) {
595249261Sdim  IndentScope Indent(*this);
596249261Sdim  OS << "TemplateArgument";
597249261Sdim  if (R.isValid())
598249261Sdim    dumpSourceRange(R);
599249261Sdim
600249261Sdim  switch (A.getKind()) {
601249261Sdim  case TemplateArgument::Null:
602249261Sdim    OS << " null";
603249261Sdim    break;
604249261Sdim  case TemplateArgument::Type:
605249261Sdim    OS << " type";
606249261Sdim    lastChild();
607249261Sdim    dumpType(A.getAsType());
608249261Sdim    break;
609249261Sdim  case TemplateArgument::Declaration:
610249261Sdim    OS << " decl";
611249261Sdim    lastChild();
612249261Sdim    dumpDeclRef(A.getAsDecl());
613249261Sdim    break;
614249261Sdim  case TemplateArgument::NullPtr:
615249261Sdim    OS << " nullptr";
616249261Sdim    break;
617249261Sdim  case TemplateArgument::Integral:
618249261Sdim    OS << " integral " << A.getAsIntegral();
619249261Sdim    break;
620249261Sdim  case TemplateArgument::Template:
621249261Sdim    OS << " template ";
622249261Sdim    A.getAsTemplate().dump(OS);
623249261Sdim    break;
624249261Sdim  case TemplateArgument::TemplateExpansion:
625249261Sdim    OS << " template expansion";
626249261Sdim    A.getAsTemplateOrTemplatePattern().dump(OS);
627249261Sdim    break;
628249261Sdim  case TemplateArgument::Expression:
629249261Sdim    OS << " expr";
630249261Sdim    lastChild();
631249261Sdim    dumpStmt(A.getAsExpr());
632249261Sdim    break;
633249261Sdim  case TemplateArgument::Pack:
634249261Sdim    OS << " pack";
635249261Sdim    for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end();
636249261Sdim         I != E; ++I) {
637249261Sdim      if (I + 1 == E)
638249261Sdim        lastChild();
639249261Sdim      dumpTemplateArgument(*I);
640249261Sdim    }
641249261Sdim    break;
642249261Sdim  }
643249261Sdim}
644249261Sdim
645249261Sdim//===----------------------------------------------------------------------===//
646249261Sdim//  Decl dumping methods.
647249261Sdim//===----------------------------------------------------------------------===//
648249261Sdim
649249261Sdimvoid ASTDumper::dumpDecl(const Decl *D) {
650249261Sdim  IndentScope Indent(*this);
651249261Sdim
652249261Sdim  if (!D) {
653249261Sdim    ColorScope Color(*this, NullColor);
654249261Sdim    OS << "<<<NULL>>>";
655249261Sdim    return;
656249261Sdim  }
657249261Sdim
658249261Sdim  {
659249261Sdim    ColorScope Color(*this, DeclKindNameColor);
660249261Sdim    OS << D->getDeclKindName() << "Decl";
661249261Sdim  }
662249261Sdim  dumpPointer(D);
663249261Sdim  if (D->getLexicalDeclContext() != D->getDeclContext())
664249261Sdim    OS << " parent " << cast<Decl>(D->getDeclContext());
665249261Sdim  if (const Decl *Prev = getPreviousDecl(D))
666249261Sdim    OS << " prev " << Prev;
667249261Sdim  dumpSourceRange(D->getSourceRange());
668249261Sdim
669249261Sdim  bool HasAttrs = D->attr_begin() != D->attr_end();
670249261Sdim  bool HasComment = D->getASTContext().getCommentForDecl(D, 0);
671249261Sdim  // Decls within functions are visited by the body
672249261Sdim  bool HasDeclContext = !isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) &&
673249261Sdim                         hasNodes(dyn_cast<DeclContext>(D));
674249261Sdim
675249261Sdim  setMoreChildren(HasAttrs || HasComment || HasDeclContext);
676249261Sdim  ConstDeclVisitor<ASTDumper>::Visit(D);
677249261Sdim
678249261Sdim  setMoreChildren(HasComment || HasDeclContext);
679249261Sdim  for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end();
680249261Sdim       I != E; ++I) {
681249261Sdim    if (I + 1 == E)
682249261Sdim      lastChild();
683249261Sdim    dumpAttr(*I);
684249261Sdim  }
685249261Sdim
686249261Sdim  setMoreChildren(HasDeclContext);
687249261Sdim  lastChild();
688249261Sdim  dumpFullComment(D->getASTContext().getCommentForDecl(D, 0));
689249261Sdim
690249261Sdim  setMoreChildren(false);
691249261Sdim  if (HasDeclContext)
692249261Sdim    dumpDeclContext(cast<DeclContext>(D));
693249261Sdim}
694249261Sdim
695249261Sdimvoid ASTDumper::VisitLabelDecl(const LabelDecl *D) {
696249261Sdim  dumpName(D);
697249261Sdim}
698249261Sdim
699249261Sdimvoid ASTDumper::VisitTypedefDecl(const TypedefDecl *D) {
700249261Sdim  dumpName(D);
701249261Sdim  dumpType(D->getUnderlyingType());
702249261Sdim  if (D->isModulePrivate())
703249261Sdim    OS << " __module_private__";
704249261Sdim}
705249261Sdim
706249261Sdimvoid ASTDumper::VisitEnumDecl(const EnumDecl *D) {
707249261Sdim  if (D->isScoped()) {
708249261Sdim    if (D->isScopedUsingClassTag())
709249261Sdim      OS << " class";
710249261Sdim    else
711249261Sdim      OS << " struct";
712249261Sdim  }
713249261Sdim  dumpName(D);
714249261Sdim  if (D->isModulePrivate())
715249261Sdim    OS << " __module_private__";
716249261Sdim  if (D->isFixed())
717249261Sdim    dumpType(D->getIntegerType());
718249261Sdim}
719249261Sdim
720249261Sdimvoid ASTDumper::VisitRecordDecl(const RecordDecl *D) {
721249261Sdim  OS << ' ' << D->getKindName();
722249261Sdim  dumpName(D);
723249261Sdim  if (D->isModulePrivate())
724249261Sdim    OS << " __module_private__";
725249261Sdim}
726249261Sdim
727249261Sdimvoid ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
728249261Sdim  dumpName(D);
729249261Sdim  dumpType(D->getType());
730249261Sdim  if (const Expr *Init = D->getInitExpr()) {
731249261Sdim    lastChild();
732249261Sdim    dumpStmt(Init);
733249261Sdim  }
734249261Sdim}
735249261Sdim
736249261Sdimvoid ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
737249261Sdim  dumpName(D);
738249261Sdim  dumpType(D->getType());
739249261Sdim  for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
740249261Sdim                                         E = D->chain_end();
741249261Sdim       I != E; ++I) {
742249261Sdim    if (I + 1 == E)
743249261Sdim      lastChild();
744249261Sdim    dumpDeclRef(*I);
745249261Sdim  }
746249261Sdim}
747249261Sdim
748249261Sdimvoid ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
749249261Sdim  dumpName(D);
750249261Sdim  dumpType(D->getType());
751249261Sdim
752249261Sdim  StorageClass SC = D->getStorageClass();
753249261Sdim  if (SC != SC_None)
754249261Sdim    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
755249261Sdim  if (D->isInlineSpecified())
756249261Sdim    OS << " inline";
757249261Sdim  if (D->isVirtualAsWritten())
758249261Sdim    OS << " virtual";
759249261Sdim  if (D->isModulePrivate())
760249261Sdim    OS << " __module_private__";
761249261Sdim
762249261Sdim  if (D->isPure())
763249261Sdim    OS << " pure";
764249261Sdim  else if (D->isDeletedAsWritten())
765249261Sdim    OS << " delete";
766249261Sdim
767249261Sdim  bool OldMoreChildren = hasMoreChildren();
768249261Sdim  const FunctionTemplateSpecializationInfo *FTSI =
769249261Sdim      D->getTemplateSpecializationInfo();
770249261Sdim  bool HasTemplateSpecialization = FTSI;
771249261Sdim
772249261Sdim  bool HasNamedDecls = D->getDeclsInPrototypeScope().begin() !=
773249261Sdim                       D->getDeclsInPrototypeScope().end();
774249261Sdim
775249261Sdim  bool HasFunctionDecls = D->param_begin() != D->param_end();
776249261Sdim
777249261Sdim  const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D);
778249261Sdim  bool HasCtorInitializers = C && C->init_begin() != C->init_end();
779249261Sdim
780249261Sdim  bool HasDeclarationBody = D->doesThisDeclarationHaveABody();
781249261Sdim
782249261Sdim  setMoreChildren(OldMoreChildren || HasNamedDecls || HasFunctionDecls ||
783249261Sdim                  HasCtorInitializers || HasDeclarationBody);
784249261Sdim  if (HasTemplateSpecialization) {
785249261Sdim    lastChild();
786249261Sdim    dumpTemplateArgumentList(*FTSI->TemplateArguments);
787249261Sdim  }
788249261Sdim
789249261Sdim  setMoreChildren(OldMoreChildren || HasFunctionDecls ||
790249261Sdim                  HasCtorInitializers || HasDeclarationBody);
791249261Sdim  for (ArrayRef<NamedDecl *>::iterator
792249261Sdim       I = D->getDeclsInPrototypeScope().begin(),
793249261Sdim       E = D->getDeclsInPrototypeScope().end(); I != E; ++I) {
794249261Sdim    if (I + 1 == E)
795249261Sdim      lastChild();
796249261Sdim    dumpDecl(*I);
797249261Sdim  }
798249261Sdim
799249261Sdim  setMoreChildren(OldMoreChildren || HasCtorInitializers || HasDeclarationBody);
800249261Sdim  for (FunctionDecl::param_const_iterator I = D->param_begin(),
801249261Sdim                                          E = D->param_end();
802249261Sdim       I != E; ++I) {
803249261Sdim    if (I + 1 == E)
804249261Sdim      lastChild();
805249261Sdim    dumpDecl(*I);
806249261Sdim  }
807249261Sdim
808249261Sdim  setMoreChildren(OldMoreChildren || HasDeclarationBody);
809249261Sdim  if (HasCtorInitializers)
810249261Sdim    for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
811249261Sdim                                                 E = C->init_end();
812249261Sdim         I != E; ++I) {
813249261Sdim      if (I + 1 == E)
814249261Sdim        lastChild();
815249261Sdim      dumpCXXCtorInitializer(*I);
816249261Sdim  }
817249261Sdim
818249261Sdim  setMoreChildren(OldMoreChildren);
819249261Sdim  if (HasDeclarationBody) {
820249261Sdim    lastChild();
821249261Sdim    dumpStmt(D->getBody());
822249261Sdim  }
823249261Sdim}
824249261Sdim
825249261Sdimvoid ASTDumper::VisitFieldDecl(const FieldDecl *D) {
826249261Sdim  dumpName(D);
827249261Sdim  dumpType(D->getType());
828249261Sdim  if (D->isMutable())
829249261Sdim    OS << " mutable";
830249261Sdim  if (D->isModulePrivate())
831249261Sdim    OS << " __module_private__";
832249261Sdim
833249261Sdim  bool OldMoreChildren = hasMoreChildren();
834249261Sdim  bool IsBitField = D->isBitField();
835249261Sdim  Expr *Init = D->getInClassInitializer();
836249261Sdim  bool HasInit = Init;
837249261Sdim
838249261Sdim  setMoreChildren(OldMoreChildren || HasInit);
839249261Sdim  if (IsBitField) {
840249261Sdim    lastChild();
841249261Sdim    dumpStmt(D->getBitWidth());
842249261Sdim  }
843249261Sdim  setMoreChildren(OldMoreChildren);
844249261Sdim  if (HasInit) {
845249261Sdim    lastChild();
846249261Sdim    dumpStmt(Init);
847249261Sdim  }
848249261Sdim}
849249261Sdim
850249261Sdimvoid ASTDumper::VisitVarDecl(const VarDecl *D) {
851249261Sdim  dumpName(D);
852249261Sdim  dumpType(D->getType());
853249261Sdim  StorageClass SC = D->getStorageClass();
854249261Sdim  if (SC != SC_None)
855249261Sdim    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
856251662Sdim  switch (D->getTLSKind()) {
857251662Sdim  case VarDecl::TLS_None: break;
858251662Sdim  case VarDecl::TLS_Static: OS << " tls"; break;
859251662Sdim  case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break;
860251662Sdim  }
861249261Sdim  if (D->isModulePrivate())
862249261Sdim    OS << " __module_private__";
863249261Sdim  if (D->isNRVOVariable())
864249261Sdim    OS << " nrvo";
865249261Sdim  if (D->hasInit()) {
866249261Sdim    lastChild();
867249261Sdim    dumpStmt(D->getInit());
868249261Sdim  }
869249261Sdim}
870249261Sdim
871249261Sdimvoid ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
872249261Sdim  lastChild();
873249261Sdim  dumpStmt(D->getAsmString());
874249261Sdim}
875249261Sdim
876249261Sdimvoid ASTDumper::VisitImportDecl(const ImportDecl *D) {
877249261Sdim  OS << ' ' << D->getImportedModule()->getFullModuleName();
878249261Sdim}
879249261Sdim
880249261Sdim//===----------------------------------------------------------------------===//
881249261Sdim// C++ Declarations
882249261Sdim//===----------------------------------------------------------------------===//
883249261Sdim
884249261Sdimvoid ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
885249261Sdim  dumpName(D);
886249261Sdim  if (D->isInline())
887249261Sdim    OS << " inline";
888249261Sdim  if (!D->isOriginalNamespace())
889249261Sdim    dumpDeclRef(D->getOriginalNamespace(), "original");
890249261Sdim}
891249261Sdim
892249261Sdimvoid ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
893249261Sdim  OS << ' ';
894249261Sdim  dumpBareDeclRef(D->getNominatedNamespace());
895249261Sdim}
896249261Sdim
897249261Sdimvoid ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
898249261Sdim  dumpName(D);
899249261Sdim  dumpDeclRef(D->getAliasedNamespace());
900249261Sdim}
901249261Sdim
902249261Sdimvoid ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
903249261Sdim  dumpName(D);
904249261Sdim  dumpType(D->getUnderlyingType());
905249261Sdim}
906249261Sdim
907249261Sdimvoid ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
908249261Sdim  dumpName(D);
909249261Sdim  dumpTemplateParameters(D->getTemplateParameters());
910249261Sdim  dumpDecl(D->getTemplatedDecl());
911249261Sdim}
912249261Sdim
913249261Sdimvoid ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
914249261Sdim  VisitRecordDecl(D);
915249261Sdim  if (!D->isCompleteDefinition())
916249261Sdim    return;
917249261Sdim
918249261Sdim  for (CXXRecordDecl::base_class_const_iterator I = D->bases_begin(),
919249261Sdim                                                E = D->bases_end();
920249261Sdim       I != E; ++I) {
921249261Sdim    IndentScope Indent(*this);
922249261Sdim    if (I->isVirtual())
923249261Sdim      OS << "virtual ";
924249261Sdim    dumpAccessSpecifier(I->getAccessSpecifier());
925249261Sdim    dumpType(I->getType());
926249261Sdim    if (I->isPackExpansion())
927249261Sdim      OS << "...";
928249261Sdim  }
929249261Sdim}
930249261Sdim
931249261Sdimvoid ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
932249261Sdim  dumpStmt(D->getAssertExpr());
933249261Sdim  lastChild();
934249261Sdim  dumpStmt(D->getMessage());
935249261Sdim}
936249261Sdim
937249261Sdimvoid ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
938249261Sdim  dumpName(D);
939249261Sdim  dumpTemplateParameters(D->getTemplateParameters());
940249261Sdim  dumpDecl(D->getTemplatedDecl());
941249261Sdim  for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(),
942249261Sdim                                           E = D->spec_end();
943249261Sdim       I != E; ++I) {
944249261Sdim    FunctionTemplateDecl::spec_iterator Next = I;
945249261Sdim    ++Next;
946249261Sdim    if (Next == E)
947249261Sdim      lastChild();
948249261Sdim    switch (I->getTemplateSpecializationKind()) {
949249261Sdim    case TSK_Undeclared:
950249261Sdim    case TSK_ImplicitInstantiation:
951249261Sdim    case TSK_ExplicitInstantiationDeclaration:
952249261Sdim    case TSK_ExplicitInstantiationDefinition:
953249261Sdim      if (D == D->getCanonicalDecl())
954249261Sdim        dumpDecl(*I);
955249261Sdim      else
956249261Sdim        dumpDeclRef(*I);
957249261Sdim      break;
958249261Sdim    case TSK_ExplicitSpecialization:
959249261Sdim      dumpDeclRef(*I);
960249261Sdim      break;
961249261Sdim    }
962249261Sdim  }
963249261Sdim}
964249261Sdim
965249261Sdimvoid ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
966249261Sdim  dumpName(D);
967249261Sdim  dumpTemplateParameters(D->getTemplateParameters());
968249261Sdim
969249261Sdim  ClassTemplateDecl::spec_iterator I = D->spec_begin();
970249261Sdim  ClassTemplateDecl::spec_iterator E = D->spec_end();
971249261Sdim  if (I == E)
972249261Sdim    lastChild();
973249261Sdim  dumpDecl(D->getTemplatedDecl());
974249261Sdim  for (; I != E; ++I) {
975249261Sdim    ClassTemplateDecl::spec_iterator Next = I;
976249261Sdim    ++Next;
977249261Sdim    if (Next == E)
978249261Sdim      lastChild();
979249261Sdim    switch (I->getTemplateSpecializationKind()) {
980249261Sdim    case TSK_Undeclared:
981249261Sdim    case TSK_ImplicitInstantiation:
982249261Sdim      if (D == D->getCanonicalDecl())
983249261Sdim        dumpDecl(*I);
984249261Sdim      else
985249261Sdim        dumpDeclRef(*I);
986249261Sdim      break;
987249261Sdim    case TSK_ExplicitSpecialization:
988249261Sdim    case TSK_ExplicitInstantiationDeclaration:
989249261Sdim    case TSK_ExplicitInstantiationDefinition:
990249261Sdim      dumpDeclRef(*I);
991249261Sdim      break;
992249261Sdim    }
993249261Sdim  }
994249261Sdim}
995249261Sdim
996249261Sdimvoid ASTDumper::VisitClassTemplateSpecializationDecl(
997249261Sdim    const ClassTemplateSpecializationDecl *D) {
998249261Sdim  VisitCXXRecordDecl(D);
999249261Sdim  dumpTemplateArgumentList(D->getTemplateArgs());
1000249261Sdim}
1001249261Sdim
1002249261Sdimvoid ASTDumper::VisitClassTemplatePartialSpecializationDecl(
1003249261Sdim    const ClassTemplatePartialSpecializationDecl *D) {
1004249261Sdim  VisitClassTemplateSpecializationDecl(D);
1005249261Sdim  dumpTemplateParameters(D->getTemplateParameters());
1006249261Sdim}
1007249261Sdim
1008249261Sdimvoid ASTDumper::VisitClassScopeFunctionSpecializationDecl(
1009249261Sdim    const ClassScopeFunctionSpecializationDecl *D) {
1010249261Sdim  dumpDeclRef(D->getSpecialization());
1011249261Sdim  if (D->hasExplicitTemplateArgs())
1012249261Sdim    dumpTemplateArgumentListInfo(D->templateArgs());
1013249261Sdim}
1014249261Sdim
1015249261Sdimvoid ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
1016249261Sdim  if (D->wasDeclaredWithTypename())
1017249261Sdim    OS << " typename";
1018249261Sdim  else
1019249261Sdim    OS << " class";
1020249261Sdim  if (D->isParameterPack())
1021249261Sdim    OS << " ...";
1022249261Sdim  dumpName(D);
1023249261Sdim  if (D->hasDefaultArgument())
1024249261Sdim    dumpType(D->getDefaultArgument());
1025249261Sdim}
1026249261Sdim
1027249261Sdimvoid ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
1028249261Sdim  dumpType(D->getType());
1029249261Sdim  if (D->isParameterPack())
1030249261Sdim    OS << " ...";
1031249261Sdim  dumpName(D);
1032249261Sdim  if (D->hasDefaultArgument())
1033249261Sdim    dumpStmt(D->getDefaultArgument());
1034249261Sdim}
1035249261Sdim
1036249261Sdimvoid ASTDumper::VisitTemplateTemplateParmDecl(
1037249261Sdim    const TemplateTemplateParmDecl *D) {
1038249261Sdim  if (D->isParameterPack())
1039249261Sdim    OS << " ...";
1040249261Sdim  dumpName(D);
1041249261Sdim  dumpTemplateParameters(D->getTemplateParameters());
1042249261Sdim  if (D->hasDefaultArgument())
1043249261Sdim    dumpTemplateArgumentLoc(D->getDefaultArgument());
1044249261Sdim}
1045249261Sdim
1046249261Sdimvoid ASTDumper::VisitUsingDecl(const UsingDecl *D) {
1047249261Sdim  OS << ' ';
1048249261Sdim  D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1049249261Sdim  OS << D->getNameAsString();
1050249261Sdim}
1051249261Sdim
1052249261Sdimvoid ASTDumper::VisitUnresolvedUsingTypenameDecl(
1053249261Sdim    const UnresolvedUsingTypenameDecl *D) {
1054249261Sdim  OS << ' ';
1055249261Sdim  D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1056249261Sdim  OS << D->getNameAsString();
1057249261Sdim}
1058249261Sdim
1059249261Sdimvoid ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
1060249261Sdim  OS << ' ';
1061249261Sdim  D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1062249261Sdim  OS << D->getNameAsString();
1063249261Sdim  dumpType(D->getType());
1064249261Sdim}
1065249261Sdim
1066249261Sdimvoid ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
1067249261Sdim  OS << ' ';
1068249261Sdim  dumpBareDeclRef(D->getTargetDecl());
1069249261Sdim}
1070249261Sdim
1071249261Sdimvoid ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
1072249261Sdim  switch (D->getLanguage()) {
1073249261Sdim  case LinkageSpecDecl::lang_c: OS << " C"; break;
1074249261Sdim  case LinkageSpecDecl::lang_cxx: OS << " C++"; break;
1075249261Sdim  }
1076249261Sdim}
1077249261Sdim
1078249261Sdimvoid ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
1079249261Sdim  OS << ' ';
1080249261Sdim  dumpAccessSpecifier(D->getAccess());
1081249261Sdim}
1082249261Sdim
1083249261Sdimvoid ASTDumper::VisitFriendDecl(const FriendDecl *D) {
1084249261Sdim  lastChild();
1085249261Sdim  if (TypeSourceInfo *T = D->getFriendType())
1086249261Sdim    dumpType(T->getType());
1087249261Sdim  else
1088249261Sdim    dumpDecl(D->getFriendDecl());
1089249261Sdim}
1090249261Sdim
1091249261Sdim//===----------------------------------------------------------------------===//
1092249261Sdim// Obj-C Declarations
1093249261Sdim//===----------------------------------------------------------------------===//
1094249261Sdim
1095249261Sdimvoid ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
1096249261Sdim  dumpName(D);
1097249261Sdim  dumpType(D->getType());
1098249261Sdim  if (D->getSynthesize())
1099249261Sdim    OS << " synthesize";
1100249261Sdim
1101249261Sdim  switch (D->getAccessControl()) {
1102249261Sdim  case ObjCIvarDecl::None:
1103249261Sdim    OS << " none";
1104249261Sdim    break;
1105249261Sdim  case ObjCIvarDecl::Private:
1106249261Sdim    OS << " private";
1107249261Sdim    break;
1108249261Sdim  case ObjCIvarDecl::Protected:
1109249261Sdim    OS << " protected";
1110249261Sdim    break;
1111249261Sdim  case ObjCIvarDecl::Public:
1112249261Sdim    OS << " public";
1113249261Sdim    break;
1114249261Sdim  case ObjCIvarDecl::Package:
1115249261Sdim    OS << " package";
1116249261Sdim    break;
1117249261Sdim  }
1118249261Sdim}
1119249261Sdim
1120249261Sdimvoid ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
1121249261Sdim  if (D->isInstanceMethod())
1122249261Sdim    OS << " -";
1123249261Sdim  else
1124249261Sdim    OS << " +";
1125249261Sdim  dumpName(D);
1126249261Sdim  dumpType(D->getResultType());
1127249261Sdim
1128249261Sdim  bool OldMoreChildren = hasMoreChildren();
1129249261Sdim  bool IsVariadic = D->isVariadic();
1130249261Sdim  bool HasBody = D->hasBody();
1131249261Sdim
1132249261Sdim  setMoreChildren(OldMoreChildren || IsVariadic || HasBody);
1133249261Sdim  if (D->isThisDeclarationADefinition()) {
1134249261Sdim    lastChild();
1135249261Sdim    dumpDeclContext(D);
1136249261Sdim  } else {
1137249261Sdim    for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
1138249261Sdim                                              E = D->param_end();
1139249261Sdim         I != E; ++I) {
1140249261Sdim      if (I + 1 == E)
1141249261Sdim        lastChild();
1142249261Sdim      dumpDecl(*I);
1143249261Sdim    }
1144249261Sdim  }
1145249261Sdim
1146249261Sdim  setMoreChildren(OldMoreChildren || HasBody);
1147249261Sdim  if (IsVariadic) {
1148249261Sdim    lastChild();
1149249261Sdim    IndentScope Indent(*this);
1150249261Sdim    OS << "...";
1151249261Sdim  }
1152249261Sdim
1153249261Sdim  setMoreChildren(OldMoreChildren);
1154249261Sdim  if (HasBody) {
1155249261Sdim    lastChild();
1156249261Sdim    dumpStmt(D->getBody());
1157249261Sdim  }
1158249261Sdim}
1159249261Sdim
1160249261Sdimvoid ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
1161249261Sdim  dumpName(D);
1162249261Sdim  dumpDeclRef(D->getClassInterface());
1163249261Sdim  if (D->protocol_begin() == D->protocol_end())
1164249261Sdim    lastChild();
1165249261Sdim  dumpDeclRef(D->getImplementation());
1166249261Sdim  for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
1167249261Sdim                                           E = D->protocol_end();
1168249261Sdim       I != E; ++I) {
1169249261Sdim    if (I + 1 == E)
1170249261Sdim      lastChild();
1171249261Sdim    dumpDeclRef(*I);
1172249261Sdim  }
1173249261Sdim}
1174249261Sdim
1175249261Sdimvoid ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
1176249261Sdim  dumpName(D);
1177249261Sdim  dumpDeclRef(D->getClassInterface());
1178249261Sdim  lastChild();
1179249261Sdim  dumpDeclRef(D->getCategoryDecl());
1180249261Sdim}
1181249261Sdim
1182249261Sdimvoid ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
1183249261Sdim  dumpName(D);
1184249261Sdim  for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
1185249261Sdim                                           E = D->protocol_end();
1186249261Sdim       I != E; ++I) {
1187249261Sdim    if (I + 1 == E)
1188249261Sdim      lastChild();
1189249261Sdim    dumpDeclRef(*I);
1190249261Sdim  }
1191249261Sdim}
1192249261Sdim
1193249261Sdimvoid ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
1194249261Sdim  dumpName(D);
1195249261Sdim  dumpDeclRef(D->getSuperClass(), "super");
1196249261Sdim  if (D->protocol_begin() == D->protocol_end())
1197249261Sdim    lastChild();
1198249261Sdim  dumpDeclRef(D->getImplementation());
1199249261Sdim  for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1200249261Sdim                                            E = D->protocol_end();
1201249261Sdim       I != E; ++I) {
1202249261Sdim    if (I + 1 == E)
1203249261Sdim      lastChild();
1204249261Sdim    dumpDeclRef(*I);
1205249261Sdim  }
1206249261Sdim}
1207249261Sdim
1208249261Sdimvoid ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
1209249261Sdim  dumpName(D);
1210249261Sdim  dumpDeclRef(D->getSuperClass(), "super");
1211249261Sdim  if (D->init_begin() == D->init_end())
1212249261Sdim    lastChild();
1213249261Sdim  dumpDeclRef(D->getClassInterface());
1214249261Sdim  for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
1215249261Sdim                                                   E = D->init_end();
1216249261Sdim       I != E; ++I) {
1217249261Sdim    if (I + 1 == E)
1218249261Sdim      lastChild();
1219249261Sdim    dumpCXXCtorInitializer(*I);
1220249261Sdim  }
1221249261Sdim}
1222249261Sdim
1223249261Sdimvoid ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
1224249261Sdim  dumpName(D);
1225249261Sdim  lastChild();
1226249261Sdim  dumpDeclRef(D->getClassInterface());
1227249261Sdim}
1228249261Sdim
1229249261Sdimvoid ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
1230249261Sdim  dumpName(D);
1231249261Sdim  dumpType(D->getType());
1232249261Sdim
1233249261Sdim  if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
1234249261Sdim    OS << " required";
1235249261Sdim  else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
1236249261Sdim    OS << " optional";
1237249261Sdim
1238249261Sdim  ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
1239249261Sdim  if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
1240249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
1241249261Sdim      OS << " readonly";
1242249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
1243249261Sdim      OS << " assign";
1244249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
1245249261Sdim      OS << " readwrite";
1246249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
1247249261Sdim      OS << " retain";
1248249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
1249249261Sdim      OS << " copy";
1250249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
1251249261Sdim      OS << " nonatomic";
1252249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
1253249261Sdim      OS << " atomic";
1254249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
1255249261Sdim      OS << " weak";
1256249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
1257249261Sdim      OS << " strong";
1258249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
1259249261Sdim      OS << " unsafe_unretained";
1260249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) {
1261249261Sdim      if (!(Attrs & ObjCPropertyDecl::OBJC_PR_setter))
1262249261Sdim        lastChild();
1263249261Sdim      dumpDeclRef(D->getGetterMethodDecl(), "getter");
1264249261Sdim    }
1265249261Sdim    if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) {
1266249261Sdim      lastChild();
1267249261Sdim      dumpDeclRef(D->getSetterMethodDecl(), "setter");
1268249261Sdim    }
1269249261Sdim  }
1270249261Sdim}
1271249261Sdim
1272249261Sdimvoid ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
1273249261Sdim  dumpName(D->getPropertyDecl());
1274249261Sdim  if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
1275249261Sdim    OS << " synthesize";
1276249261Sdim  else
1277249261Sdim    OS << " dynamic";
1278249261Sdim  dumpDeclRef(D->getPropertyDecl());
1279249261Sdim  lastChild();
1280249261Sdim  dumpDeclRef(D->getPropertyIvarDecl());
1281249261Sdim}
1282249261Sdim
1283249261Sdimvoid ASTDumper::VisitBlockDecl(const BlockDecl *D) {
1284249261Sdim  for (BlockDecl::param_const_iterator I = D->param_begin(), E = D->param_end();
1285249261Sdim       I != E; ++I)
1286249261Sdim    dumpDecl(*I);
1287249261Sdim
1288249261Sdim  if (D->isVariadic()) {
1289249261Sdim    IndentScope Indent(*this);
1290249261Sdim    OS << "...";
1291249261Sdim  }
1292249261Sdim
1293249261Sdim  if (D->capturesCXXThis()) {
1294249261Sdim    IndentScope Indent(*this);
1295249261Sdim    OS << "capture this";
1296249261Sdim  }
1297249261Sdim  for (BlockDecl::capture_iterator I = D->capture_begin(), E = D->capture_end();
1298249261Sdim       I != E; ++I) {
1299249261Sdim    IndentScope Indent(*this);
1300249261Sdim    OS << "capture";
1301249261Sdim    if (I->isByRef())
1302249261Sdim      OS << " byref";
1303249261Sdim    if (I->isNested())
1304249261Sdim      OS << " nested";
1305249261Sdim    if (I->getVariable()) {
1306249261Sdim      OS << ' ';
1307249261Sdim      dumpBareDeclRef(I->getVariable());
1308249261Sdim    }
1309249261Sdim    if (I->hasCopyExpr())
1310249261Sdim      dumpStmt(I->getCopyExpr());
1311249261Sdim  }
1312249261Sdim  lastChild();
1313249261Sdim  dumpStmt(D->getBody());
1314249261Sdim}
1315249261Sdim
1316249261Sdim//===----------------------------------------------------------------------===//
1317249261Sdim//  Stmt dumping methods.
1318249261Sdim//===----------------------------------------------------------------------===//
1319249261Sdim
1320249261Sdimvoid ASTDumper::dumpStmt(const Stmt *S) {
1321249261Sdim  IndentScope Indent(*this);
1322249261Sdim
1323249261Sdim  if (!S) {
1324249261Sdim    ColorScope Color(*this, NullColor);
1325249261Sdim    OS << "<<<NULL>>>";
1326249261Sdim    return;
1327249261Sdim  }
1328249261Sdim
1329249261Sdim  if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
1330249261Sdim    VisitDeclStmt(DS);
1331249261Sdim    return;
1332249261Sdim  }
1333249261Sdim
1334249261Sdim  setMoreChildren(S->children());
1335249261Sdim  ConstStmtVisitor<ASTDumper>::Visit(S);
1336249261Sdim  setMoreChildren(false);
1337249261Sdim  for (Stmt::const_child_range CI = S->children(); CI; ++CI) {
1338249261Sdim    Stmt::const_child_range Next = CI;
1339249261Sdim    ++Next;
1340249261Sdim    if (!Next)
1341249261Sdim      lastChild();
1342249261Sdim    dumpStmt(*CI);
1343249261Sdim  }
1344249261Sdim}
1345249261Sdim
1346249261Sdimvoid ASTDumper::VisitStmt(const Stmt *Node) {
1347249261Sdim  {
1348249261Sdim    ColorScope Color(*this, StmtColor);
1349249261Sdim    OS << Node->getStmtClassName();
1350249261Sdim  }
1351249261Sdim  dumpPointer(Node);
1352249261Sdim  dumpSourceRange(Node->getSourceRange());
1353249261Sdim}
1354249261Sdim
1355249261Sdimvoid ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
1356249261Sdim  VisitStmt(Node);
1357249261Sdim  for (DeclStmt::const_decl_iterator I = Node->decl_begin(),
1358249261Sdim                                     E = Node->decl_end();
1359249261Sdim       I != E; ++I) {
1360249261Sdim    if (I + 1 == E)
1361249261Sdim      lastChild();
1362249261Sdim    dumpDecl(*I);
1363249261Sdim  }
1364249261Sdim}
1365249261Sdim
1366249261Sdimvoid ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) {
1367249261Sdim  VisitStmt(Node);
1368249261Sdim  for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(),
1369249261Sdim                                        E = Node->getAttrs().end();
1370249261Sdim       I != E; ++I) {
1371249261Sdim    if (I + 1 == E)
1372249261Sdim      lastChild();
1373249261Sdim    dumpAttr(*I);
1374249261Sdim  }
1375249261Sdim}
1376249261Sdim
1377249261Sdimvoid ASTDumper::VisitLabelStmt(const LabelStmt *Node) {
1378249261Sdim  VisitStmt(Node);
1379249261Sdim  OS << " '" << Node->getName() << "'";
1380249261Sdim}
1381249261Sdim
1382249261Sdimvoid ASTDumper::VisitGotoStmt(const GotoStmt *Node) {
1383249261Sdim  VisitStmt(Node);
1384249261Sdim  OS << " '" << Node->getLabel()->getName() << "'";
1385249261Sdim  dumpPointer(Node->getLabel());
1386249261Sdim}
1387249261Sdim
1388249261Sdim//===----------------------------------------------------------------------===//
1389249261Sdim//  Expr dumping methods.
1390249261Sdim//===----------------------------------------------------------------------===//
1391249261Sdim
1392249261Sdimvoid ASTDumper::VisitExpr(const Expr *Node) {
1393249261Sdim  VisitStmt(Node);
1394249261Sdim  dumpType(Node->getType());
1395249261Sdim
1396249261Sdim  {
1397249261Sdim    ColorScope Color(*this, ValueKindColor);
1398249261Sdim    switch (Node->getValueKind()) {
1399249261Sdim    case VK_RValue:
1400249261Sdim      break;
1401249261Sdim    case VK_LValue:
1402249261Sdim      OS << " lvalue";
1403249261Sdim      break;
1404249261Sdim    case VK_XValue:
1405249261Sdim      OS << " xvalue";
1406249261Sdim      break;
1407249261Sdim    }
1408249261Sdim  }
1409249261Sdim
1410249261Sdim  {
1411249261Sdim    ColorScope Color(*this, ObjectKindColor);
1412249261Sdim    switch (Node->getObjectKind()) {
1413249261Sdim    case OK_Ordinary:
1414249261Sdim      break;
1415249261Sdim    case OK_BitField:
1416249261Sdim      OS << " bitfield";
1417249261Sdim      break;
1418249261Sdim    case OK_ObjCProperty:
1419249261Sdim      OS << " objcproperty";
1420249261Sdim      break;
1421249261Sdim    case OK_ObjCSubscript:
1422249261Sdim      OS << " objcsubscript";
1423249261Sdim      break;
1424249261Sdim    case OK_VectorComponent:
1425249261Sdim      OS << " vectorcomponent";
1426249261Sdim      break;
1427249261Sdim    }
1428249261Sdim  }
1429249261Sdim}
1430249261Sdim
1431249261Sdimstatic void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
1432249261Sdim  if (Node->path_empty())
1433249261Sdim    return;
1434249261Sdim
1435249261Sdim  OS << " (";
1436249261Sdim  bool First = true;
1437249261Sdim  for (CastExpr::path_const_iterator I = Node->path_begin(),
1438249261Sdim                                     E = Node->path_end();
1439249261Sdim       I != E; ++I) {
1440249261Sdim    const CXXBaseSpecifier *Base = *I;
1441249261Sdim    if (!First)
1442249261Sdim      OS << " -> ";
1443249261Sdim
1444249261Sdim    const CXXRecordDecl *RD =
1445249261Sdim    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
1446249261Sdim
1447249261Sdim    if (Base->isVirtual())
1448249261Sdim      OS << "virtual ";
1449249261Sdim    OS << RD->getName();
1450249261Sdim    First = false;
1451249261Sdim  }
1452249261Sdim
1453249261Sdim  OS << ')';
1454249261Sdim}
1455249261Sdim
1456249261Sdimvoid ASTDumper::VisitCastExpr(const CastExpr *Node) {
1457249261Sdim  VisitExpr(Node);
1458249261Sdim  OS << " <";
1459249261Sdim  {
1460249261Sdim    ColorScope Color(*this, CastColor);
1461249261Sdim    OS << Node->getCastKindName();
1462249261Sdim  }
1463249261Sdim  dumpBasePath(OS, Node);
1464249261Sdim  OS << ">";
1465249261Sdim}
1466249261Sdim
1467249261Sdimvoid ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1468249261Sdim  VisitExpr(Node);
1469249261Sdim
1470249261Sdim  OS << " ";
1471249261Sdim  dumpBareDeclRef(Node->getDecl());
1472249261Sdim  if (Node->getDecl() != Node->getFoundDecl()) {
1473249261Sdim    OS << " (";
1474249261Sdim    dumpBareDeclRef(Node->getFoundDecl());
1475249261Sdim    OS << ")";
1476249261Sdim  }
1477249261Sdim}
1478249261Sdim
1479249261Sdimvoid ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) {
1480249261Sdim  VisitExpr(Node);
1481249261Sdim  OS << " (";
1482249261Sdim  if (!Node->requiresADL())
1483249261Sdim    OS << "no ";
1484249261Sdim  OS << "ADL) = '" << Node->getName() << '\'';
1485249261Sdim
1486249261Sdim  UnresolvedLookupExpr::decls_iterator
1487249261Sdim    I = Node->decls_begin(), E = Node->decls_end();
1488249261Sdim  if (I == E)
1489249261Sdim    OS << " empty";
1490249261Sdim  for (; I != E; ++I)
1491249261Sdim    dumpPointer(*I);
1492249261Sdim}
1493249261Sdim
1494249261Sdimvoid ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
1495249261Sdim  VisitExpr(Node);
1496249261Sdim
1497249261Sdim  {
1498249261Sdim    ColorScope Color(*this, DeclKindNameColor);
1499249261Sdim    OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
1500249261Sdim  }
1501249261Sdim  OS << "='" << *Node->getDecl() << "'";
1502249261Sdim  dumpPointer(Node->getDecl());
1503249261Sdim  if (Node->isFreeIvar())
1504249261Sdim    OS << " isFreeIvar";
1505249261Sdim}
1506249261Sdim
1507249261Sdimvoid ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
1508249261Sdim  VisitExpr(Node);
1509249261Sdim  switch (Node->getIdentType()) {
1510249261Sdim  default: llvm_unreachable("unknown case");
1511249261Sdim  case PredefinedExpr::Func:           OS <<  " __func__"; break;
1512249261Sdim  case PredefinedExpr::Function:       OS <<  " __FUNCTION__"; break;
1513249261Sdim  case PredefinedExpr::LFunction:      OS <<  " L__FUNCTION__"; break;
1514249261Sdim  case PredefinedExpr::PrettyFunction: OS <<  " __PRETTY_FUNCTION__";break;
1515249261Sdim  }
1516249261Sdim}
1517249261Sdim
1518249261Sdimvoid ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1519249261Sdim  VisitExpr(Node);
1520249261Sdim  ColorScope Color(*this, ValueColor);
1521249261Sdim  OS << " " << Node->getValue();
1522249261Sdim}
1523249261Sdim
1524249261Sdimvoid ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1525249261Sdim  VisitExpr(Node);
1526249261Sdim
1527249261Sdim  bool isSigned = Node->getType()->isSignedIntegerType();
1528249261Sdim  ColorScope Color(*this, ValueColor);
1529249261Sdim  OS << " " << Node->getValue().toString(10, isSigned);
1530249261Sdim}
1531249261Sdim
1532249261Sdimvoid ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1533249261Sdim  VisitExpr(Node);
1534249261Sdim  ColorScope Color(*this, ValueColor);
1535249261Sdim  OS << " " << Node->getValueAsApproximateDouble();
1536249261Sdim}
1537249261Sdim
1538249261Sdimvoid ASTDumper::VisitStringLiteral(const StringLiteral *Str) {
1539249261Sdim  VisitExpr(Str);
1540249261Sdim  ColorScope Color(*this, ValueColor);
1541249261Sdim  OS << " ";
1542249261Sdim  Str->outputString(OS);
1543249261Sdim}
1544249261Sdim
1545249261Sdimvoid ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1546249261Sdim  VisitExpr(Node);
1547249261Sdim  OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
1548249261Sdim     << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1549249261Sdim}
1550249261Sdim
1551249261Sdimvoid ASTDumper::VisitUnaryExprOrTypeTraitExpr(
1552249261Sdim    const UnaryExprOrTypeTraitExpr *Node) {
1553249261Sdim  VisitExpr(Node);
1554249261Sdim  switch(Node->getKind()) {
1555249261Sdim  case UETT_SizeOf:
1556249261Sdim    OS << " sizeof";
1557249261Sdim    break;
1558249261Sdim  case UETT_AlignOf:
1559249261Sdim    OS << " alignof";
1560249261Sdim    break;
1561249261Sdim  case UETT_VecStep:
1562249261Sdim    OS << " vec_step";
1563249261Sdim    break;
1564249261Sdim  }
1565249261Sdim  if (Node->isArgumentType())
1566249261Sdim    dumpType(Node->getArgumentType());
1567249261Sdim}
1568249261Sdim
1569249261Sdimvoid ASTDumper::VisitMemberExpr(const MemberExpr *Node) {
1570249261Sdim  VisitExpr(Node);
1571249261Sdim  OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
1572249261Sdim  dumpPointer(Node->getMemberDecl());
1573249261Sdim}
1574249261Sdim
1575249261Sdimvoid ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) {
1576249261Sdim  VisitExpr(Node);
1577249261Sdim  OS << " " << Node->getAccessor().getNameStart();
1578249261Sdim}
1579249261Sdim
1580249261Sdimvoid ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1581249261Sdim  VisitExpr(Node);
1582249261Sdim  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1583249261Sdim}
1584249261Sdim
1585249261Sdimvoid ASTDumper::VisitCompoundAssignOperator(
1586249261Sdim    const CompoundAssignOperator *Node) {
1587249261Sdim  VisitExpr(Node);
1588249261Sdim  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1589249261Sdim     << "' ComputeLHSTy=";
1590249261Sdim  dumpBareType(Node->getComputationLHSType());
1591249261Sdim  OS << " ComputeResultTy=";
1592249261Sdim  dumpBareType(Node->getComputationResultType());
1593249261Sdim}
1594249261Sdim
1595249261Sdimvoid ASTDumper::VisitBlockExpr(const BlockExpr *Node) {
1596249261Sdim  VisitExpr(Node);
1597249261Sdim  dumpDecl(Node->getBlockDecl());
1598249261Sdim}
1599249261Sdim
1600249261Sdimvoid ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
1601249261Sdim  VisitExpr(Node);
1602249261Sdim
1603249261Sdim  if (Expr *Source = Node->getSourceExpr()) {
1604249261Sdim    lastChild();
1605249261Sdim    dumpStmt(Source);
1606249261Sdim  }
1607249261Sdim}
1608249261Sdim
1609249261Sdim// GNU extensions.
1610249261Sdim
1611249261Sdimvoid ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
1612249261Sdim  VisitExpr(Node);
1613249261Sdim  OS << " " << Node->getLabel()->getName();
1614249261Sdim  dumpPointer(Node->getLabel());
1615249261Sdim}
1616249261Sdim
1617249261Sdim//===----------------------------------------------------------------------===//
1618249261Sdim// C++ Expressions
1619249261Sdim//===----------------------------------------------------------------------===//
1620249261Sdim
1621249261Sdimvoid ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
1622249261Sdim  VisitExpr(Node);
1623249261Sdim  OS << " " << Node->getCastName()
1624249261Sdim     << "<" << Node->getTypeAsWritten().getAsString() << ">"
1625249261Sdim     << " <" << Node->getCastKindName();
1626249261Sdim  dumpBasePath(OS, Node);
1627249261Sdim  OS << ">";
1628249261Sdim}
1629249261Sdim
1630249261Sdimvoid ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1631249261Sdim  VisitExpr(Node);
1632249261Sdim  OS << " " << (Node->getValue() ? "true" : "false");
1633249261Sdim}
1634249261Sdim
1635249261Sdimvoid ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1636249261Sdim  VisitExpr(Node);
1637249261Sdim  OS << " this";
1638249261Sdim}
1639249261Sdim
1640249261Sdimvoid ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) {
1641249261Sdim  VisitExpr(Node);
1642249261Sdim  OS << " functional cast to " << Node->getTypeAsWritten().getAsString()
1643249261Sdim     << " <" << Node->getCastKindName() << ">";
1644249261Sdim}
1645249261Sdim
1646249261Sdimvoid ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1647249261Sdim  VisitExpr(Node);
1648249261Sdim  CXXConstructorDecl *Ctor = Node->getConstructor();
1649249261Sdim  dumpType(Ctor->getType());
1650249261Sdim  if (Node->isElidable())
1651249261Sdim    OS << " elidable";
1652249261Sdim  if (Node->requiresZeroInitialization())
1653249261Sdim    OS << " zeroing";
1654249261Sdim}
1655249261Sdim
1656249261Sdimvoid ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) {
1657249261Sdim  VisitExpr(Node);
1658249261Sdim  OS << " ";
1659249261Sdim  dumpCXXTemporary(Node->getTemporary());
1660249261Sdim}
1661249261Sdim
1662249261Sdimvoid ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
1663249261Sdim  VisitExpr(Node);
1664249261Sdim  for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
1665249261Sdim    dumpDeclRef(Node->getObject(i), "cleanup");
1666249261Sdim}
1667249261Sdim
1668249261Sdimvoid ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
1669249261Sdim  OS << "(CXXTemporary";
1670249261Sdim  dumpPointer(Temporary);
1671249261Sdim  OS << ")";
1672249261Sdim}
1673249261Sdim
1674249261Sdim//===----------------------------------------------------------------------===//
1675249261Sdim// Obj-C Expressions
1676249261Sdim//===----------------------------------------------------------------------===//
1677249261Sdim
1678249261Sdimvoid ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
1679249261Sdim  VisitExpr(Node);
1680249261Sdim  OS << " selector=" << Node->getSelector().getAsString();
1681249261Sdim  switch (Node->getReceiverKind()) {
1682249261Sdim  case ObjCMessageExpr::Instance:
1683249261Sdim    break;
1684249261Sdim
1685249261Sdim  case ObjCMessageExpr::Class:
1686249261Sdim    OS << " class=";
1687249261Sdim    dumpBareType(Node->getClassReceiver());
1688249261Sdim    break;
1689249261Sdim
1690249261Sdim  case ObjCMessageExpr::SuperInstance:
1691249261Sdim    OS << " super (instance)";
1692249261Sdim    break;
1693249261Sdim
1694249261Sdim  case ObjCMessageExpr::SuperClass:
1695249261Sdim    OS << " super (class)";
1696249261Sdim    break;
1697249261Sdim  }
1698249261Sdim}
1699249261Sdim
1700249261Sdimvoid ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
1701249261Sdim  VisitExpr(Node);
1702249261Sdim  OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString();
1703249261Sdim}
1704249261Sdim
1705249261Sdimvoid ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
1706249261Sdim  VisitStmt(Node);
1707249261Sdim  if (const VarDecl *CatchParam = Node->getCatchParamDecl())
1708249261Sdim    dumpDecl(CatchParam);
1709249261Sdim  else
1710249261Sdim    OS << " catch all";
1711249261Sdim}
1712249261Sdim
1713249261Sdimvoid ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
1714249261Sdim  VisitExpr(Node);
1715249261Sdim  dumpType(Node->getEncodedType());
1716249261Sdim}
1717249261Sdim
1718249261Sdimvoid ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1719249261Sdim  VisitExpr(Node);
1720249261Sdim
1721249261Sdim  OS << " " << Node->getSelector().getAsString();
1722249261Sdim}
1723249261Sdim
1724249261Sdimvoid ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
1725249261Sdim  VisitExpr(Node);
1726249261Sdim
1727249261Sdim  OS << ' ' << *Node->getProtocol();
1728249261Sdim}
1729249261Sdim
1730249261Sdimvoid ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
1731249261Sdim  VisitExpr(Node);
1732249261Sdim  if (Node->isImplicitProperty()) {
1733249261Sdim    OS << " Kind=MethodRef Getter=\"";
1734249261Sdim    if (Node->getImplicitPropertyGetter())
1735249261Sdim      OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
1736249261Sdim    else
1737249261Sdim      OS << "(null)";
1738249261Sdim
1739249261Sdim    OS << "\" Setter=\"";
1740249261Sdim    if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
1741249261Sdim      OS << Setter->getSelector().getAsString();
1742249261Sdim    else
1743249261Sdim      OS << "(null)";
1744249261Sdim    OS << "\"";
1745249261Sdim  } else {
1746249261Sdim    OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"';
1747249261Sdim  }
1748249261Sdim
1749249261Sdim  if (Node->isSuperReceiver())
1750249261Sdim    OS << " super";
1751249261Sdim
1752249261Sdim  OS << " Messaging=";
1753249261Sdim  if (Node->isMessagingGetter() && Node->isMessagingSetter())
1754249261Sdim    OS << "Getter&Setter";
1755249261Sdim  else if (Node->isMessagingGetter())
1756249261Sdim    OS << "Getter";
1757249261Sdim  else if (Node->isMessagingSetter())
1758249261Sdim    OS << "Setter";
1759249261Sdim}
1760249261Sdim
1761249261Sdimvoid ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
1762249261Sdim  VisitExpr(Node);
1763249261Sdim  if (Node->isArraySubscriptRefExpr())
1764249261Sdim    OS << " Kind=ArraySubscript GetterForArray=\"";
1765249261Sdim  else
1766249261Sdim    OS << " Kind=DictionarySubscript GetterForDictionary=\"";
1767249261Sdim  if (Node->getAtIndexMethodDecl())
1768249261Sdim    OS << Node->getAtIndexMethodDecl()->getSelector().getAsString();
1769249261Sdim  else
1770249261Sdim    OS << "(null)";
1771249261Sdim
1772249261Sdim  if (Node->isArraySubscriptRefExpr())
1773249261Sdim    OS << "\" SetterForArray=\"";
1774249261Sdim  else
1775249261Sdim    OS << "\" SetterForDictionary=\"";
1776249261Sdim  if (Node->setAtIndexMethodDecl())
1777249261Sdim    OS << Node->setAtIndexMethodDecl()->getSelector().getAsString();
1778249261Sdim  else
1779249261Sdim    OS << "(null)";
1780249261Sdim}
1781249261Sdim
1782249261Sdimvoid ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
1783249261Sdim  VisitExpr(Node);
1784249261Sdim  OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
1785249261Sdim}
1786249261Sdim
1787249261Sdim//===----------------------------------------------------------------------===//
1788249261Sdim// Comments
1789249261Sdim//===----------------------------------------------------------------------===//
1790249261Sdim
1791249261Sdimconst char *ASTDumper::getCommandName(unsigned CommandID) {
1792249261Sdim  if (Traits)
1793249261Sdim    return Traits->getCommandInfo(CommandID)->Name;
1794249261Sdim  const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
1795249261Sdim  if (Info)
1796249261Sdim    return Info->Name;
1797249261Sdim  return "<not a builtin command>";
1798249261Sdim}
1799249261Sdim
1800249261Sdimvoid ASTDumper::dumpFullComment(const FullComment *C) {
1801249261Sdim  if (!C)
1802249261Sdim    return;
1803249261Sdim
1804249261Sdim  FC = C;
1805249261Sdim  dumpComment(C);
1806249261Sdim  FC = 0;
1807249261Sdim}
1808249261Sdim
1809249261Sdimvoid ASTDumper::dumpComment(const Comment *C) {
1810249261Sdim  IndentScope Indent(*this);
1811249261Sdim
1812249261Sdim  if (!C) {
1813249261Sdim    ColorScope Color(*this, NullColor);
1814249261Sdim    OS << "<<<NULL>>>";
1815249261Sdim    return;
1816249261Sdim  }
1817249261Sdim
1818249261Sdim  {
1819249261Sdim    ColorScope Color(*this, CommentColor);
1820249261Sdim    OS << C->getCommentKindName();
1821249261Sdim  }
1822249261Sdim  dumpPointer(C);
1823249261Sdim  dumpSourceRange(C->getSourceRange());
1824249261Sdim  ConstCommentVisitor<ASTDumper>::visit(C);
1825249261Sdim  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
1826249261Sdim       I != E; ++I) {
1827249261Sdim    if (I + 1 == E)
1828249261Sdim      lastChild();
1829249261Sdim    dumpComment(*I);
1830249261Sdim  }
1831249261Sdim}
1832249261Sdim
1833249261Sdimvoid ASTDumper::visitTextComment(const TextComment *C) {
1834249261Sdim  OS << " Text=\"" << C->getText() << "\"";
1835249261Sdim}
1836249261Sdim
1837249261Sdimvoid ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) {
1838249261Sdim  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
1839249261Sdim  switch (C->getRenderKind()) {
1840249261Sdim  case InlineCommandComment::RenderNormal:
1841249261Sdim    OS << " RenderNormal";
1842249261Sdim    break;
1843249261Sdim  case InlineCommandComment::RenderBold:
1844249261Sdim    OS << " RenderBold";
1845249261Sdim    break;
1846249261Sdim  case InlineCommandComment::RenderMonospaced:
1847249261Sdim    OS << " RenderMonospaced";
1848249261Sdim    break;
1849249261Sdim  case InlineCommandComment::RenderEmphasized:
1850249261Sdim    OS << " RenderEmphasized";
1851249261Sdim    break;
1852249261Sdim  }
1853249261Sdim
1854249261Sdim  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
1855249261Sdim    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
1856249261Sdim}
1857249261Sdim
1858249261Sdimvoid ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
1859249261Sdim  OS << " Name=\"" << C->getTagName() << "\"";
1860249261Sdim  if (C->getNumAttrs() != 0) {
1861249261Sdim    OS << " Attrs: ";
1862249261Sdim    for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
1863249261Sdim      const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
1864249261Sdim      OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
1865249261Sdim    }
1866249261Sdim  }
1867249261Sdim  if (C->isSelfClosing())
1868249261Sdim    OS << " SelfClosing";
1869249261Sdim}
1870249261Sdim
1871249261Sdimvoid ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
1872249261Sdim  OS << " Name=\"" << C->getTagName() << "\"";
1873249261Sdim}
1874249261Sdim
1875249261Sdimvoid ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) {
1876249261Sdim  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
1877249261Sdim  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
1878249261Sdim    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
1879249261Sdim}
1880249261Sdim
1881249261Sdimvoid ASTDumper::visitParamCommandComment(const ParamCommandComment *C) {
1882249261Sdim  OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
1883249261Sdim
1884249261Sdim  if (C->isDirectionExplicit())
1885249261Sdim    OS << " explicitly";
1886249261Sdim  else
1887249261Sdim    OS << " implicitly";
1888249261Sdim
1889249261Sdim  if (C->hasParamName()) {
1890249261Sdim    if (C->isParamIndexValid())
1891249261Sdim      OS << " Param=\"" << C->getParamName(FC) << "\"";
1892249261Sdim    else
1893249261Sdim      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
1894249261Sdim  }
1895249261Sdim
1896249261Sdim  if (C->isParamIndexValid())
1897249261Sdim    OS << " ParamIndex=" << C->getParamIndex();
1898249261Sdim}
1899249261Sdim
1900249261Sdimvoid ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) {
1901249261Sdim  if (C->hasParamName()) {
1902249261Sdim    if (C->isPositionValid())
1903249261Sdim      OS << " Param=\"" << C->getParamName(FC) << "\"";
1904249261Sdim    else
1905249261Sdim      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
1906249261Sdim  }
1907249261Sdim
1908249261Sdim  if (C->isPositionValid()) {
1909249261Sdim    OS << " Position=<";
1910249261Sdim    for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
1911249261Sdim      OS << C->getIndex(i);
1912249261Sdim      if (i != e - 1)
1913249261Sdim        OS << ", ";
1914249261Sdim    }
1915249261Sdim    OS << ">";
1916249261Sdim  }
1917249261Sdim}
1918249261Sdim
1919249261Sdimvoid ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
1920249261Sdim  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
1921249261Sdim        " CloseName=\"" << C->getCloseName() << "\"";
1922249261Sdim}
1923249261Sdim
1924249261Sdimvoid ASTDumper::visitVerbatimBlockLineComment(
1925249261Sdim    const VerbatimBlockLineComment *C) {
1926249261Sdim  OS << " Text=\"" << C->getText() << "\"";
1927249261Sdim}
1928249261Sdim
1929249261Sdimvoid ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
1930249261Sdim  OS << " Text=\"" << C->getText() << "\"";
1931249261Sdim}
1932249261Sdim
1933249261Sdim//===----------------------------------------------------------------------===//
1934249261Sdim// Decl method implementations
1935249261Sdim//===----------------------------------------------------------------------===//
1936249261Sdim
1937249261Sdimvoid Decl::dump() const {
1938249261Sdim  dump(llvm::errs());
1939249261Sdim}
1940249261Sdim
1941249261Sdimvoid Decl::dump(raw_ostream &OS) const {
1942249261Sdim  ASTDumper P(OS, &getASTContext().getCommentCommandTraits(),
1943249261Sdim              &getASTContext().getSourceManager());
1944249261Sdim  P.dumpDecl(this);
1945249261Sdim}
1946249261Sdim
1947249261Sdimvoid Decl::dumpColor() const {
1948249261Sdim  ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(),
1949249261Sdim              &getASTContext().getSourceManager(), /*ShowColors*/true);
1950249261Sdim  P.dumpDecl(this);
1951249261Sdim}
1952249261Sdim//===----------------------------------------------------------------------===//
1953249261Sdim// Stmt method implementations
1954249261Sdim//===----------------------------------------------------------------------===//
1955249261Sdim
1956249261Sdimvoid Stmt::dump(SourceManager &SM) const {
1957249261Sdim  dump(llvm::errs(), SM);
1958249261Sdim}
1959249261Sdim
1960249261Sdimvoid Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
1961249261Sdim  ASTDumper P(OS, 0, &SM);
1962249261Sdim  P.dumpStmt(this);
1963249261Sdim}
1964249261Sdim
1965249261Sdimvoid Stmt::dump() const {
1966249261Sdim  ASTDumper P(llvm::errs(), 0, 0);
1967249261Sdim  P.dumpStmt(this);
1968249261Sdim}
1969249261Sdim
1970249261Sdimvoid Stmt::dumpColor() const {
1971249261Sdim  ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true);
1972249261Sdim  P.dumpStmt(this);
1973249261Sdim}
1974249261Sdim
1975249261Sdim//===----------------------------------------------------------------------===//
1976249261Sdim// Comment method implementations
1977249261Sdim//===----------------------------------------------------------------------===//
1978249261Sdim
1979249261Sdimvoid Comment::dump() const {
1980249261Sdim  dump(llvm::errs(), 0, 0);
1981249261Sdim}
1982249261Sdim
1983249261Sdimvoid Comment::dump(const ASTContext &Context) const {
1984249261Sdim  dump(llvm::errs(), &Context.getCommentCommandTraits(),
1985249261Sdim       &Context.getSourceManager());
1986249261Sdim}
1987249261Sdim
1988249261Sdimvoid Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
1989249261Sdim                   const SourceManager *SM) const {
1990249261Sdim  const FullComment *FC = dyn_cast<FullComment>(this);
1991249261Sdim  ASTDumper D(OS, Traits, SM);
1992249261Sdim  D.dumpFullComment(FC);
1993249261Sdim}
1994249261Sdim
1995249261Sdimvoid Comment::dumpColor() const {
1996249261Sdim  const FullComment *FC = dyn_cast<FullComment>(this);
1997249261Sdim  ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true);
1998249261Sdim  D.dumpFullComment(FC);
1999249261Sdim}
2000