ASTDumper.cpp revision 280031
1//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the AST dump methods, which dump out the
11// AST in a form that exposes type details and other fields.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Attr.h"
17#include "clang/AST/CommentVisitor.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/DeclLookups.h"
20#include "clang/AST/DeclObjC.h"
21#include "clang/AST/DeclVisitor.h"
22#include "clang/AST/StmtVisitor.h"
23#include "clang/AST/TypeVisitor.h"
24#include "clang/Basic/Module.h"
25#include "clang/Basic/SourceManager.h"
26#include "llvm/Support/raw_ostream.h"
27using namespace clang;
28using namespace clang::comments;
29
30//===----------------------------------------------------------------------===//
31// ASTDumper Visitor
32//===----------------------------------------------------------------------===//
33
34namespace  {
35  // Colors used for various parts of the AST dump
36  // Do not use bold yellow for any text.  It is hard to read on white screens.
37
38  struct TerminalColor {
39    raw_ostream::Colors Color;
40    bool Bold;
41  };
42
43  // Red           - CastColor
44  // Green         - TypeColor
45  // Bold Green    - DeclKindNameColor, UndeserializedColor
46  // Yellow        - AddressColor, LocationColor
47  // Blue          - CommentColor, NullColor, IndentColor
48  // Bold Blue     - AttrColor
49  // Bold Magenta  - StmtColor
50  // Cyan          - ValueKindColor, ObjectKindColor
51  // Bold Cyan     - ValueColor, DeclNameColor
52
53  // Decl kind names (VarDecl, FunctionDecl, etc)
54  static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true };
55  // Attr names (CleanupAttr, GuardedByAttr, etc)
56  static const TerminalColor AttrColor = { raw_ostream::BLUE, true };
57  // Statement names (DeclStmt, ImplicitCastExpr, etc)
58  static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true };
59  // Comment names (FullComment, ParagraphComment, TextComment, etc)
60  static const TerminalColor CommentColor = { raw_ostream::BLUE, false };
61
62  // Type names (int, float, etc, plus user defined types)
63  static const TerminalColor TypeColor = { raw_ostream::GREEN, false };
64
65  // Pointer address
66  static const TerminalColor AddressColor = { raw_ostream::YELLOW, false };
67  // Source locations
68  static const TerminalColor LocationColor = { raw_ostream::YELLOW, false };
69
70  // lvalue/xvalue
71  static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false };
72  // bitfield/objcproperty/objcsubscript/vectorcomponent
73  static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false };
74
75  // Null statements
76  static const TerminalColor NullColor = { raw_ostream::BLUE, false };
77
78  // Undeserialized entities
79  static const TerminalColor UndeserializedColor = { raw_ostream::GREEN, true };
80
81  // CastKind from CastExpr's
82  static const TerminalColor CastColor = { raw_ostream::RED, false };
83
84  // Value of the statement
85  static const TerminalColor ValueColor = { raw_ostream::CYAN, true };
86  // Decl names
87  static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true };
88
89  // Indents ( `, -. | )
90  static const TerminalColor IndentColor = { raw_ostream::BLUE, false };
91
92  class ASTDumper
93      : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>,
94        public ConstCommentVisitor<ASTDumper>, public TypeVisitor<ASTDumper> {
95    raw_ostream &OS;
96    const CommandTraits *Traits;
97    const SourceManager *SM;
98
99    /// Pending[i] is an action to dump an entity at level i.
100    llvm::SmallVector<std::function<void(bool isLastChild)>, 32> Pending;
101
102    /// Indicates whether we're at the top level.
103    bool TopLevel;
104
105    /// Indicates if we're handling the first child after entering a new depth.
106    bool FirstChild;
107
108    /// Prefix for currently-being-dumped entity.
109    std::string Prefix;
110
111    /// Keep track of the last location we print out so that we can
112    /// print out deltas from then on out.
113    const char *LastLocFilename;
114    unsigned LastLocLine;
115
116    /// The \c FullComment parent of the comment being dumped.
117    const FullComment *FC;
118
119    bool ShowColors;
120
121    /// Dump a child of the current node.
122    template<typename Fn> void dumpChild(Fn doDumpChild) {
123      // If we're at the top level, there's nothing interesting to do; just
124      // run the dumper.
125      if (TopLevel) {
126        TopLevel = false;
127        doDumpChild();
128        while (!Pending.empty()) {
129          Pending.back()(true);
130          Pending.pop_back();
131        }
132        Prefix.clear();
133        OS << "\n";
134        TopLevel = true;
135        return;
136      }
137
138      const FullComment *OrigFC = FC;
139      auto dumpWithIndent = [this, doDumpChild, OrigFC](bool isLastChild) {
140        // Print out the appropriate tree structure and work out the prefix for
141        // children of this node. For instance:
142        //
143        //   A        Prefix = ""
144        //   |-B      Prefix = "| "
145        //   | `-C    Prefix = "|   "
146        //   `-D      Prefix = "  "
147        //     |-E    Prefix = "  | "
148        //     `-F    Prefix = "    "
149        //   G        Prefix = ""
150        //
151        // Note that the first level gets no prefix.
152        {
153          OS << '\n';
154          ColorScope Color(*this, IndentColor);
155          OS << Prefix << (isLastChild ? '`' : '|') << '-';
156          this->Prefix.push_back(isLastChild ? ' ' : '|');
157          this->Prefix.push_back(' ');
158        }
159
160        FirstChild = true;
161        unsigned Depth = Pending.size();
162
163        FC = OrigFC;
164        doDumpChild();
165
166        // If any children are left, they're the last at their nesting level.
167        // Dump those ones out now.
168        while (Depth < Pending.size()) {
169          Pending.back()(true);
170          this->Pending.pop_back();
171        }
172
173        // Restore the old prefix.
174        this->Prefix.resize(Prefix.size() - 2);
175      };
176
177      if (FirstChild) {
178        Pending.push_back(std::move(dumpWithIndent));
179      } else {
180        Pending.back()(false);
181        Pending.back() = std::move(dumpWithIndent);
182      }
183      FirstChild = false;
184    }
185
186    class ColorScope {
187      ASTDumper &Dumper;
188    public:
189      ColorScope(ASTDumper &Dumper, TerminalColor Color)
190        : Dumper(Dumper) {
191        if (Dumper.ShowColors)
192          Dumper.OS.changeColor(Color.Color, Color.Bold);
193      }
194      ~ColorScope() {
195        if (Dumper.ShowColors)
196          Dumper.OS.resetColor();
197      }
198    };
199
200  public:
201    ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
202              const SourceManager *SM)
203      : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true),
204        LastLocFilename(""), LastLocLine(~0U), FC(nullptr),
205        ShowColors(SM && SM->getDiagnostics().getShowColors()) { }
206
207    ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
208              const SourceManager *SM, bool ShowColors)
209      : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true),
210        LastLocFilename(""), LastLocLine(~0U),
211        ShowColors(ShowColors) { }
212
213    void dumpDecl(const Decl *D);
214    void dumpStmt(const Stmt *S);
215    void dumpFullComment(const FullComment *C);
216
217    // Utilities
218    void dumpPointer(const void *Ptr);
219    void dumpSourceRange(SourceRange R);
220    void dumpLocation(SourceLocation Loc);
221    void dumpBareType(QualType T, bool Desugar = true);
222    void dumpType(QualType T);
223    void dumpTypeAsChild(QualType T);
224    void dumpTypeAsChild(const Type *T);
225    void dumpBareDeclRef(const Decl *Node);
226    void dumpDeclRef(const Decl *Node, const char *Label = nullptr);
227    void dumpName(const NamedDecl *D);
228    bool hasNodes(const DeclContext *DC);
229    void dumpDeclContext(const DeclContext *DC);
230    void dumpLookups(const DeclContext *DC, bool DumpDecls);
231    void dumpAttr(const Attr *A);
232
233    // C++ Utilities
234    void dumpAccessSpecifier(AccessSpecifier AS);
235    void dumpCXXCtorInitializer(const CXXCtorInitializer *Init);
236    void dumpTemplateParameters(const TemplateParameterList *TPL);
237    void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
238    void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A);
239    void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
240    void dumpTemplateArgument(const TemplateArgument &A,
241                              SourceRange R = SourceRange());
242
243    // Types
244    void VisitComplexType(const ComplexType *T) {
245      dumpTypeAsChild(T->getElementType());
246    }
247    void VisitPointerType(const PointerType *T) {
248      dumpTypeAsChild(T->getPointeeType());
249    }
250    void VisitBlockPointerType(const BlockPointerType *T) {
251      dumpTypeAsChild(T->getPointeeType());
252    }
253    void VisitReferenceType(const ReferenceType *T) {
254      dumpTypeAsChild(T->getPointeeType());
255    }
256    void VisitRValueReferenceType(const ReferenceType *T) {
257      if (T->isSpelledAsLValue())
258        OS << " written as lvalue reference";
259      VisitReferenceType(T);
260    }
261    void VisitMemberPointerType(const MemberPointerType *T) {
262      dumpTypeAsChild(T->getClass());
263      dumpTypeAsChild(T->getPointeeType());
264    }
265    void VisitArrayType(const ArrayType *T) {
266      switch (T->getSizeModifier()) {
267        case ArrayType::Normal: break;
268        case ArrayType::Static: OS << " static"; break;
269        case ArrayType::Star: OS << " *"; break;
270      }
271      OS << " " << T->getIndexTypeQualifiers().getAsString();
272      dumpTypeAsChild(T->getElementType());
273    }
274    void VisitConstantArrayType(const ConstantArrayType *T) {
275      OS << " " << T->getSize();
276      VisitArrayType(T);
277    }
278    void VisitVariableArrayType(const VariableArrayType *T) {
279      OS << " ";
280      dumpSourceRange(T->getBracketsRange());
281      VisitArrayType(T);
282      dumpStmt(T->getSizeExpr());
283    }
284    void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
285      VisitArrayType(T);
286      OS << " ";
287      dumpSourceRange(T->getBracketsRange());
288      dumpStmt(T->getSizeExpr());
289    }
290    void VisitDependentSizedExtVectorType(
291        const DependentSizedExtVectorType *T) {
292      OS << " ";
293      dumpLocation(T->getAttributeLoc());
294      dumpTypeAsChild(T->getElementType());
295      dumpStmt(T->getSizeExpr());
296    }
297    void VisitVectorType(const VectorType *T) {
298      switch (T->getVectorKind()) {
299        case VectorType::GenericVector: break;
300        case VectorType::AltiVecVector: OS << " altivec"; break;
301        case VectorType::AltiVecPixel: OS << " altivec pixel"; break;
302        case VectorType::AltiVecBool: OS << " altivec bool"; break;
303        case VectorType::NeonVector: OS << " neon"; break;
304        case VectorType::NeonPolyVector: OS << " neon poly"; break;
305      }
306      OS << " " << T->getNumElements();
307      dumpTypeAsChild(T->getElementType());
308    }
309    void VisitFunctionType(const FunctionType *T) {
310      auto EI = T->getExtInfo();
311      if (EI.getNoReturn()) OS << " noreturn";
312      if (EI.getProducesResult()) OS << " produces_result";
313      if (EI.getHasRegParm()) OS << " regparm " << EI.getRegParm();
314      OS << " " << FunctionType::getNameForCallConv(EI.getCC());
315      dumpTypeAsChild(T->getReturnType());
316    }
317    void VisitFunctionProtoType(const FunctionProtoType *T) {
318      auto EPI = T->getExtProtoInfo();
319      if (EPI.HasTrailingReturn) OS << " trailing_return";
320      if (T->isConst()) OS << " const";
321      if (T->isVolatile()) OS << " volatile";
322      if (T->isRestrict()) OS << " restrict";
323      switch (EPI.RefQualifier) {
324        case RQ_None: break;
325        case RQ_LValue: OS << " &"; break;
326        case RQ_RValue: OS << " &&"; break;
327      }
328      // FIXME: Exception specification.
329      // FIXME: Consumed parameters.
330      VisitFunctionType(T);
331      for (QualType PT : T->getParamTypes())
332        dumpTypeAsChild(PT);
333      if (EPI.Variadic)
334        dumpChild([=] { OS << "..."; });
335    }
336    void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
337      dumpDeclRef(T->getDecl());
338    }
339    void VisitTypedefType(const TypedefType *T) {
340      dumpDeclRef(T->getDecl());
341    }
342    void VisitTypeOfExprType(const TypeOfExprType *T) {
343      dumpStmt(T->getUnderlyingExpr());
344    }
345    void VisitDecltypeType(const DecltypeType *T) {
346      dumpStmt(T->getUnderlyingExpr());
347    }
348    void VisitUnaryTransformType(const UnaryTransformType *T) {
349      switch (T->getUTTKind()) {
350      case UnaryTransformType::EnumUnderlyingType:
351        OS << " underlying_type";
352        break;
353      }
354      dumpTypeAsChild(T->getBaseType());
355    }
356    void VisitTagType(const TagType *T) {
357      dumpDeclRef(T->getDecl());
358    }
359    void VisitAttributedType(const AttributedType *T) {
360      // FIXME: AttrKind
361      dumpTypeAsChild(T->getModifiedType());
362    }
363    void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
364      OS << " depth " << T->getDepth() << " index " << T->getIndex();
365      if (T->isParameterPack()) OS << " pack";
366      dumpDeclRef(T->getDecl());
367    }
368    void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
369      dumpTypeAsChild(T->getReplacedParameter());
370    }
371    void VisitSubstTemplateTypeParmPackType(
372        const SubstTemplateTypeParmPackType *T) {
373      dumpTypeAsChild(T->getReplacedParameter());
374      dumpTemplateArgument(T->getArgumentPack());
375    }
376    void VisitAutoType(const AutoType *T) {
377      if (T->isDecltypeAuto()) OS << " decltype(auto)";
378      if (!T->isDeduced())
379        OS << " undeduced";
380    }
381    void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
382      if (T->isTypeAlias()) OS << " alias";
383      OS << " "; T->getTemplateName().dump(OS);
384      for (auto &Arg : *T)
385        dumpTemplateArgument(Arg);
386      if (T->isTypeAlias())
387        dumpTypeAsChild(T->getAliasedType());
388    }
389    void VisitInjectedClassNameType(const InjectedClassNameType *T) {
390      dumpDeclRef(T->getDecl());
391    }
392    void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
393      dumpDeclRef(T->getDecl());
394    }
395    void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
396      dumpTypeAsChild(T->getPointeeType());
397    }
398    void VisitAtomicType(const AtomicType *T) {
399      dumpTypeAsChild(T->getValueType());
400    }
401    void VisitAdjustedType(const AdjustedType *T) {
402      dumpTypeAsChild(T->getOriginalType());
403    }
404    void VisitPackExpansionType(const PackExpansionType *T) {
405      if (auto N = T->getNumExpansions()) OS << " expansions " << *N;
406      if (!T->isSugared())
407        dumpTypeAsChild(T->getPattern());
408    }
409    // FIXME: ElaboratedType, DependentNameType,
410    // DependentTemplateSpecializationType, ObjCObjectType
411
412    // Decls
413    void VisitLabelDecl(const LabelDecl *D);
414    void VisitTypedefDecl(const TypedefDecl *D);
415    void VisitEnumDecl(const EnumDecl *D);
416    void VisitRecordDecl(const RecordDecl *D);
417    void VisitEnumConstantDecl(const EnumConstantDecl *D);
418    void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
419    void VisitFunctionDecl(const FunctionDecl *D);
420    void VisitFieldDecl(const FieldDecl *D);
421    void VisitVarDecl(const VarDecl *D);
422    void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D);
423    void VisitImportDecl(const ImportDecl *D);
424
425    // C++ Decls
426    void VisitNamespaceDecl(const NamespaceDecl *D);
427    void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
428    void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
429    void VisitTypeAliasDecl(const TypeAliasDecl *D);
430    void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
431    void VisitCXXRecordDecl(const CXXRecordDecl *D);
432    void VisitStaticAssertDecl(const StaticAssertDecl *D);
433    template<typename SpecializationDecl>
434    void VisitTemplateDeclSpecialization(const SpecializationDecl *D,
435                                         bool DumpExplicitInst,
436                                         bool DumpRefOnly);
437    template<typename TemplateDecl>
438    void VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
439    void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
440    void VisitClassTemplateDecl(const ClassTemplateDecl *D);
441    void VisitClassTemplateSpecializationDecl(
442        const ClassTemplateSpecializationDecl *D);
443    void VisitClassTemplatePartialSpecializationDecl(
444        const ClassTemplatePartialSpecializationDecl *D);
445    void VisitClassScopeFunctionSpecializationDecl(
446        const ClassScopeFunctionSpecializationDecl *D);
447    void VisitVarTemplateDecl(const VarTemplateDecl *D);
448    void VisitVarTemplateSpecializationDecl(
449        const VarTemplateSpecializationDecl *D);
450    void VisitVarTemplatePartialSpecializationDecl(
451        const VarTemplatePartialSpecializationDecl *D);
452    void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
453    void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
454    void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
455    void VisitUsingDecl(const UsingDecl *D);
456    void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
457    void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
458    void VisitUsingShadowDecl(const UsingShadowDecl *D);
459    void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
460    void VisitAccessSpecDecl(const AccessSpecDecl *D);
461    void VisitFriendDecl(const FriendDecl *D);
462
463    // ObjC Decls
464    void VisitObjCIvarDecl(const ObjCIvarDecl *D);
465    void VisitObjCMethodDecl(const ObjCMethodDecl *D);
466    void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
467    void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
468    void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
469    void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
470    void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
471    void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
472    void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
473    void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
474    void VisitBlockDecl(const BlockDecl *D);
475
476    // Stmts.
477    void VisitStmt(const Stmt *Node);
478    void VisitDeclStmt(const DeclStmt *Node);
479    void VisitAttributedStmt(const AttributedStmt *Node);
480    void VisitLabelStmt(const LabelStmt *Node);
481    void VisitGotoStmt(const GotoStmt *Node);
482    void VisitCXXCatchStmt(const CXXCatchStmt *Node);
483
484    // Exprs
485    void VisitExpr(const Expr *Node);
486    void VisitCastExpr(const CastExpr *Node);
487    void VisitDeclRefExpr(const DeclRefExpr *Node);
488    void VisitPredefinedExpr(const PredefinedExpr *Node);
489    void VisitCharacterLiteral(const CharacterLiteral *Node);
490    void VisitIntegerLiteral(const IntegerLiteral *Node);
491    void VisitFloatingLiteral(const FloatingLiteral *Node);
492    void VisitStringLiteral(const StringLiteral *Str);
493    void VisitInitListExpr(const InitListExpr *ILE);
494    void VisitUnaryOperator(const UnaryOperator *Node);
495    void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
496    void VisitMemberExpr(const MemberExpr *Node);
497    void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
498    void VisitBinaryOperator(const BinaryOperator *Node);
499    void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
500    void VisitAddrLabelExpr(const AddrLabelExpr *Node);
501    void VisitBlockExpr(const BlockExpr *Node);
502    void VisitOpaqueValueExpr(const OpaqueValueExpr *Node);
503
504    // C++
505    void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
506    void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
507    void VisitCXXThisExpr(const CXXThisExpr *Node);
508    void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
509    void VisitCXXConstructExpr(const CXXConstructExpr *Node);
510    void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
511    void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
512    void VisitExprWithCleanups(const ExprWithCleanups *Node);
513    void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
514    void dumpCXXTemporary(const CXXTemporary *Temporary);
515    void VisitLambdaExpr(const LambdaExpr *Node) {
516      VisitExpr(Node);
517      dumpDecl(Node->getLambdaClass());
518    }
519
520    // ObjC
521    void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
522    void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
523    void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
524    void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
525    void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
526    void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
527    void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
528    void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
529    void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
530    void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
531
532    // Comments.
533    const char *getCommandName(unsigned CommandID);
534    void dumpComment(const Comment *C);
535
536    // Inline comments.
537    void visitTextComment(const TextComment *C);
538    void visitInlineCommandComment(const InlineCommandComment *C);
539    void visitHTMLStartTagComment(const HTMLStartTagComment *C);
540    void visitHTMLEndTagComment(const HTMLEndTagComment *C);
541
542    // Block comments.
543    void visitBlockCommandComment(const BlockCommandComment *C);
544    void visitParamCommandComment(const ParamCommandComment *C);
545    void visitTParamCommandComment(const TParamCommandComment *C);
546    void visitVerbatimBlockComment(const VerbatimBlockComment *C);
547    void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
548    void visitVerbatimLineComment(const VerbatimLineComment *C);
549  };
550}
551
552//===----------------------------------------------------------------------===//
553//  Utilities
554//===----------------------------------------------------------------------===//
555
556void ASTDumper::dumpPointer(const void *Ptr) {
557  ColorScope Color(*this, AddressColor);
558  OS << ' ' << Ptr;
559}
560
561void ASTDumper::dumpLocation(SourceLocation Loc) {
562  if (!SM)
563    return;
564
565  ColorScope Color(*this, LocationColor);
566  SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
567
568  // The general format we print out is filename:line:col, but we drop pieces
569  // that haven't changed since the last loc printed.
570  PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
571
572  if (PLoc.isInvalid()) {
573    OS << "<invalid sloc>";
574    return;
575  }
576
577  if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
578    OS << PLoc.getFilename() << ':' << PLoc.getLine()
579       << ':' << PLoc.getColumn();
580    LastLocFilename = PLoc.getFilename();
581    LastLocLine = PLoc.getLine();
582  } else if (PLoc.getLine() != LastLocLine) {
583    OS << "line" << ':' << PLoc.getLine()
584       << ':' << PLoc.getColumn();
585    LastLocLine = PLoc.getLine();
586  } else {
587    OS << "col" << ':' << PLoc.getColumn();
588  }
589}
590
591void ASTDumper::dumpSourceRange(SourceRange R) {
592  // Can't translate locations if a SourceManager isn't available.
593  if (!SM)
594    return;
595
596  OS << " <";
597  dumpLocation(R.getBegin());
598  if (R.getBegin() != R.getEnd()) {
599    OS << ", ";
600    dumpLocation(R.getEnd());
601  }
602  OS << ">";
603
604  // <t2.c:123:421[blah], t2.c:412:321>
605
606}
607
608void ASTDumper::dumpBareType(QualType T, bool Desugar) {
609  ColorScope Color(*this, TypeColor);
610
611  SplitQualType T_split = T.split();
612  OS << "'" << QualType::getAsString(T_split) << "'";
613
614  if (Desugar && !T.isNull()) {
615    // If the type is sugared, also dump a (shallow) desugared type.
616    SplitQualType D_split = T.getSplitDesugaredType();
617    if (T_split != D_split)
618      OS << ":'" << QualType::getAsString(D_split) << "'";
619  }
620}
621
622void ASTDumper::dumpType(QualType T) {
623  OS << ' ';
624  dumpBareType(T);
625}
626
627void ASTDumper::dumpTypeAsChild(QualType T) {
628  SplitQualType SQT = T.split();
629  if (!SQT.Quals.hasQualifiers())
630    return dumpTypeAsChild(SQT.Ty);
631
632  dumpChild([=] {
633    OS << "QualType";
634    dumpPointer(T.getAsOpaquePtr());
635    OS << " ";
636    dumpBareType(T, false);
637    OS << " " << T.split().Quals.getAsString();
638    dumpTypeAsChild(T.split().Ty);
639  });
640}
641
642void ASTDumper::dumpTypeAsChild(const Type *T) {
643  dumpChild([=] {
644    if (!T) {
645      ColorScope Color(*this, NullColor);
646      OS << "<<<NULL>>>";
647      return;
648    }
649
650    {
651      ColorScope Color(*this, TypeColor);
652      OS << T->getTypeClassName() << "Type";
653    }
654    dumpPointer(T);
655    OS << " ";
656    dumpBareType(QualType(T, 0), false);
657
658    QualType SingleStepDesugar =
659        T->getLocallyUnqualifiedSingleStepDesugaredType();
660    if (SingleStepDesugar != QualType(T, 0))
661      OS << " sugar";
662    if (T->isDependentType())
663      OS << " dependent";
664    else if (T->isInstantiationDependentType())
665      OS << " instantiation_dependent";
666    if (T->isVariablyModifiedType())
667      OS << " variably_modified";
668    if (T->containsUnexpandedParameterPack())
669      OS << " contains_unexpanded_pack";
670    if (T->isFromAST())
671      OS << " imported";
672
673    TypeVisitor<ASTDumper>::Visit(T);
674
675    if (SingleStepDesugar != QualType(T, 0))
676      dumpTypeAsChild(SingleStepDesugar);
677  });
678}
679
680void ASTDumper::dumpBareDeclRef(const Decl *D) {
681  {
682    ColorScope Color(*this, DeclKindNameColor);
683    OS << D->getDeclKindName();
684  }
685  dumpPointer(D);
686
687  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
688    ColorScope Color(*this, DeclNameColor);
689    OS << " '" << ND->getDeclName() << '\'';
690  }
691
692  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
693    dumpType(VD->getType());
694}
695
696void ASTDumper::dumpDeclRef(const Decl *D, const char *Label) {
697  if (!D)
698    return;
699
700  dumpChild([=]{
701    if (Label)
702      OS << Label << ' ';
703    dumpBareDeclRef(D);
704  });
705}
706
707void ASTDumper::dumpName(const NamedDecl *ND) {
708  if (ND->getDeclName()) {
709    ColorScope Color(*this, DeclNameColor);
710    OS << ' ' << ND->getNameAsString();
711  }
712}
713
714bool ASTDumper::hasNodes(const DeclContext *DC) {
715  if (!DC)
716    return false;
717
718  return DC->hasExternalLexicalStorage() ||
719         DC->noload_decls_begin() != DC->noload_decls_end();
720}
721
722void ASTDumper::dumpDeclContext(const DeclContext *DC) {
723  if (!DC)
724    return;
725
726  for (auto *D : DC->noload_decls())
727    dumpDecl(D);
728
729  if (DC->hasExternalLexicalStorage()) {
730    dumpChild([=]{
731      ColorScope Color(*this, UndeserializedColor);
732      OS << "<undeserialized declarations>";
733    });
734  }
735}
736
737void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
738  dumpChild([=] {
739    OS << "StoredDeclsMap ";
740    dumpBareDeclRef(cast<Decl>(DC));
741
742    const DeclContext *Primary = DC->getPrimaryContext();
743    if (Primary != DC) {
744      OS << " primary";
745      dumpPointer(cast<Decl>(Primary));
746    }
747
748    bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
749
750    DeclContext::all_lookups_iterator I = Primary->noload_lookups_begin(),
751                                      E = Primary->noload_lookups_end();
752    while (I != E) {
753      DeclarationName Name = I.getLookupName();
754      DeclContextLookupResult R = *I++;
755
756      dumpChild([=] {
757        OS << "DeclarationName ";
758        {
759          ColorScope Color(*this, DeclNameColor);
760          OS << '\'' << Name << '\'';
761        }
762
763        for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
764             RI != RE; ++RI) {
765          dumpChild([=] {
766            dumpBareDeclRef(*RI);
767
768            if ((*RI)->isHidden())
769              OS << " hidden";
770
771            // If requested, dump the redecl chain for this lookup.
772            if (DumpDecls) {
773              // Dump earliest decl first.
774              std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
775                if (Decl *Prev = D->getPreviousDecl())
776                  DumpWithPrev(Prev);
777                dumpDecl(D);
778              };
779              DumpWithPrev(*RI);
780            }
781          });
782        }
783      });
784    }
785
786    if (HasUndeserializedLookups) {
787      dumpChild([=] {
788        ColorScope Color(*this, UndeserializedColor);
789        OS << "<undeserialized lookups>";
790      });
791    }
792  });
793}
794
795void ASTDumper::dumpAttr(const Attr *A) {
796  dumpChild([=] {
797    {
798      ColorScope Color(*this, AttrColor);
799
800      switch (A->getKind()) {
801#define ATTR(X) case attr::X: OS << #X; break;
802#include "clang/Basic/AttrList.inc"
803      default:
804        llvm_unreachable("unexpected attribute kind");
805      }
806      OS << "Attr";
807    }
808    dumpPointer(A);
809    dumpSourceRange(A->getRange());
810    if (A->isInherited())
811      OS << " Inherited";
812    if (A->isImplicit())
813      OS << " Implicit";
814#include "clang/AST/AttrDump.inc"
815  });
816}
817
818static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
819
820template<typename T>
821static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
822  const T *First = D->getFirstDecl();
823  if (First != D)
824    OS << " first " << First;
825}
826
827template<typename T>
828static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
829  const T *Prev = D->getPreviousDecl();
830  if (Prev)
831    OS << " prev " << Prev;
832}
833
834/// Dump the previous declaration in the redeclaration chain for a declaration,
835/// if any.
836static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
837  switch (D->getKind()) {
838#define DECL(DERIVED, BASE) \
839  case Decl::DERIVED: \
840    return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
841#define ABSTRACT_DECL(DECL)
842#include "clang/AST/DeclNodes.inc"
843  }
844  llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
845}
846
847//===----------------------------------------------------------------------===//
848//  C++ Utilities
849//===----------------------------------------------------------------------===//
850
851void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) {
852  switch (AS) {
853  case AS_none:
854    break;
855  case AS_public:
856    OS << "public";
857    break;
858  case AS_protected:
859    OS << "protected";
860    break;
861  case AS_private:
862    OS << "private";
863    break;
864  }
865}
866
867void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) {
868  dumpChild([=] {
869    OS << "CXXCtorInitializer";
870    if (Init->isAnyMemberInitializer()) {
871      OS << ' ';
872      dumpBareDeclRef(Init->getAnyMember());
873    } else if (Init->isBaseInitializer()) {
874      dumpType(QualType(Init->getBaseClass(), 0));
875    } else if (Init->isDelegatingInitializer()) {
876      dumpType(Init->getTypeSourceInfo()->getType());
877    } else {
878      llvm_unreachable("Unknown initializer type");
879    }
880    dumpStmt(Init->getInit());
881  });
882}
883
884void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) {
885  if (!TPL)
886    return;
887
888  for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end();
889       I != E; ++I)
890    dumpDecl(*I);
891}
892
893void ASTDumper::dumpTemplateArgumentListInfo(
894    const TemplateArgumentListInfo &TALI) {
895  for (unsigned i = 0, e = TALI.size(); i < e; ++i)
896    dumpTemplateArgumentLoc(TALI[i]);
897}
898
899void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) {
900  dumpTemplateArgument(A.getArgument(), A.getSourceRange());
901}
902
903void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
904  for (unsigned i = 0, e = TAL.size(); i < e; ++i)
905    dumpTemplateArgument(TAL[i]);
906}
907
908void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) {
909  dumpChild([=] {
910    OS << "TemplateArgument";
911    if (R.isValid())
912      dumpSourceRange(R);
913
914    switch (A.getKind()) {
915    case TemplateArgument::Null:
916      OS << " null";
917      break;
918    case TemplateArgument::Type:
919      OS << " type";
920      dumpType(A.getAsType());
921      break;
922    case TemplateArgument::Declaration:
923      OS << " decl";
924      dumpDeclRef(A.getAsDecl());
925      break;
926    case TemplateArgument::NullPtr:
927      OS << " nullptr";
928      break;
929    case TemplateArgument::Integral:
930      OS << " integral " << A.getAsIntegral();
931      break;
932    case TemplateArgument::Template:
933      OS << " template ";
934      A.getAsTemplate().dump(OS);
935      break;
936    case TemplateArgument::TemplateExpansion:
937      OS << " template expansion";
938      A.getAsTemplateOrTemplatePattern().dump(OS);
939      break;
940    case TemplateArgument::Expression:
941      OS << " expr";
942      dumpStmt(A.getAsExpr());
943      break;
944    case TemplateArgument::Pack:
945      OS << " pack";
946      for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end();
947           I != E; ++I)
948        dumpTemplateArgument(*I);
949      break;
950    }
951  });
952}
953
954//===----------------------------------------------------------------------===//
955//  Decl dumping methods.
956//===----------------------------------------------------------------------===//
957
958void ASTDumper::dumpDecl(const Decl *D) {
959  dumpChild([=] {
960    if (!D) {
961      ColorScope Color(*this, NullColor);
962      OS << "<<<NULL>>>";
963      return;
964    }
965
966    {
967      ColorScope Color(*this, DeclKindNameColor);
968      OS << D->getDeclKindName() << "Decl";
969    }
970    dumpPointer(D);
971    if (D->getLexicalDeclContext() != D->getDeclContext())
972      OS << " parent " << cast<Decl>(D->getDeclContext());
973    dumpPreviousDecl(OS, D);
974    dumpSourceRange(D->getSourceRange());
975    OS << ' ';
976    dumpLocation(D->getLocation());
977    if (Module *M = D->getOwningModule())
978      OS << " in " << M->getFullModuleName();
979    if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
980      if (ND->isHidden())
981        OS << " hidden";
982    if (D->isImplicit())
983      OS << " implicit";
984    if (D->isUsed())
985      OS << " used";
986    else if (D->isThisDeclarationReferenced())
987      OS << " referenced";
988    if (D->isInvalidDecl())
989      OS << " invalid";
990    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
991      if (FD->isConstexpr())
992        OS << " constexpr";
993
994
995    ConstDeclVisitor<ASTDumper>::Visit(D);
996
997    for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); I != E;
998         ++I)
999      dumpAttr(*I);
1000
1001    if (const FullComment *Comment =
1002            D->getASTContext().getLocalCommentForDeclUncached(D))
1003      dumpFullComment(Comment);
1004
1005    // Decls within functions are visited by the body.
1006    if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) &&
1007        hasNodes(dyn_cast<DeclContext>(D)))
1008      dumpDeclContext(cast<DeclContext>(D));
1009  });
1010}
1011
1012void ASTDumper::VisitLabelDecl(const LabelDecl *D) {
1013  dumpName(D);
1014}
1015
1016void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) {
1017  dumpName(D);
1018  dumpType(D->getUnderlyingType());
1019  if (D->isModulePrivate())
1020    OS << " __module_private__";
1021}
1022
1023void ASTDumper::VisitEnumDecl(const EnumDecl *D) {
1024  if (D->isScoped()) {
1025    if (D->isScopedUsingClassTag())
1026      OS << " class";
1027    else
1028      OS << " struct";
1029  }
1030  dumpName(D);
1031  if (D->isModulePrivate())
1032    OS << " __module_private__";
1033  if (D->isFixed())
1034    dumpType(D->getIntegerType());
1035}
1036
1037void ASTDumper::VisitRecordDecl(const RecordDecl *D) {
1038  OS << ' ' << D->getKindName();
1039  dumpName(D);
1040  if (D->isModulePrivate())
1041    OS << " __module_private__";
1042  if (D->isCompleteDefinition())
1043    OS << " definition";
1044}
1045
1046void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
1047  dumpName(D);
1048  dumpType(D->getType());
1049  if (const Expr *Init = D->getInitExpr())
1050    dumpStmt(Init);
1051}
1052
1053void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
1054  dumpName(D);
1055  dumpType(D->getType());
1056
1057  for (auto *Child : D->chain())
1058    dumpDeclRef(Child);
1059}
1060
1061void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
1062  dumpName(D);
1063  dumpType(D->getType());
1064
1065  StorageClass SC = D->getStorageClass();
1066  if (SC != SC_None)
1067    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1068  if (D->isInlineSpecified())
1069    OS << " inline";
1070  if (D->isVirtualAsWritten())
1071    OS << " virtual";
1072  if (D->isModulePrivate())
1073    OS << " __module_private__";
1074
1075  if (D->isPure())
1076    OS << " pure";
1077  else if (D->isDeletedAsWritten())
1078    OS << " delete";
1079
1080  if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) {
1081    FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
1082    switch (EPI.ExceptionSpec.Type) {
1083    default: break;
1084    case EST_Unevaluated:
1085      OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
1086      break;
1087    case EST_Uninstantiated:
1088      OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
1089      break;
1090    }
1091  }
1092
1093  if (const FunctionTemplateSpecializationInfo *FTSI =
1094          D->getTemplateSpecializationInfo())
1095    dumpTemplateArgumentList(*FTSI->TemplateArguments);
1096
1097  for (ArrayRef<NamedDecl *>::iterator
1098       I = D->getDeclsInPrototypeScope().begin(),
1099       E = D->getDeclsInPrototypeScope().end(); I != E; ++I)
1100    dumpDecl(*I);
1101
1102  for (FunctionDecl::param_const_iterator I = D->param_begin(),
1103                                          E = D->param_end();
1104       I != E; ++I)
1105    dumpDecl(*I);
1106
1107  if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D))
1108    for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
1109                                                 E = C->init_end();
1110         I != E; ++I)
1111      dumpCXXCtorInitializer(*I);
1112
1113  if (D->doesThisDeclarationHaveABody())
1114    dumpStmt(D->getBody());
1115}
1116
1117void ASTDumper::VisitFieldDecl(const FieldDecl *D) {
1118  dumpName(D);
1119  dumpType(D->getType());
1120  if (D->isMutable())
1121    OS << " mutable";
1122  if (D->isModulePrivate())
1123    OS << " __module_private__";
1124
1125  if (D->isBitField())
1126    dumpStmt(D->getBitWidth());
1127  if (Expr *Init = D->getInClassInitializer())
1128    dumpStmt(Init);
1129}
1130
1131void ASTDumper::VisitVarDecl(const VarDecl *D) {
1132  dumpName(D);
1133  dumpType(D->getType());
1134  StorageClass SC = D->getStorageClass();
1135  if (SC != SC_None)
1136    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1137  switch (D->getTLSKind()) {
1138  case VarDecl::TLS_None: break;
1139  case VarDecl::TLS_Static: OS << " tls"; break;
1140  case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break;
1141  }
1142  if (D->isModulePrivate())
1143    OS << " __module_private__";
1144  if (D->isNRVOVariable())
1145    OS << " nrvo";
1146  if (D->hasInit()) {
1147    switch (D->getInitStyle()) {
1148    case VarDecl::CInit: OS << " cinit"; break;
1149    case VarDecl::CallInit: OS << " callinit"; break;
1150    case VarDecl::ListInit: OS << " listinit"; break;
1151    }
1152    dumpStmt(D->getInit());
1153  }
1154}
1155
1156void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
1157  dumpStmt(D->getAsmString());
1158}
1159
1160void ASTDumper::VisitImportDecl(const ImportDecl *D) {
1161  OS << ' ' << D->getImportedModule()->getFullModuleName();
1162}
1163
1164//===----------------------------------------------------------------------===//
1165// C++ Declarations
1166//===----------------------------------------------------------------------===//
1167
1168void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
1169  dumpName(D);
1170  if (D->isInline())
1171    OS << " inline";
1172  if (!D->isOriginalNamespace())
1173    dumpDeclRef(D->getOriginalNamespace(), "original");
1174}
1175
1176void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
1177  OS << ' ';
1178  dumpBareDeclRef(D->getNominatedNamespace());
1179}
1180
1181void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
1182  dumpName(D);
1183  dumpDeclRef(D->getAliasedNamespace());
1184}
1185
1186void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
1187  dumpName(D);
1188  dumpType(D->getUnderlyingType());
1189}
1190
1191void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
1192  dumpName(D);
1193  dumpTemplateParameters(D->getTemplateParameters());
1194  dumpDecl(D->getTemplatedDecl());
1195}
1196
1197void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
1198  VisitRecordDecl(D);
1199  if (!D->isCompleteDefinition())
1200    return;
1201
1202  for (const auto &I : D->bases()) {
1203    dumpChild([=] {
1204      if (I.isVirtual())
1205        OS << "virtual ";
1206      dumpAccessSpecifier(I.getAccessSpecifier());
1207      dumpType(I.getType());
1208      if (I.isPackExpansion())
1209        OS << "...";
1210    });
1211  }
1212}
1213
1214void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
1215  dumpStmt(D->getAssertExpr());
1216  dumpStmt(D->getMessage());
1217}
1218
1219template<typename SpecializationDecl>
1220void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D,
1221                                                bool DumpExplicitInst,
1222                                                bool DumpRefOnly) {
1223  bool DumpedAny = false;
1224  for (auto *RedeclWithBadType : D->redecls()) {
1225    // FIXME: The redecls() range sometimes has elements of a less-specific
1226    // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
1227    // us TagDecls, and should give CXXRecordDecls).
1228    auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
1229    if (!Redecl) {
1230      // Found the injected-class-name for a class template. This will be dumped
1231      // as part of its surrounding class so we don't need to dump it here.
1232      assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
1233             "expected an injected-class-name");
1234      continue;
1235    }
1236
1237    switch (Redecl->getTemplateSpecializationKind()) {
1238    case TSK_ExplicitInstantiationDeclaration:
1239    case TSK_ExplicitInstantiationDefinition:
1240      if (!DumpExplicitInst)
1241        break;
1242      // Fall through.
1243    case TSK_Undeclared:
1244    case TSK_ImplicitInstantiation:
1245      if (DumpRefOnly)
1246        dumpDeclRef(Redecl);
1247      else
1248        dumpDecl(Redecl);
1249      DumpedAny = true;
1250      break;
1251    case TSK_ExplicitSpecialization:
1252      break;
1253    }
1254  }
1255
1256  // Ensure we dump at least one decl for each specialization.
1257  if (!DumpedAny)
1258    dumpDeclRef(D);
1259}
1260
1261template<typename TemplateDecl>
1262void ASTDumper::VisitTemplateDecl(const TemplateDecl *D,
1263                                  bool DumpExplicitInst) {
1264  dumpName(D);
1265  dumpTemplateParameters(D->getTemplateParameters());
1266
1267  dumpDecl(D->getTemplatedDecl());
1268
1269  for (auto *Child : D->specializations())
1270    VisitTemplateDeclSpecialization(Child, DumpExplicitInst,
1271                                    !D->isCanonicalDecl());
1272}
1273
1274void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
1275  // FIXME: We don't add a declaration of a function template specialization
1276  // to its context when it's explicitly instantiated, so dump explicit
1277  // instantiations when we dump the template itself.
1278  VisitTemplateDecl(D, true);
1279}
1280
1281void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
1282  VisitTemplateDecl(D, false);
1283}
1284
1285void ASTDumper::VisitClassTemplateSpecializationDecl(
1286    const ClassTemplateSpecializationDecl *D) {
1287  VisitCXXRecordDecl(D);
1288  dumpTemplateArgumentList(D->getTemplateArgs());
1289}
1290
1291void ASTDumper::VisitClassTemplatePartialSpecializationDecl(
1292    const ClassTemplatePartialSpecializationDecl *D) {
1293  VisitClassTemplateSpecializationDecl(D);
1294  dumpTemplateParameters(D->getTemplateParameters());
1295}
1296
1297void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
1298    const ClassScopeFunctionSpecializationDecl *D) {
1299  dumpDeclRef(D->getSpecialization());
1300  if (D->hasExplicitTemplateArgs())
1301    dumpTemplateArgumentListInfo(D->templateArgs());
1302}
1303
1304void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
1305  VisitTemplateDecl(D, false);
1306}
1307
1308void ASTDumper::VisitVarTemplateSpecializationDecl(
1309    const VarTemplateSpecializationDecl *D) {
1310  dumpTemplateArgumentList(D->getTemplateArgs());
1311  VisitVarDecl(D);
1312}
1313
1314void ASTDumper::VisitVarTemplatePartialSpecializationDecl(
1315    const VarTemplatePartialSpecializationDecl *D) {
1316  dumpTemplateParameters(D->getTemplateParameters());
1317  VisitVarTemplateSpecializationDecl(D);
1318}
1319
1320void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
1321  if (D->wasDeclaredWithTypename())
1322    OS << " typename";
1323  else
1324    OS << " class";
1325  if (D->isParameterPack())
1326    OS << " ...";
1327  dumpName(D);
1328  if (D->hasDefaultArgument())
1329    dumpTemplateArgument(D->getDefaultArgument());
1330}
1331
1332void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
1333  dumpType(D->getType());
1334  if (D->isParameterPack())
1335    OS << " ...";
1336  dumpName(D);
1337  if (D->hasDefaultArgument())
1338    dumpTemplateArgument(D->getDefaultArgument());
1339}
1340
1341void ASTDumper::VisitTemplateTemplateParmDecl(
1342    const TemplateTemplateParmDecl *D) {
1343  if (D->isParameterPack())
1344    OS << " ...";
1345  dumpName(D);
1346  dumpTemplateParameters(D->getTemplateParameters());
1347  if (D->hasDefaultArgument())
1348    dumpTemplateArgumentLoc(D->getDefaultArgument());
1349}
1350
1351void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
1352  OS << ' ';
1353  D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1354  OS << D->getNameAsString();
1355}
1356
1357void ASTDumper::VisitUnresolvedUsingTypenameDecl(
1358    const UnresolvedUsingTypenameDecl *D) {
1359  OS << ' ';
1360  D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1361  OS << D->getNameAsString();
1362}
1363
1364void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
1365  OS << ' ';
1366  D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1367  OS << D->getNameAsString();
1368  dumpType(D->getType());
1369}
1370
1371void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
1372  OS << ' ';
1373  dumpBareDeclRef(D->getTargetDecl());
1374}
1375
1376void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
1377  switch (D->getLanguage()) {
1378  case LinkageSpecDecl::lang_c: OS << " C"; break;
1379  case LinkageSpecDecl::lang_cxx: OS << " C++"; break;
1380  }
1381}
1382
1383void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
1384  OS << ' ';
1385  dumpAccessSpecifier(D->getAccess());
1386}
1387
1388void ASTDumper::VisitFriendDecl(const FriendDecl *D) {
1389  if (TypeSourceInfo *T = D->getFriendType())
1390    dumpType(T->getType());
1391  else
1392    dumpDecl(D->getFriendDecl());
1393}
1394
1395//===----------------------------------------------------------------------===//
1396// Obj-C Declarations
1397//===----------------------------------------------------------------------===//
1398
1399void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
1400  dumpName(D);
1401  dumpType(D->getType());
1402  if (D->getSynthesize())
1403    OS << " synthesize";
1404
1405  switch (D->getAccessControl()) {
1406  case ObjCIvarDecl::None:
1407    OS << " none";
1408    break;
1409  case ObjCIvarDecl::Private:
1410    OS << " private";
1411    break;
1412  case ObjCIvarDecl::Protected:
1413    OS << " protected";
1414    break;
1415  case ObjCIvarDecl::Public:
1416    OS << " public";
1417    break;
1418  case ObjCIvarDecl::Package:
1419    OS << " package";
1420    break;
1421  }
1422}
1423
1424void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
1425  if (D->isInstanceMethod())
1426    OS << " -";
1427  else
1428    OS << " +";
1429  dumpName(D);
1430  dumpType(D->getReturnType());
1431
1432  if (D->isThisDeclarationADefinition()) {
1433    dumpDeclContext(D);
1434  } else {
1435    for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
1436                                              E = D->param_end();
1437         I != E; ++I)
1438      dumpDecl(*I);
1439  }
1440
1441  if (D->isVariadic())
1442    dumpChild([=] { OS << "..."; });
1443
1444  if (D->hasBody())
1445    dumpStmt(D->getBody());
1446}
1447
1448void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
1449  dumpName(D);
1450  dumpDeclRef(D->getClassInterface());
1451  dumpDeclRef(D->getImplementation());
1452  for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
1453                                           E = D->protocol_end();
1454       I != E; ++I)
1455    dumpDeclRef(*I);
1456}
1457
1458void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
1459  dumpName(D);
1460  dumpDeclRef(D->getClassInterface());
1461  dumpDeclRef(D->getCategoryDecl());
1462}
1463
1464void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
1465  dumpName(D);
1466
1467  for (auto *Child : D->protocols())
1468    dumpDeclRef(Child);
1469}
1470
1471void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
1472  dumpName(D);
1473  dumpDeclRef(D->getSuperClass(), "super");
1474
1475  dumpDeclRef(D->getImplementation());
1476  for (auto *Child : D->protocols())
1477    dumpDeclRef(Child);
1478}
1479
1480void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
1481  dumpName(D);
1482  dumpDeclRef(D->getSuperClass(), "super");
1483  dumpDeclRef(D->getClassInterface());
1484  for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
1485                                                   E = D->init_end();
1486       I != E; ++I)
1487    dumpCXXCtorInitializer(*I);
1488}
1489
1490void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
1491  dumpName(D);
1492  dumpDeclRef(D->getClassInterface());
1493}
1494
1495void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
1496  dumpName(D);
1497  dumpType(D->getType());
1498
1499  if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
1500    OS << " required";
1501  else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
1502    OS << " optional";
1503
1504  ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
1505  if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
1506    if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
1507      OS << " readonly";
1508    if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
1509      OS << " assign";
1510    if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
1511      OS << " readwrite";
1512    if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
1513      OS << " retain";
1514    if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
1515      OS << " copy";
1516    if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
1517      OS << " nonatomic";
1518    if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
1519      OS << " atomic";
1520    if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
1521      OS << " weak";
1522    if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
1523      OS << " strong";
1524    if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
1525      OS << " unsafe_unretained";
1526    if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
1527      dumpDeclRef(D->getGetterMethodDecl(), "getter");
1528    if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
1529      dumpDeclRef(D->getSetterMethodDecl(), "setter");
1530  }
1531}
1532
1533void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
1534  dumpName(D->getPropertyDecl());
1535  if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
1536    OS << " synthesize";
1537  else
1538    OS << " dynamic";
1539  dumpDeclRef(D->getPropertyDecl());
1540  dumpDeclRef(D->getPropertyIvarDecl());
1541}
1542
1543void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
1544  for (auto I : D->params())
1545    dumpDecl(I);
1546
1547  if (D->isVariadic())
1548    dumpChild([=]{ OS << "..."; });
1549
1550  if (D->capturesCXXThis())
1551    dumpChild([=]{ OS << "capture this"; });
1552
1553  for (const auto &I : D->captures()) {
1554    dumpChild([=] {
1555      OS << "capture";
1556      if (I.isByRef())
1557        OS << " byref";
1558      if (I.isNested())
1559        OS << " nested";
1560      if (I.getVariable()) {
1561        OS << ' ';
1562        dumpBareDeclRef(I.getVariable());
1563      }
1564      if (I.hasCopyExpr())
1565        dumpStmt(I.getCopyExpr());
1566    });
1567  }
1568  dumpStmt(D->getBody());
1569}
1570
1571//===----------------------------------------------------------------------===//
1572//  Stmt dumping methods.
1573//===----------------------------------------------------------------------===//
1574
1575void ASTDumper::dumpStmt(const Stmt *S) {
1576  dumpChild([=] {
1577    if (!S) {
1578      ColorScope Color(*this, NullColor);
1579      OS << "<<<NULL>>>";
1580      return;
1581    }
1582
1583    if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
1584      VisitDeclStmt(DS);
1585      return;
1586    }
1587
1588    ConstStmtVisitor<ASTDumper>::Visit(S);
1589
1590    for (Stmt::const_child_range CI = S->children(); CI; ++CI)
1591      dumpStmt(*CI);
1592  });
1593}
1594
1595void ASTDumper::VisitStmt(const Stmt *Node) {
1596  {
1597    ColorScope Color(*this, StmtColor);
1598    OS << Node->getStmtClassName();
1599  }
1600  dumpPointer(Node);
1601  dumpSourceRange(Node->getSourceRange());
1602}
1603
1604void ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
1605  VisitStmt(Node);
1606  for (DeclStmt::const_decl_iterator I = Node->decl_begin(),
1607                                     E = Node->decl_end();
1608       I != E; ++I)
1609    dumpDecl(*I);
1610}
1611
1612void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) {
1613  VisitStmt(Node);
1614  for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(),
1615                                        E = Node->getAttrs().end();
1616       I != E; ++I)
1617    dumpAttr(*I);
1618}
1619
1620void ASTDumper::VisitLabelStmt(const LabelStmt *Node) {
1621  VisitStmt(Node);
1622  OS << " '" << Node->getName() << "'";
1623}
1624
1625void ASTDumper::VisitGotoStmt(const GotoStmt *Node) {
1626  VisitStmt(Node);
1627  OS << " '" << Node->getLabel()->getName() << "'";
1628  dumpPointer(Node->getLabel());
1629}
1630
1631void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) {
1632  VisitStmt(Node);
1633  dumpDecl(Node->getExceptionDecl());
1634}
1635
1636//===----------------------------------------------------------------------===//
1637//  Expr dumping methods.
1638//===----------------------------------------------------------------------===//
1639
1640void ASTDumper::VisitExpr(const Expr *Node) {
1641  VisitStmt(Node);
1642  dumpType(Node->getType());
1643
1644  {
1645    ColorScope Color(*this, ValueKindColor);
1646    switch (Node->getValueKind()) {
1647    case VK_RValue:
1648      break;
1649    case VK_LValue:
1650      OS << " lvalue";
1651      break;
1652    case VK_XValue:
1653      OS << " xvalue";
1654      break;
1655    }
1656  }
1657
1658  {
1659    ColorScope Color(*this, ObjectKindColor);
1660    switch (Node->getObjectKind()) {
1661    case OK_Ordinary:
1662      break;
1663    case OK_BitField:
1664      OS << " bitfield";
1665      break;
1666    case OK_ObjCProperty:
1667      OS << " objcproperty";
1668      break;
1669    case OK_ObjCSubscript:
1670      OS << " objcsubscript";
1671      break;
1672    case OK_VectorComponent:
1673      OS << " vectorcomponent";
1674      break;
1675    }
1676  }
1677}
1678
1679static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
1680  if (Node->path_empty())
1681    return;
1682
1683  OS << " (";
1684  bool First = true;
1685  for (CastExpr::path_const_iterator I = Node->path_begin(),
1686                                     E = Node->path_end();
1687       I != E; ++I) {
1688    const CXXBaseSpecifier *Base = *I;
1689    if (!First)
1690      OS << " -> ";
1691
1692    const CXXRecordDecl *RD =
1693    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
1694
1695    if (Base->isVirtual())
1696      OS << "virtual ";
1697    OS << RD->getName();
1698    First = false;
1699  }
1700
1701  OS << ')';
1702}
1703
1704void ASTDumper::VisitCastExpr(const CastExpr *Node) {
1705  VisitExpr(Node);
1706  OS << " <";
1707  {
1708    ColorScope Color(*this, CastColor);
1709    OS << Node->getCastKindName();
1710  }
1711  dumpBasePath(OS, Node);
1712  OS << ">";
1713}
1714
1715void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1716  VisitExpr(Node);
1717
1718  OS << " ";
1719  dumpBareDeclRef(Node->getDecl());
1720  if (Node->getDecl() != Node->getFoundDecl()) {
1721    OS << " (";
1722    dumpBareDeclRef(Node->getFoundDecl());
1723    OS << ")";
1724  }
1725}
1726
1727void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) {
1728  VisitExpr(Node);
1729  OS << " (";
1730  if (!Node->requiresADL())
1731    OS << "no ";
1732  OS << "ADL) = '" << Node->getName() << '\'';
1733
1734  UnresolvedLookupExpr::decls_iterator
1735    I = Node->decls_begin(), E = Node->decls_end();
1736  if (I == E)
1737    OS << " empty";
1738  for (; I != E; ++I)
1739    dumpPointer(*I);
1740}
1741
1742void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
1743  VisitExpr(Node);
1744
1745  {
1746    ColorScope Color(*this, DeclKindNameColor);
1747    OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
1748  }
1749  OS << "='" << *Node->getDecl() << "'";
1750  dumpPointer(Node->getDecl());
1751  if (Node->isFreeIvar())
1752    OS << " isFreeIvar";
1753}
1754
1755void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
1756  VisitExpr(Node);
1757  OS << " " << PredefinedExpr::getIdentTypeName(Node->getIdentType());
1758}
1759
1760void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1761  VisitExpr(Node);
1762  ColorScope Color(*this, ValueColor);
1763  OS << " " << Node->getValue();
1764}
1765
1766void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1767  VisitExpr(Node);
1768
1769  bool isSigned = Node->getType()->isSignedIntegerType();
1770  ColorScope Color(*this, ValueColor);
1771  OS << " " << Node->getValue().toString(10, isSigned);
1772}
1773
1774void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1775  VisitExpr(Node);
1776  ColorScope Color(*this, ValueColor);
1777  OS << " " << Node->getValueAsApproximateDouble();
1778}
1779
1780void ASTDumper::VisitStringLiteral(const StringLiteral *Str) {
1781  VisitExpr(Str);
1782  ColorScope Color(*this, ValueColor);
1783  OS << " ";
1784  Str->outputString(OS);
1785}
1786
1787void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
1788  VisitExpr(ILE);
1789  if (auto *Filler = ILE->getArrayFiller()) {
1790    dumpChild([=] {
1791      OS << "array filler";
1792      dumpStmt(Filler);
1793    });
1794  }
1795  if (auto *Field = ILE->getInitializedFieldInUnion()) {
1796    OS << " field ";
1797    dumpBareDeclRef(Field);
1798  }
1799}
1800
1801void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1802  VisitExpr(Node);
1803  OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
1804     << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1805}
1806
1807void ASTDumper::VisitUnaryExprOrTypeTraitExpr(
1808    const UnaryExprOrTypeTraitExpr *Node) {
1809  VisitExpr(Node);
1810  switch(Node->getKind()) {
1811  case UETT_SizeOf:
1812    OS << " sizeof";
1813    break;
1814  case UETT_AlignOf:
1815    OS << " alignof";
1816    break;
1817  case UETT_VecStep:
1818    OS << " vec_step";
1819    break;
1820  }
1821  if (Node->isArgumentType())
1822    dumpType(Node->getArgumentType());
1823}
1824
1825void ASTDumper::VisitMemberExpr(const MemberExpr *Node) {
1826  VisitExpr(Node);
1827  OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
1828  dumpPointer(Node->getMemberDecl());
1829}
1830
1831void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) {
1832  VisitExpr(Node);
1833  OS << " " << Node->getAccessor().getNameStart();
1834}
1835
1836void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1837  VisitExpr(Node);
1838  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1839}
1840
1841void ASTDumper::VisitCompoundAssignOperator(
1842    const CompoundAssignOperator *Node) {
1843  VisitExpr(Node);
1844  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1845     << "' ComputeLHSTy=";
1846  dumpBareType(Node->getComputationLHSType());
1847  OS << " ComputeResultTy=";
1848  dumpBareType(Node->getComputationResultType());
1849}
1850
1851void ASTDumper::VisitBlockExpr(const BlockExpr *Node) {
1852  VisitExpr(Node);
1853  dumpDecl(Node->getBlockDecl());
1854}
1855
1856void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
1857  VisitExpr(Node);
1858
1859  if (Expr *Source = Node->getSourceExpr())
1860    dumpStmt(Source);
1861}
1862
1863// GNU extensions.
1864
1865void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
1866  VisitExpr(Node);
1867  OS << " " << Node->getLabel()->getName();
1868  dumpPointer(Node->getLabel());
1869}
1870
1871//===----------------------------------------------------------------------===//
1872// C++ Expressions
1873//===----------------------------------------------------------------------===//
1874
1875void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
1876  VisitExpr(Node);
1877  OS << " " << Node->getCastName()
1878     << "<" << Node->getTypeAsWritten().getAsString() << ">"
1879     << " <" << Node->getCastKindName();
1880  dumpBasePath(OS, Node);
1881  OS << ">";
1882}
1883
1884void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1885  VisitExpr(Node);
1886  OS << " " << (Node->getValue() ? "true" : "false");
1887}
1888
1889void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1890  VisitExpr(Node);
1891  OS << " this";
1892}
1893
1894void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) {
1895  VisitExpr(Node);
1896  OS << " functional cast to " << Node->getTypeAsWritten().getAsString()
1897     << " <" << Node->getCastKindName() << ">";
1898}
1899
1900void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1901  VisitExpr(Node);
1902  CXXConstructorDecl *Ctor = Node->getConstructor();
1903  dumpType(Ctor->getType());
1904  if (Node->isElidable())
1905    OS << " elidable";
1906  if (Node->requiresZeroInitialization())
1907    OS << " zeroing";
1908}
1909
1910void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) {
1911  VisitExpr(Node);
1912  OS << " ";
1913  dumpCXXTemporary(Node->getTemporary());
1914}
1915
1916void
1917ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) {
1918  VisitExpr(Node);
1919  if (const ValueDecl *VD = Node->getExtendingDecl()) {
1920    OS << " extended by ";
1921    dumpBareDeclRef(VD);
1922  }
1923}
1924
1925void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
1926  VisitExpr(Node);
1927  for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
1928    dumpDeclRef(Node->getObject(i), "cleanup");
1929}
1930
1931void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
1932  OS << "(CXXTemporary";
1933  dumpPointer(Temporary);
1934  OS << ")";
1935}
1936
1937//===----------------------------------------------------------------------===//
1938// Obj-C Expressions
1939//===----------------------------------------------------------------------===//
1940
1941void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
1942  VisitExpr(Node);
1943  OS << " selector=";
1944  Node->getSelector().print(OS);
1945  switch (Node->getReceiverKind()) {
1946  case ObjCMessageExpr::Instance:
1947    break;
1948
1949  case ObjCMessageExpr::Class:
1950    OS << " class=";
1951    dumpBareType(Node->getClassReceiver());
1952    break;
1953
1954  case ObjCMessageExpr::SuperInstance:
1955    OS << " super (instance)";
1956    break;
1957
1958  case ObjCMessageExpr::SuperClass:
1959    OS << " super (class)";
1960    break;
1961  }
1962}
1963
1964void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
1965  VisitExpr(Node);
1966  OS << " selector=";
1967  Node->getBoxingMethod()->getSelector().print(OS);
1968}
1969
1970void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
1971  VisitStmt(Node);
1972  if (const VarDecl *CatchParam = Node->getCatchParamDecl())
1973    dumpDecl(CatchParam);
1974  else
1975    OS << " catch all";
1976}
1977
1978void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
1979  VisitExpr(Node);
1980  dumpType(Node->getEncodedType());
1981}
1982
1983void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1984  VisitExpr(Node);
1985
1986  OS << " ";
1987  Node->getSelector().print(OS);
1988}
1989
1990void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
1991  VisitExpr(Node);
1992
1993  OS << ' ' << *Node->getProtocol();
1994}
1995
1996void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
1997  VisitExpr(Node);
1998  if (Node->isImplicitProperty()) {
1999    OS << " Kind=MethodRef Getter=\"";
2000    if (Node->getImplicitPropertyGetter())
2001      Node->getImplicitPropertyGetter()->getSelector().print(OS);
2002    else
2003      OS << "(null)";
2004
2005    OS << "\" Setter=\"";
2006    if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
2007      Setter->getSelector().print(OS);
2008    else
2009      OS << "(null)";
2010    OS << "\"";
2011  } else {
2012    OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"';
2013  }
2014
2015  if (Node->isSuperReceiver())
2016    OS << " super";
2017
2018  OS << " Messaging=";
2019  if (Node->isMessagingGetter() && Node->isMessagingSetter())
2020    OS << "Getter&Setter";
2021  else if (Node->isMessagingGetter())
2022    OS << "Getter";
2023  else if (Node->isMessagingSetter())
2024    OS << "Setter";
2025}
2026
2027void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
2028  VisitExpr(Node);
2029  if (Node->isArraySubscriptRefExpr())
2030    OS << " Kind=ArraySubscript GetterForArray=\"";
2031  else
2032    OS << " Kind=DictionarySubscript GetterForDictionary=\"";
2033  if (Node->getAtIndexMethodDecl())
2034    Node->getAtIndexMethodDecl()->getSelector().print(OS);
2035  else
2036    OS << "(null)";
2037
2038  if (Node->isArraySubscriptRefExpr())
2039    OS << "\" SetterForArray=\"";
2040  else
2041    OS << "\" SetterForDictionary=\"";
2042  if (Node->setAtIndexMethodDecl())
2043    Node->setAtIndexMethodDecl()->getSelector().print(OS);
2044  else
2045    OS << "(null)";
2046}
2047
2048void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
2049  VisitExpr(Node);
2050  OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
2051}
2052
2053//===----------------------------------------------------------------------===//
2054// Comments
2055//===----------------------------------------------------------------------===//
2056
2057const char *ASTDumper::getCommandName(unsigned CommandID) {
2058  if (Traits)
2059    return Traits->getCommandInfo(CommandID)->Name;
2060  const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
2061  if (Info)
2062    return Info->Name;
2063  return "<not a builtin command>";
2064}
2065
2066void ASTDumper::dumpFullComment(const FullComment *C) {
2067  if (!C)
2068    return;
2069
2070  FC = C;
2071  dumpComment(C);
2072  FC = nullptr;
2073}
2074
2075void ASTDumper::dumpComment(const Comment *C) {
2076  dumpChild([=] {
2077    if (!C) {
2078      ColorScope Color(*this, NullColor);
2079      OS << "<<<NULL>>>";
2080      return;
2081    }
2082
2083    {
2084      ColorScope Color(*this, CommentColor);
2085      OS << C->getCommentKindName();
2086    }
2087    dumpPointer(C);
2088    dumpSourceRange(C->getSourceRange());
2089    ConstCommentVisitor<ASTDumper>::visit(C);
2090    for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
2091         I != E; ++I)
2092      dumpComment(*I);
2093  });
2094}
2095
2096void ASTDumper::visitTextComment(const TextComment *C) {
2097  OS << " Text=\"" << C->getText() << "\"";
2098}
2099
2100void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) {
2101  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
2102  switch (C->getRenderKind()) {
2103  case InlineCommandComment::RenderNormal:
2104    OS << " RenderNormal";
2105    break;
2106  case InlineCommandComment::RenderBold:
2107    OS << " RenderBold";
2108    break;
2109  case InlineCommandComment::RenderMonospaced:
2110    OS << " RenderMonospaced";
2111    break;
2112  case InlineCommandComment::RenderEmphasized:
2113    OS << " RenderEmphasized";
2114    break;
2115  }
2116
2117  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
2118    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
2119}
2120
2121void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
2122  OS << " Name=\"" << C->getTagName() << "\"";
2123  if (C->getNumAttrs() != 0) {
2124    OS << " Attrs: ";
2125    for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
2126      const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
2127      OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
2128    }
2129  }
2130  if (C->isSelfClosing())
2131    OS << " SelfClosing";
2132}
2133
2134void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
2135  OS << " Name=\"" << C->getTagName() << "\"";
2136}
2137
2138void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) {
2139  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
2140  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
2141    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
2142}
2143
2144void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) {
2145  OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
2146
2147  if (C->isDirectionExplicit())
2148    OS << " explicitly";
2149  else
2150    OS << " implicitly";
2151
2152  if (C->hasParamName()) {
2153    if (C->isParamIndexValid())
2154      OS << " Param=\"" << C->getParamName(FC) << "\"";
2155    else
2156      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
2157  }
2158
2159  if (C->isParamIndexValid() && !C->isVarArgParam())
2160    OS << " ParamIndex=" << C->getParamIndex();
2161}
2162
2163void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) {
2164  if (C->hasParamName()) {
2165    if (C->isPositionValid())
2166      OS << " Param=\"" << C->getParamName(FC) << "\"";
2167    else
2168      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
2169  }
2170
2171  if (C->isPositionValid()) {
2172    OS << " Position=<";
2173    for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
2174      OS << C->getIndex(i);
2175      if (i != e - 1)
2176        OS << ", ";
2177    }
2178    OS << ">";
2179  }
2180}
2181
2182void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
2183  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
2184        " CloseName=\"" << C->getCloseName() << "\"";
2185}
2186
2187void ASTDumper::visitVerbatimBlockLineComment(
2188    const VerbatimBlockLineComment *C) {
2189  OS << " Text=\"" << C->getText() << "\"";
2190}
2191
2192void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
2193  OS << " Text=\"" << C->getText() << "\"";
2194}
2195
2196//===----------------------------------------------------------------------===//
2197// Type method implementations
2198//===----------------------------------------------------------------------===//
2199
2200void QualType::dump(const char *msg) const {
2201  if (msg)
2202    llvm::errs() << msg << ": ";
2203  dump();
2204}
2205
2206LLVM_DUMP_METHOD void QualType::dump() const {
2207  ASTDumper Dumper(llvm::errs(), nullptr, nullptr);
2208  Dumper.dumpTypeAsChild(*this);
2209}
2210
2211LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
2212
2213//===----------------------------------------------------------------------===//
2214// Decl method implementations
2215//===----------------------------------------------------------------------===//
2216
2217LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
2218
2219LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const {
2220  ASTDumper P(OS, &getASTContext().getCommentCommandTraits(),
2221              &getASTContext().getSourceManager());
2222  P.dumpDecl(this);
2223}
2224
2225LLVM_DUMP_METHOD void Decl::dumpColor() const {
2226  ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(),
2227              &getASTContext().getSourceManager(), /*ShowColors*/true);
2228  P.dumpDecl(this);
2229}
2230
2231LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
2232  dumpLookups(llvm::errs());
2233}
2234
2235LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
2236                                               bool DumpDecls) const {
2237  const DeclContext *DC = this;
2238  while (!DC->isTranslationUnit())
2239    DC = DC->getParent();
2240  ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
2241  ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager());
2242  P.dumpLookups(this, DumpDecls);
2243}
2244
2245//===----------------------------------------------------------------------===//
2246// Stmt method implementations
2247//===----------------------------------------------------------------------===//
2248
2249LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
2250  dump(llvm::errs(), SM);
2251}
2252
2253LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
2254  ASTDumper P(OS, nullptr, &SM);
2255  P.dumpStmt(this);
2256}
2257
2258LLVM_DUMP_METHOD void Stmt::dump() const {
2259  ASTDumper P(llvm::errs(), nullptr, nullptr);
2260  P.dumpStmt(this);
2261}
2262
2263LLVM_DUMP_METHOD void Stmt::dumpColor() const {
2264  ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
2265  P.dumpStmt(this);
2266}
2267
2268//===----------------------------------------------------------------------===//
2269// Comment method implementations
2270//===----------------------------------------------------------------------===//
2271
2272LLVM_DUMP_METHOD void Comment::dump() const {
2273  dump(llvm::errs(), nullptr, nullptr);
2274}
2275
2276LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
2277  dump(llvm::errs(), &Context.getCommentCommandTraits(),
2278       &Context.getSourceManager());
2279}
2280
2281void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
2282                   const SourceManager *SM) const {
2283  const FullComment *FC = dyn_cast<FullComment>(this);
2284  ASTDumper D(OS, Traits, SM);
2285  D.dumpFullComment(FC);
2286}
2287
2288LLVM_DUMP_METHOD void Comment::dumpColor() const {
2289  const FullComment *FC = dyn_cast<FullComment>(this);
2290  ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
2291  D.dumpFullComment(FC);
2292}
2293