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