xref: /freebsd/contrib/llvm-project/clang/lib/AST/TextNodeDumper.cpp (revision d9a42747950146bf03cda7f6e25d219253f8a57a)
1 //===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements AST dumping of components of individual AST nodes.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/TextNodeDumper.h"
14 #include "clang/AST/APValue.h"
15 #include "clang/AST/DeclFriend.h"
16 #include "clang/AST/DeclOpenMP.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/LocInfoType.h"
19 #include "clang/AST/Type.h"
20 #include "clang/Basic/Module.h"
21 #include "clang/Basic/SourceManager.h"
22 #include "clang/Basic/Specifiers.h"
23 #include "clang/Basic/TypeTraits.h"
24 #include "llvm/ADT/StringExtras.h"
25 
26 #include <algorithm>
27 #include <utility>
28 
29 using namespace clang;
30 
31 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
32 
33 template <typename T>
34 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
35   const T *First = D->getFirstDecl();
36   if (First != D)
37     OS << " first " << First;
38 }
39 
40 template <typename T>
41 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
42   const T *Prev = D->getPreviousDecl();
43   if (Prev)
44     OS << " prev " << Prev;
45 }
46 
47 /// Dump the previous declaration in the redeclaration chain for a declaration,
48 /// if any.
49 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
50   switch (D->getKind()) {
51 #define DECL(DERIVED, BASE)                                                    \
52   case Decl::DERIVED:                                                          \
53     return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
54 #define ABSTRACT_DECL(DECL)
55 #include "clang/AST/DeclNodes.inc"
56   }
57   llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
58 }
59 
60 TextNodeDumper::TextNodeDumper(raw_ostream &OS, const ASTContext &Context,
61                                bool ShowColors)
62     : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors),
63       Context(&Context), SM(&Context.getSourceManager()),
64       PrintPolicy(Context.getPrintingPolicy()),
65       Traits(&Context.getCommentCommandTraits()) {}
66 
67 TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors)
68     : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors) {}
69 
70 void TextNodeDumper::Visit(const comments::Comment *C,
71                            const comments::FullComment *FC) {
72   if (!C) {
73     ColorScope Color(OS, ShowColors, NullColor);
74     OS << "<<<NULL>>>";
75     return;
76   }
77 
78   {
79     ColorScope Color(OS, ShowColors, CommentColor);
80     OS << C->getCommentKindName();
81   }
82   dumpPointer(C);
83   dumpSourceRange(C->getSourceRange());
84 
85   ConstCommentVisitor<TextNodeDumper, void,
86                       const comments::FullComment *>::visit(C, FC);
87 }
88 
89 void TextNodeDumper::Visit(const Attr *A) {
90   {
91     ColorScope Color(OS, ShowColors, AttrColor);
92 
93     switch (A->getKind()) {
94 #define ATTR(X)                                                                \
95   case attr::X:                                                                \
96     OS << #X;                                                                  \
97     break;
98 #include "clang/Basic/AttrList.inc"
99     }
100     OS << "Attr";
101   }
102   dumpPointer(A);
103   dumpSourceRange(A->getRange());
104   if (A->isInherited())
105     OS << " Inherited";
106   if (A->isImplicit())
107     OS << " Implicit";
108 
109   ConstAttrVisitor<TextNodeDumper>::Visit(A);
110 }
111 
112 void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
113                            const Decl *From, StringRef Label) {
114   OS << "TemplateArgument";
115   if (R.isValid())
116     dumpSourceRange(R);
117 
118   if (From)
119     dumpDeclRef(From, Label);
120 
121   ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
122 }
123 
124 void TextNodeDumper::Visit(const Stmt *Node) {
125   if (!Node) {
126     ColorScope Color(OS, ShowColors, NullColor);
127     OS << "<<<NULL>>>";
128     return;
129   }
130   {
131     ColorScope Color(OS, ShowColors, StmtColor);
132     OS << Node->getStmtClassName();
133   }
134   dumpPointer(Node);
135   dumpSourceRange(Node->getSourceRange());
136 
137   if (const auto *E = dyn_cast<Expr>(Node)) {
138     dumpType(E->getType());
139 
140     if (E->containsErrors()) {
141       ColorScope Color(OS, ShowColors, ErrorsColor);
142       OS << " contains-errors";
143     }
144 
145     {
146       ColorScope Color(OS, ShowColors, ValueKindColor);
147       switch (E->getValueKind()) {
148       case VK_PRValue:
149         break;
150       case VK_LValue:
151         OS << " lvalue";
152         break;
153       case VK_XValue:
154         OS << " xvalue";
155         break;
156       }
157     }
158 
159     {
160       ColorScope Color(OS, ShowColors, ObjectKindColor);
161       switch (E->getObjectKind()) {
162       case OK_Ordinary:
163         break;
164       case OK_BitField:
165         OS << " bitfield";
166         break;
167       case OK_ObjCProperty:
168         OS << " objcproperty";
169         break;
170       case OK_ObjCSubscript:
171         OS << " objcsubscript";
172         break;
173       case OK_VectorComponent:
174         OS << " vectorcomponent";
175         break;
176       case OK_MatrixComponent:
177         OS << " matrixcomponent";
178         break;
179       }
180     }
181   }
182 
183   ConstStmtVisitor<TextNodeDumper>::Visit(Node);
184 }
185 
186 void TextNodeDumper::Visit(const Type *T) {
187   if (!T) {
188     ColorScope Color(OS, ShowColors, NullColor);
189     OS << "<<<NULL>>>";
190     return;
191   }
192   if (isa<LocInfoType>(T)) {
193     {
194       ColorScope Color(OS, ShowColors, TypeColor);
195       OS << "LocInfo Type";
196     }
197     dumpPointer(T);
198     return;
199   }
200 
201   {
202     ColorScope Color(OS, ShowColors, TypeColor);
203     OS << T->getTypeClassName() << "Type";
204   }
205   dumpPointer(T);
206   OS << " ";
207   dumpBareType(QualType(T, 0), false);
208 
209   QualType SingleStepDesugar =
210       T->getLocallyUnqualifiedSingleStepDesugaredType();
211   if (SingleStepDesugar != QualType(T, 0))
212     OS << " sugar";
213 
214   if (T->containsErrors()) {
215     ColorScope Color(OS, ShowColors, ErrorsColor);
216     OS << " contains-errors";
217   }
218 
219   if (T->isDependentType())
220     OS << " dependent";
221   else if (T->isInstantiationDependentType())
222     OS << " instantiation_dependent";
223 
224   if (T->isVariablyModifiedType())
225     OS << " variably_modified";
226   if (T->containsUnexpandedParameterPack())
227     OS << " contains_unexpanded_pack";
228   if (T->isFromAST())
229     OS << " imported";
230 
231   TypeVisitor<TextNodeDumper>::Visit(T);
232 }
233 
234 void TextNodeDumper::Visit(QualType T) {
235   OS << "QualType";
236   dumpPointer(T.getAsOpaquePtr());
237   OS << " ";
238   dumpBareType(T, false);
239   OS << " " << T.split().Quals.getAsString();
240 }
241 
242 void TextNodeDumper::Visit(const Decl *D) {
243   if (!D) {
244     ColorScope Color(OS, ShowColors, NullColor);
245     OS << "<<<NULL>>>";
246     return;
247   }
248 
249   {
250     ColorScope Color(OS, ShowColors, DeclKindNameColor);
251     OS << D->getDeclKindName() << "Decl";
252   }
253   dumpPointer(D);
254   if (D->getLexicalDeclContext() != D->getDeclContext())
255     OS << " parent " << cast<Decl>(D->getDeclContext());
256   dumpPreviousDecl(OS, D);
257   dumpSourceRange(D->getSourceRange());
258   OS << ' ';
259   dumpLocation(D->getLocation());
260   if (D->isFromASTFile())
261     OS << " imported";
262   if (Module *M = D->getOwningModule())
263     OS << " in " << M->getFullModuleName();
264   if (auto *ND = dyn_cast<NamedDecl>(D))
265     for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
266              const_cast<NamedDecl *>(ND)))
267       AddChild([=] { OS << "also in " << M->getFullModuleName(); });
268   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
269     if (!ND->isUnconditionallyVisible())
270       OS << " hidden";
271   if (D->isImplicit())
272     OS << " implicit";
273 
274   if (D->isUsed())
275     OS << " used";
276   else if (D->isThisDeclarationReferenced())
277     OS << " referenced";
278 
279   if (D->isInvalidDecl())
280     OS << " invalid";
281   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
282     if (FD->isConstexprSpecified())
283       OS << " constexpr";
284     if (FD->isConsteval())
285       OS << " consteval";
286     if (FD->isMultiVersion())
287       OS << " multiversion";
288   }
289 
290   if (!isa<FunctionDecl>(*D)) {
291     const auto *MD = dyn_cast<ObjCMethodDecl>(D);
292     if (!MD || !MD->isThisDeclarationADefinition()) {
293       const auto *DC = dyn_cast<DeclContext>(D);
294       if (DC && DC->hasExternalLexicalStorage()) {
295         ColorScope Color(OS, ShowColors, UndeserializedColor);
296         OS << " <undeserialized declarations>";
297       }
298     }
299   }
300 
301   ConstDeclVisitor<TextNodeDumper>::Visit(D);
302 }
303 
304 void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
305   OS << "CXXCtorInitializer";
306   if (Init->isAnyMemberInitializer()) {
307     OS << ' ';
308     dumpBareDeclRef(Init->getAnyMember());
309   } else if (Init->isBaseInitializer()) {
310     dumpType(QualType(Init->getBaseClass(), 0));
311   } else if (Init->isDelegatingInitializer()) {
312     dumpType(Init->getTypeSourceInfo()->getType());
313   } else {
314     llvm_unreachable("Unknown initializer type");
315   }
316 }
317 
318 void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
319   OS << "capture";
320   if (C.isByRef())
321     OS << " byref";
322   if (C.isNested())
323     OS << " nested";
324   if (C.getVariable()) {
325     OS << ' ';
326     dumpBareDeclRef(C.getVariable());
327   }
328 }
329 
330 void TextNodeDumper::Visit(const OMPClause *C) {
331   if (!C) {
332     ColorScope Color(OS, ShowColors, NullColor);
333     OS << "<<<NULL>>> OMPClause";
334     return;
335   }
336   {
337     ColorScope Color(OS, ShowColors, AttrColor);
338     StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind()));
339     OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
340        << ClauseName.drop_front() << "Clause";
341   }
342   dumpPointer(C);
343   dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
344   if (C->isImplicit())
345     OS << " <implicit>";
346 }
347 
348 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
349   const TypeSourceInfo *TSI = A.getTypeSourceInfo();
350   if (TSI) {
351     OS << "case ";
352     dumpType(TSI->getType());
353   } else {
354     OS << "default";
355   }
356 
357   if (A.isSelected())
358     OS << " selected";
359 }
360 
361 void TextNodeDumper::Visit(const concepts::Requirement *R) {
362   if (!R) {
363     ColorScope Color(OS, ShowColors, NullColor);
364     OS << "<<<NULL>>> Requirement";
365     return;
366   }
367 
368   {
369     ColorScope Color(OS, ShowColors, StmtColor);
370     switch (R->getKind()) {
371     case concepts::Requirement::RK_Type:
372       OS << "TypeRequirement";
373       break;
374     case concepts::Requirement::RK_Simple:
375       OS << "SimpleRequirement";
376       break;
377     case concepts::Requirement::RK_Compound:
378       OS << "CompoundRequirement";
379       break;
380     case concepts::Requirement::RK_Nested:
381       OS << "NestedRequirement";
382       break;
383     }
384   }
385 
386   dumpPointer(R);
387 
388   if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) {
389     if (ER->hasNoexceptRequirement())
390       OS << " noexcept";
391   }
392 
393   if (R->isDependent())
394     OS << " dependent";
395   else
396     OS << (R->isSatisfied() ? " satisfied" : " unsatisfied");
397   if (R->containsUnexpandedParameterPack())
398     OS << " contains_unexpanded_pack";
399 }
400 
401 static double GetApproxValue(const llvm::APFloat &F) {
402   llvm::APFloat V = F;
403   bool ignored;
404   V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
405             &ignored);
406   return V.convertToDouble();
407 }
408 
409 /// True if the \p APValue \p Value can be folded onto the current line.
410 static bool isSimpleAPValue(const APValue &Value) {
411   switch (Value.getKind()) {
412   case APValue::None:
413   case APValue::Indeterminate:
414   case APValue::Int:
415   case APValue::Float:
416   case APValue::FixedPoint:
417   case APValue::ComplexInt:
418   case APValue::ComplexFloat:
419   case APValue::LValue:
420   case APValue::MemberPointer:
421   case APValue::AddrLabelDiff:
422     return true;
423   case APValue::Vector:
424   case APValue::Array:
425   case APValue::Struct:
426     return false;
427   case APValue::Union:
428     return isSimpleAPValue(Value.getUnionValue());
429   }
430   llvm_unreachable("unexpected APValue kind!");
431 }
432 
433 /// Dump the children of the \p APValue \p Value.
434 ///
435 /// \param[in] Value          The \p APValue to visit
436 /// \param[in] Ty             The \p QualType passed to \p Visit
437 ///
438 /// \param[in] IdxToChildFun  A function mapping an \p APValue and an index
439 ///                           to one of the child of the \p APValue
440 ///
441 /// \param[in] NumChildren    \p IdxToChildFun will be called on \p Value with
442 ///                           the indices in the range \p [0,NumChildren(
443 ///
444 /// \param[in] LabelSingular  The label to use on a line with a single child
445 /// \param[in] LabelPlurial   The label to use on a line with multiple children
446 void TextNodeDumper::dumpAPValueChildren(
447     const APValue &Value, QualType Ty,
448     const APValue &(*IdxToChildFun)(const APValue &, unsigned),
449     unsigned NumChildren, StringRef LabelSingular, StringRef LabelPlurial) {
450   // To save some vertical space we print up to MaxChildrenPerLine APValues
451   // considered to be simple (by isSimpleAPValue) on a single line.
452   constexpr unsigned MaxChildrenPerLine = 4;
453   unsigned I = 0;
454   while (I < NumChildren) {
455     unsigned J = I;
456     while (J < NumChildren) {
457       if (isSimpleAPValue(IdxToChildFun(Value, J)) &&
458           (J - I < MaxChildrenPerLine)) {
459         ++J;
460         continue;
461       }
462       break;
463     }
464 
465     J = std::max(I + 1, J);
466 
467     // Print [I,J) on a single line.
468     AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() {
469       for (unsigned X = I; X < J; ++X) {
470         Visit(IdxToChildFun(Value, X), Ty);
471         if (X + 1 != J)
472           OS << ", ";
473       }
474     });
475     I = J;
476   }
477 }
478 
479 void TextNodeDumper::Visit(const APValue &Value, QualType Ty) {
480   ColorScope Color(OS, ShowColors, ValueKindColor);
481   switch (Value.getKind()) {
482   case APValue::None:
483     OS << "None";
484     return;
485   case APValue::Indeterminate:
486     OS << "Indeterminate";
487     return;
488   case APValue::Int:
489     OS << "Int ";
490     {
491       ColorScope Color(OS, ShowColors, ValueColor);
492       OS << Value.getInt();
493     }
494     return;
495   case APValue::Float:
496     OS << "Float ";
497     {
498       ColorScope Color(OS, ShowColors, ValueColor);
499       OS << GetApproxValue(Value.getFloat());
500     }
501     return;
502   case APValue::FixedPoint:
503     OS << "FixedPoint ";
504     {
505       ColorScope Color(OS, ShowColors, ValueColor);
506       OS << Value.getFixedPoint();
507     }
508     return;
509   case APValue::Vector: {
510     unsigned VectorLength = Value.getVectorLength();
511     OS << "Vector length=" << VectorLength;
512 
513     dumpAPValueChildren(
514         Value, Ty,
515         [](const APValue &Value, unsigned Index) -> const APValue & {
516           return Value.getVectorElt(Index);
517         },
518         VectorLength, "element", "elements");
519     return;
520   }
521   case APValue::ComplexInt:
522     OS << "ComplexInt ";
523     {
524       ColorScope Color(OS, ShowColors, ValueColor);
525       OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag()
526          << 'i';
527     }
528     return;
529   case APValue::ComplexFloat:
530     OS << "ComplexFloat ";
531     {
532       ColorScope Color(OS, ShowColors, ValueColor);
533       OS << GetApproxValue(Value.getComplexFloatReal()) << " + "
534          << GetApproxValue(Value.getComplexFloatImag()) << 'i';
535     }
536     return;
537   case APValue::LValue:
538     (void)Context;
539     OS << "LValue <todo>";
540     return;
541   case APValue::Array: {
542     unsigned ArraySize = Value.getArraySize();
543     unsigned NumInitializedElements = Value.getArrayInitializedElts();
544     OS << "Array size=" << ArraySize;
545 
546     dumpAPValueChildren(
547         Value, Ty,
548         [](const APValue &Value, unsigned Index) -> const APValue & {
549           return Value.getArrayInitializedElt(Index);
550         },
551         NumInitializedElements, "element", "elements");
552 
553     if (Value.hasArrayFiller()) {
554       AddChild("filler", [=] {
555         {
556           ColorScope Color(OS, ShowColors, ValueColor);
557           OS << ArraySize - NumInitializedElements << " x ";
558         }
559         Visit(Value.getArrayFiller(), Ty);
560       });
561     }
562 
563     return;
564   }
565   case APValue::Struct: {
566     OS << "Struct";
567 
568     dumpAPValueChildren(
569         Value, Ty,
570         [](const APValue &Value, unsigned Index) -> const APValue & {
571           return Value.getStructBase(Index);
572         },
573         Value.getStructNumBases(), "base", "bases");
574 
575     dumpAPValueChildren(
576         Value, Ty,
577         [](const APValue &Value, unsigned Index) -> const APValue & {
578           return Value.getStructField(Index);
579         },
580         Value.getStructNumFields(), "field", "fields");
581 
582     return;
583   }
584   case APValue::Union: {
585     OS << "Union";
586     {
587       ColorScope Color(OS, ShowColors, ValueColor);
588       if (const FieldDecl *FD = Value.getUnionField())
589         OS << " ." << *cast<NamedDecl>(FD);
590     }
591     // If the union value is considered to be simple, fold it into the
592     // current line to save some vertical space.
593     const APValue &UnionValue = Value.getUnionValue();
594     if (isSimpleAPValue(UnionValue)) {
595       OS << ' ';
596       Visit(UnionValue, Ty);
597     } else {
598       AddChild([=] { Visit(UnionValue, Ty); });
599     }
600 
601     return;
602   }
603   case APValue::MemberPointer:
604     OS << "MemberPointer <todo>";
605     return;
606   case APValue::AddrLabelDiff:
607     OS << "AddrLabelDiff <todo>";
608     return;
609   }
610   llvm_unreachable("Unknown APValue kind!");
611 }
612 
613 void TextNodeDumper::dumpPointer(const void *Ptr) {
614   ColorScope Color(OS, ShowColors, AddressColor);
615   OS << ' ' << Ptr;
616 }
617 
618 void TextNodeDumper::dumpLocation(SourceLocation Loc) {
619   if (!SM)
620     return;
621 
622   ColorScope Color(OS, ShowColors, LocationColor);
623   SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
624 
625   // The general format we print out is filename:line:col, but we drop pieces
626   // that haven't changed since the last loc printed.
627   PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
628 
629   if (PLoc.isInvalid()) {
630     OS << "<invalid sloc>";
631     return;
632   }
633 
634   if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
635     OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
636        << PLoc.getColumn();
637     LastLocFilename = PLoc.getFilename();
638     LastLocLine = PLoc.getLine();
639   } else if (PLoc.getLine() != LastLocLine) {
640     OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
641     LastLocLine = PLoc.getLine();
642   } else {
643     OS << "col" << ':' << PLoc.getColumn();
644   }
645 }
646 
647 void TextNodeDumper::dumpSourceRange(SourceRange R) {
648   // Can't translate locations if a SourceManager isn't available.
649   if (!SM)
650     return;
651 
652   OS << " <";
653   dumpLocation(R.getBegin());
654   if (R.getBegin() != R.getEnd()) {
655     OS << ", ";
656     dumpLocation(R.getEnd());
657   }
658   OS << ">";
659 
660   // <t2.c:123:421[blah], t2.c:412:321>
661 }
662 
663 void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
664   ColorScope Color(OS, ShowColors, TypeColor);
665 
666   SplitQualType T_split = T.split();
667   OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'";
668 
669   if (Desugar && !T.isNull()) {
670     // If the type is sugared, also dump a (shallow) desugared type.
671     SplitQualType D_split = T.getSplitDesugaredType();
672     if (T_split != D_split)
673       OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
674   }
675 }
676 
677 void TextNodeDumper::dumpType(QualType T) {
678   OS << ' ';
679   dumpBareType(T);
680 }
681 
682 void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
683   if (!D) {
684     ColorScope Color(OS, ShowColors, NullColor);
685     OS << "<<<NULL>>>";
686     return;
687   }
688 
689   {
690     ColorScope Color(OS, ShowColors, DeclKindNameColor);
691     OS << D->getDeclKindName();
692   }
693   dumpPointer(D);
694 
695   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
696     ColorScope Color(OS, ShowColors, DeclNameColor);
697     OS << " '" << ND->getDeclName() << '\'';
698   }
699 
700   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
701     dumpType(VD->getType());
702 }
703 
704 void TextNodeDumper::dumpName(const NamedDecl *ND) {
705   if (ND->getDeclName()) {
706     ColorScope Color(OS, ShowColors, DeclNameColor);
707     OS << ' ' << ND->getDeclName();
708   }
709 }
710 
711 void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
712   const auto AccessSpelling = getAccessSpelling(AS);
713   if (AccessSpelling.empty())
714     return;
715   OS << AccessSpelling;
716 }
717 
718 void TextNodeDumper::dumpCleanupObject(
719     const ExprWithCleanups::CleanupObject &C) {
720   if (auto *BD = C.dyn_cast<BlockDecl *>())
721     dumpDeclRef(BD, "cleanup");
722   else if (auto *CLE = C.dyn_cast<CompoundLiteralExpr *>())
723     AddChild([=] {
724       OS << "cleanup ";
725       {
726         ColorScope Color(OS, ShowColors, StmtColor);
727         OS << CLE->getStmtClassName();
728       }
729       dumpPointer(CLE);
730     });
731   else
732     llvm_unreachable("unexpected cleanup type");
733 }
734 
735 void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
736   if (!D)
737     return;
738 
739   AddChild([=] {
740     if (!Label.empty())
741       OS << Label << ' ';
742     dumpBareDeclRef(D);
743   });
744 }
745 
746 const char *TextNodeDumper::getCommandName(unsigned CommandID) {
747   if (Traits)
748     return Traits->getCommandInfo(CommandID)->Name;
749   const comments::CommandInfo *Info =
750       comments::CommandTraits::getBuiltinCommandInfo(CommandID);
751   if (Info)
752     return Info->Name;
753   return "<not a builtin command>";
754 }
755 
756 void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) {
757 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
758   if (FPO.has##NAME##Override())                                               \
759     OS << " " #NAME "=" << FPO.get##NAME##Override();
760 #include "clang/Basic/FPOptions.def"
761 }
762 
763 void TextNodeDumper::visitTextComment(const comments::TextComment *C,
764                                       const comments::FullComment *) {
765   OS << " Text=\"" << C->getText() << "\"";
766 }
767 
768 void TextNodeDumper::visitInlineCommandComment(
769     const comments::InlineCommandComment *C, const comments::FullComment *) {
770   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
771   switch (C->getRenderKind()) {
772   case comments::InlineCommandComment::RenderNormal:
773     OS << " RenderNormal";
774     break;
775   case comments::InlineCommandComment::RenderBold:
776     OS << " RenderBold";
777     break;
778   case comments::InlineCommandComment::RenderMonospaced:
779     OS << " RenderMonospaced";
780     break;
781   case comments::InlineCommandComment::RenderEmphasized:
782     OS << " RenderEmphasized";
783     break;
784   case comments::InlineCommandComment::RenderAnchor:
785     OS << " RenderAnchor";
786     break;
787   }
788 
789   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
790     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
791 }
792 
793 void TextNodeDumper::visitHTMLStartTagComment(
794     const comments::HTMLStartTagComment *C, const comments::FullComment *) {
795   OS << " Name=\"" << C->getTagName() << "\"";
796   if (C->getNumAttrs() != 0) {
797     OS << " Attrs: ";
798     for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
799       const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
800       OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
801     }
802   }
803   if (C->isSelfClosing())
804     OS << " SelfClosing";
805 }
806 
807 void TextNodeDumper::visitHTMLEndTagComment(
808     const comments::HTMLEndTagComment *C, const comments::FullComment *) {
809   OS << " Name=\"" << C->getTagName() << "\"";
810 }
811 
812 void TextNodeDumper::visitBlockCommandComment(
813     const comments::BlockCommandComment *C, const comments::FullComment *) {
814   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
815   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
816     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
817 }
818 
819 void TextNodeDumper::visitParamCommandComment(
820     const comments::ParamCommandComment *C, const comments::FullComment *FC) {
821   OS << " "
822      << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
823 
824   if (C->isDirectionExplicit())
825     OS << " explicitly";
826   else
827     OS << " implicitly";
828 
829   if (C->hasParamName()) {
830     if (C->isParamIndexValid())
831       OS << " Param=\"" << C->getParamName(FC) << "\"";
832     else
833       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
834   }
835 
836   if (C->isParamIndexValid() && !C->isVarArgParam())
837     OS << " ParamIndex=" << C->getParamIndex();
838 }
839 
840 void TextNodeDumper::visitTParamCommandComment(
841     const comments::TParamCommandComment *C, const comments::FullComment *FC) {
842   if (C->hasParamName()) {
843     if (C->isPositionValid())
844       OS << " Param=\"" << C->getParamName(FC) << "\"";
845     else
846       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
847   }
848 
849   if (C->isPositionValid()) {
850     OS << " Position=<";
851     for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
852       OS << C->getIndex(i);
853       if (i != e - 1)
854         OS << ", ";
855     }
856     OS << ">";
857   }
858 }
859 
860 void TextNodeDumper::visitVerbatimBlockComment(
861     const comments::VerbatimBlockComment *C, const comments::FullComment *) {
862   OS << " Name=\"" << getCommandName(C->getCommandID())
863      << "\""
864         " CloseName=\""
865      << C->getCloseName() << "\"";
866 }
867 
868 void TextNodeDumper::visitVerbatimBlockLineComment(
869     const comments::VerbatimBlockLineComment *C,
870     const comments::FullComment *) {
871   OS << " Text=\"" << C->getText() << "\"";
872 }
873 
874 void TextNodeDumper::visitVerbatimLineComment(
875     const comments::VerbatimLineComment *C, const comments::FullComment *) {
876   OS << " Text=\"" << C->getText() << "\"";
877 }
878 
879 void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
880   OS << " null";
881 }
882 
883 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
884   OS << " type";
885   dumpType(TA.getAsType());
886 }
887 
888 void TextNodeDumper::VisitDeclarationTemplateArgument(
889     const TemplateArgument &TA) {
890   OS << " decl";
891   dumpDeclRef(TA.getAsDecl());
892 }
893 
894 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
895   OS << " nullptr";
896 }
897 
898 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
899   OS << " integral " << TA.getAsIntegral();
900 }
901 
902 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
903   if (TA.getAsTemplate().getKind() == TemplateName::UsingTemplate)
904     OS << " using";
905   OS << " template ";
906   TA.getAsTemplate().dump(OS);
907 }
908 
909 void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
910     const TemplateArgument &TA) {
911   if (TA.getAsTemplateOrTemplatePattern().getKind() ==
912       TemplateName::UsingTemplate)
913     OS << " using";
914   OS << " template expansion ";
915   TA.getAsTemplateOrTemplatePattern().dump(OS);
916 }
917 
918 void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
919   OS << " expr";
920 }
921 
922 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
923   OS << " pack";
924 }
925 
926 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
927   if (Node->path_empty())
928     return;
929 
930   OS << " (";
931   bool First = true;
932   for (CastExpr::path_const_iterator I = Node->path_begin(),
933                                      E = Node->path_end();
934        I != E; ++I) {
935     const CXXBaseSpecifier *Base = *I;
936     if (!First)
937       OS << " -> ";
938 
939     const auto *RD =
940         cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
941 
942     if (Base->isVirtual())
943       OS << "virtual ";
944     OS << RD->getName();
945     First = false;
946   }
947 
948   OS << ')';
949 }
950 
951 void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
952   if (Node->hasInitStorage())
953     OS << " has_init";
954   if (Node->hasVarStorage())
955     OS << " has_var";
956   if (Node->hasElseStorage())
957     OS << " has_else";
958   if (Node->isConstexpr())
959     OS << " constexpr";
960   if (Node->isConsteval()) {
961     OS << " ";
962     if (Node->isNegatedConsteval())
963       OS << "!";
964     OS << "consteval";
965   }
966 }
967 
968 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
969   if (Node->hasInitStorage())
970     OS << " has_init";
971   if (Node->hasVarStorage())
972     OS << " has_var";
973 }
974 
975 void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
976   if (Node->hasVarStorage())
977     OS << " has_var";
978 }
979 
980 void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
981   OS << " '" << Node->getName() << "'";
982   if (Node->isSideEntry())
983     OS << " side_entry";
984 }
985 
986 void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
987   OS << " '" << Node->getLabel()->getName() << "'";
988   dumpPointer(Node->getLabel());
989 }
990 
991 void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
992   if (Node->caseStmtIsGNURange())
993     OS << " gnu_range";
994 }
995 
996 void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
997   if (Node->hasAPValueResult())
998     AddChild("value",
999              [=] { Visit(Node->getAPValueResult(), Node->getType()); });
1000 }
1001 
1002 void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
1003   if (Node->usesADL())
1004     OS << " adl";
1005   if (Node->hasStoredFPFeatures())
1006     printFPOptions(Node->getFPFeatures());
1007 }
1008 
1009 void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) {
1010   const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator());
1011   if (OperatorSpelling)
1012     OS << " '" << OperatorSpelling << "'";
1013 
1014   VisitCallExpr(Node);
1015 }
1016 
1017 void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
1018   OS << " <";
1019   {
1020     ColorScope Color(OS, ShowColors, CastColor);
1021     OS << Node->getCastKindName();
1022   }
1023   dumpBasePath(OS, Node);
1024   OS << ">";
1025   if (Node->hasStoredFPFeatures())
1026     printFPOptions(Node->getFPFeatures());
1027 }
1028 
1029 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
1030   VisitCastExpr(Node);
1031   if (Node->isPartOfExplicitCast())
1032     OS << " part_of_explicit_cast";
1033 }
1034 
1035 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1036   OS << " ";
1037   dumpBareDeclRef(Node->getDecl());
1038   if (Node->getDecl() != Node->getFoundDecl()) {
1039     OS << " (";
1040     dumpBareDeclRef(Node->getFoundDecl());
1041     OS << ")";
1042   }
1043   switch (Node->isNonOdrUse()) {
1044   case NOUR_None: break;
1045   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1046   case NOUR_Constant: OS << " non_odr_use_constant"; break;
1047   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1048   }
1049 }
1050 
1051 void TextNodeDumper::VisitUnresolvedLookupExpr(
1052     const UnresolvedLookupExpr *Node) {
1053   OS << " (";
1054   if (!Node->requiresADL())
1055     OS << "no ";
1056   OS << "ADL) = '" << Node->getName() << '\'';
1057 
1058   UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
1059                                        E = Node->decls_end();
1060   if (I == E)
1061     OS << " empty";
1062   for (; I != E; ++I)
1063     dumpPointer(*I);
1064 }
1065 
1066 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
1067   {
1068     ColorScope Color(OS, ShowColors, DeclKindNameColor);
1069     OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
1070   }
1071   OS << "='" << *Node->getDecl() << "'";
1072   dumpPointer(Node->getDecl());
1073   if (Node->isFreeIvar())
1074     OS << " isFreeIvar";
1075 }
1076 
1077 void TextNodeDumper::VisitSYCLUniqueStableNameExpr(
1078     const SYCLUniqueStableNameExpr *Node) {
1079   dumpType(Node->getTypeSourceInfo()->getType());
1080 }
1081 
1082 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
1083   OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1084 }
1085 
1086 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1087   ColorScope Color(OS, ShowColors, ValueColor);
1088   OS << " " << Node->getValue();
1089 }
1090 
1091 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1092   bool isSigned = Node->getType()->isSignedIntegerType();
1093   ColorScope Color(OS, ShowColors, ValueColor);
1094   OS << " " << toString(Node->getValue(), 10, isSigned);
1095 }
1096 
1097 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
1098   ColorScope Color(OS, ShowColors, ValueColor);
1099   OS << " " << Node->getValueAsString(/*Radix=*/10);
1100 }
1101 
1102 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1103   ColorScope Color(OS, ShowColors, ValueColor);
1104   OS << " " << Node->getValueAsApproximateDouble();
1105 }
1106 
1107 void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
1108   ColorScope Color(OS, ShowColors, ValueColor);
1109   OS << " ";
1110   Str->outputString(OS);
1111 }
1112 
1113 void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
1114   if (auto *Field = ILE->getInitializedFieldInUnion()) {
1115     OS << " field ";
1116     dumpBareDeclRef(Field);
1117   }
1118 }
1119 
1120 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
1121   if (E->isResultDependent())
1122     OS << " result_dependent";
1123 }
1124 
1125 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1126   OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
1127      << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1128   if (!Node->canOverflow())
1129     OS << " cannot overflow";
1130   if (Node->hasStoredFPFeatures())
1131     printFPOptions(Node->getStoredFPFeatures());
1132 }
1133 
1134 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1135     const UnaryExprOrTypeTraitExpr *Node) {
1136   OS << " " << getTraitSpelling(Node->getKind());
1137 
1138   if (Node->isArgumentType())
1139     dumpType(Node->getArgumentType());
1140 }
1141 
1142 void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
1143   OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
1144   dumpPointer(Node->getMemberDecl());
1145   switch (Node->isNonOdrUse()) {
1146   case NOUR_None: break;
1147   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1148   case NOUR_Constant: OS << " non_odr_use_constant"; break;
1149   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1150   }
1151 }
1152 
1153 void TextNodeDumper::VisitExtVectorElementExpr(
1154     const ExtVectorElementExpr *Node) {
1155   OS << " " << Node->getAccessor().getNameStart();
1156 }
1157 
1158 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1159   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1160   if (Node->hasStoredFPFeatures())
1161     printFPOptions(Node->getStoredFPFeatures());
1162 }
1163 
1164 void TextNodeDumper::VisitCompoundAssignOperator(
1165     const CompoundAssignOperator *Node) {
1166   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1167      << "' ComputeLHSTy=";
1168   dumpBareType(Node->getComputationLHSType());
1169   OS << " ComputeResultTy=";
1170   dumpBareType(Node->getComputationResultType());
1171   if (Node->hasStoredFPFeatures())
1172     printFPOptions(Node->getStoredFPFeatures());
1173 }
1174 
1175 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
1176   OS << " " << Node->getLabel()->getName();
1177   dumpPointer(Node->getLabel());
1178 }
1179 
1180 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
1181   OS << " " << Node->getCastName() << "<"
1182      << Node->getTypeAsWritten().getAsString() << ">"
1183      << " <" << Node->getCastKindName();
1184   dumpBasePath(OS, Node);
1185   OS << ">";
1186 }
1187 
1188 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1189   OS << " " << (Node->getValue() ? "true" : "false");
1190 }
1191 
1192 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1193   if (Node->isImplicit())
1194     OS << " implicit";
1195   OS << " this";
1196 }
1197 
1198 void TextNodeDumper::VisitCXXFunctionalCastExpr(
1199     const CXXFunctionalCastExpr *Node) {
1200   OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
1201      << Node->getCastKindName() << ">";
1202   if (Node->hasStoredFPFeatures())
1203     printFPOptions(Node->getFPFeatures());
1204 }
1205 
1206 void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) {
1207   VisitCXXNamedCastExpr(Node);
1208   if (Node->hasStoredFPFeatures())
1209     printFPOptions(Node->getFPFeatures());
1210 }
1211 
1212 void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
1213     const CXXUnresolvedConstructExpr *Node) {
1214   dumpType(Node->getTypeAsWritten());
1215   if (Node->isListInitialization())
1216     OS << " list";
1217 }
1218 
1219 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1220   CXXConstructorDecl *Ctor = Node->getConstructor();
1221   dumpType(Ctor->getType());
1222   if (Node->isElidable())
1223     OS << " elidable";
1224   if (Node->isListInitialization())
1225     OS << " list";
1226   if (Node->isStdInitListInitialization())
1227     OS << " std::initializer_list";
1228   if (Node->requiresZeroInitialization())
1229     OS << " zeroing";
1230 }
1231 
1232 void TextNodeDumper::VisitCXXBindTemporaryExpr(
1233     const CXXBindTemporaryExpr *Node) {
1234   OS << " (CXXTemporary";
1235   dumpPointer(Node);
1236   OS << ")";
1237 }
1238 
1239 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
1240   if (Node->isGlobalNew())
1241     OS << " global";
1242   if (Node->isArray())
1243     OS << " array";
1244   if (Node->getOperatorNew()) {
1245     OS << ' ';
1246     dumpBareDeclRef(Node->getOperatorNew());
1247   }
1248   // We could dump the deallocation function used in case of error, but it's
1249   // usually not that interesting.
1250 }
1251 
1252 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
1253   if (Node->isGlobalDelete())
1254     OS << " global";
1255   if (Node->isArrayForm())
1256     OS << " array";
1257   if (Node->getOperatorDelete()) {
1258     OS << ' ';
1259     dumpBareDeclRef(Node->getOperatorDelete());
1260   }
1261 }
1262 
1263 void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) {
1264   OS << " " << getTraitSpelling(Node->getTrait());
1265 }
1266 
1267 void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) {
1268   OS << " " << getTraitSpelling(Node->getTrait());
1269 }
1270 
1271 void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) {
1272   OS << " " << getTraitSpelling(Node->getTrait());
1273 }
1274 
1275 void TextNodeDumper::VisitMaterializeTemporaryExpr(
1276     const MaterializeTemporaryExpr *Node) {
1277   if (const ValueDecl *VD = Node->getExtendingDecl()) {
1278     OS << " extended by ";
1279     dumpBareDeclRef(VD);
1280   }
1281 }
1282 
1283 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
1284   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
1285     dumpCleanupObject(Node->getObject(i));
1286 }
1287 
1288 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
1289   dumpPointer(Node->getPack());
1290   dumpName(Node->getPack());
1291 }
1292 
1293 void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
1294     const CXXDependentScopeMemberExpr *Node) {
1295   OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
1296 }
1297 
1298 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
1299   OS << " selector=";
1300   Node->getSelector().print(OS);
1301   switch (Node->getReceiverKind()) {
1302   case ObjCMessageExpr::Instance:
1303     break;
1304 
1305   case ObjCMessageExpr::Class:
1306     OS << " class=";
1307     dumpBareType(Node->getClassReceiver());
1308     break;
1309 
1310   case ObjCMessageExpr::SuperInstance:
1311     OS << " super (instance)";
1312     break;
1313 
1314   case ObjCMessageExpr::SuperClass:
1315     OS << " super (class)";
1316     break;
1317   }
1318 }
1319 
1320 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
1321   if (auto *BoxingMethod = Node->getBoxingMethod()) {
1322     OS << " selector=";
1323     BoxingMethod->getSelector().print(OS);
1324   }
1325 }
1326 
1327 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
1328   if (!Node->getCatchParamDecl())
1329     OS << " catch all";
1330 }
1331 
1332 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
1333   dumpType(Node->getEncodedType());
1334 }
1335 
1336 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1337   OS << " ";
1338   Node->getSelector().print(OS);
1339 }
1340 
1341 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
1342   OS << ' ' << *Node->getProtocol();
1343 }
1344 
1345 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
1346   if (Node->isImplicitProperty()) {
1347     OS << " Kind=MethodRef Getter=\"";
1348     if (Node->getImplicitPropertyGetter())
1349       Node->getImplicitPropertyGetter()->getSelector().print(OS);
1350     else
1351       OS << "(null)";
1352 
1353     OS << "\" Setter=\"";
1354     if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
1355       Setter->getSelector().print(OS);
1356     else
1357       OS << "(null)";
1358     OS << "\"";
1359   } else {
1360     OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
1361        << '"';
1362   }
1363 
1364   if (Node->isSuperReceiver())
1365     OS << " super";
1366 
1367   OS << " Messaging=";
1368   if (Node->isMessagingGetter() && Node->isMessagingSetter())
1369     OS << "Getter&Setter";
1370   else if (Node->isMessagingGetter())
1371     OS << "Getter";
1372   else if (Node->isMessagingSetter())
1373     OS << "Setter";
1374 }
1375 
1376 void TextNodeDumper::VisitObjCSubscriptRefExpr(
1377     const ObjCSubscriptRefExpr *Node) {
1378   if (Node->isArraySubscriptRefExpr())
1379     OS << " Kind=ArraySubscript GetterForArray=\"";
1380   else
1381     OS << " Kind=DictionarySubscript GetterForDictionary=\"";
1382   if (Node->getAtIndexMethodDecl())
1383     Node->getAtIndexMethodDecl()->getSelector().print(OS);
1384   else
1385     OS << "(null)";
1386 
1387   if (Node->isArraySubscriptRefExpr())
1388     OS << "\" SetterForArray=\"";
1389   else
1390     OS << "\" SetterForDictionary=\"";
1391   if (Node->setAtIndexMethodDecl())
1392     Node->setAtIndexMethodDecl()->getSelector().print(OS);
1393   else
1394     OS << "(null)";
1395 }
1396 
1397 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
1398   OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
1399 }
1400 
1401 void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) {
1402   OS << " ";
1403   for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1404     Visit(Node->getIteratorDecl(I));
1405     OS << " = ";
1406     const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1407     OS << " begin ";
1408     Visit(Range.Begin);
1409     OS << " end ";
1410     Visit(Range.End);
1411     if (Range.Step) {
1412       OS << " step ";
1413       Visit(Range.Step);
1414     }
1415   }
1416 }
1417 
1418 void TextNodeDumper::VisitConceptSpecializationExpr(
1419     const ConceptSpecializationExpr *Node) {
1420   OS << " ";
1421   dumpBareDeclRef(Node->getFoundDecl());
1422 }
1423 
1424 void TextNodeDumper::VisitRequiresExpr(
1425     const RequiresExpr *Node) {
1426   if (!Node->isValueDependent())
1427     OS << (Node->isSatisfied() ? " satisfied" : " unsatisfied");
1428 }
1429 
1430 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
1431   if (T->isSpelledAsLValue())
1432     OS << " written as lvalue reference";
1433 }
1434 
1435 void TextNodeDumper::VisitArrayType(const ArrayType *T) {
1436   switch (T->getSizeModifier()) {
1437   case ArrayType::Normal:
1438     break;
1439   case ArrayType::Static:
1440     OS << " static";
1441     break;
1442   case ArrayType::Star:
1443     OS << " *";
1444     break;
1445   }
1446   OS << " " << T->getIndexTypeQualifiers().getAsString();
1447 }
1448 
1449 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
1450   OS << " " << T->getSize();
1451   VisitArrayType(T);
1452 }
1453 
1454 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
1455   OS << " ";
1456   dumpSourceRange(T->getBracketsRange());
1457   VisitArrayType(T);
1458 }
1459 
1460 void TextNodeDumper::VisitDependentSizedArrayType(
1461     const DependentSizedArrayType *T) {
1462   VisitArrayType(T);
1463   OS << " ";
1464   dumpSourceRange(T->getBracketsRange());
1465 }
1466 
1467 void TextNodeDumper::VisitDependentSizedExtVectorType(
1468     const DependentSizedExtVectorType *T) {
1469   OS << " ";
1470   dumpLocation(T->getAttributeLoc());
1471 }
1472 
1473 void TextNodeDumper::VisitVectorType(const VectorType *T) {
1474   switch (T->getVectorKind()) {
1475   case VectorType::GenericVector:
1476     break;
1477   case VectorType::AltiVecVector:
1478     OS << " altivec";
1479     break;
1480   case VectorType::AltiVecPixel:
1481     OS << " altivec pixel";
1482     break;
1483   case VectorType::AltiVecBool:
1484     OS << " altivec bool";
1485     break;
1486   case VectorType::NeonVector:
1487     OS << " neon";
1488     break;
1489   case VectorType::NeonPolyVector:
1490     OS << " neon poly";
1491     break;
1492   case VectorType::SveFixedLengthDataVector:
1493     OS << " fixed-length sve data vector";
1494     break;
1495   case VectorType::SveFixedLengthPredicateVector:
1496     OS << " fixed-length sve predicate vector";
1497     break;
1498   }
1499   OS << " " << T->getNumElements();
1500 }
1501 
1502 void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
1503   auto EI = T->getExtInfo();
1504   if (EI.getNoReturn())
1505     OS << " noreturn";
1506   if (EI.getProducesResult())
1507     OS << " produces_result";
1508   if (EI.getHasRegParm())
1509     OS << " regparm " << EI.getRegParm();
1510   OS << " " << FunctionType::getNameForCallConv(EI.getCC());
1511 }
1512 
1513 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
1514   auto EPI = T->getExtProtoInfo();
1515   if (EPI.HasTrailingReturn)
1516     OS << " trailing_return";
1517   if (T->isConst())
1518     OS << " const";
1519   if (T->isVolatile())
1520     OS << " volatile";
1521   if (T->isRestrict())
1522     OS << " restrict";
1523   if (T->getExtProtoInfo().Variadic)
1524     OS << " variadic";
1525   switch (EPI.RefQualifier) {
1526   case RQ_None:
1527     break;
1528   case RQ_LValue:
1529     OS << " &";
1530     break;
1531   case RQ_RValue:
1532     OS << " &&";
1533     break;
1534   }
1535   // FIXME: Exception specification.
1536   // FIXME: Consumed parameters.
1537   VisitFunctionType(T);
1538 }
1539 
1540 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1541   dumpDeclRef(T->getDecl());
1542 }
1543 
1544 void TextNodeDumper::VisitUsingType(const UsingType *T) {
1545   dumpDeclRef(T->getFoundDecl());
1546 }
1547 
1548 void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
1549   dumpDeclRef(T->getDecl());
1550 }
1551 
1552 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
1553   switch (T->getUTTKind()) {
1554   case UnaryTransformType::EnumUnderlyingType:
1555     OS << " underlying_type";
1556     break;
1557   }
1558 }
1559 
1560 void TextNodeDumper::VisitTagType(const TagType *T) {
1561   dumpDeclRef(T->getDecl());
1562 }
1563 
1564 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1565   OS << " depth " << T->getDepth() << " index " << T->getIndex();
1566   if (T->isParameterPack())
1567     OS << " pack";
1568   dumpDeclRef(T->getDecl());
1569 }
1570 
1571 void TextNodeDumper::VisitAutoType(const AutoType *T) {
1572   if (T->isDecltypeAuto())
1573     OS << " decltype(auto)";
1574   if (!T->isDeduced())
1575     OS << " undeduced";
1576   if (T->isConstrained()) {
1577     dumpDeclRef(T->getTypeConstraintConcept());
1578     for (const auto &Arg : T->getTypeConstraintArguments())
1579       VisitTemplateArgument(Arg);
1580   }
1581 }
1582 
1583 void TextNodeDumper::VisitDeducedTemplateSpecializationType(
1584     const DeducedTemplateSpecializationType *T) {
1585   if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
1586     OS << " using";
1587 }
1588 
1589 void TextNodeDumper::VisitTemplateSpecializationType(
1590     const TemplateSpecializationType *T) {
1591   if (T->isTypeAlias())
1592     OS << " alias";
1593   if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
1594     OS << " using";
1595   OS << " ";
1596   T->getTemplateName().dump(OS);
1597 }
1598 
1599 void TextNodeDumper::VisitInjectedClassNameType(
1600     const InjectedClassNameType *T) {
1601   dumpDeclRef(T->getDecl());
1602 }
1603 
1604 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1605   dumpDeclRef(T->getDecl());
1606 }
1607 
1608 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
1609   if (auto N = T->getNumExpansions())
1610     OS << " expansions " << *N;
1611 }
1612 
1613 void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
1614 
1615 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
1616   dumpName(D);
1617   dumpType(D->getUnderlyingType());
1618   if (D->isModulePrivate())
1619     OS << " __module_private__";
1620 }
1621 
1622 void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
1623   if (D->isScoped()) {
1624     if (D->isScopedUsingClassTag())
1625       OS << " class";
1626     else
1627       OS << " struct";
1628   }
1629   dumpName(D);
1630   if (D->isModulePrivate())
1631     OS << " __module_private__";
1632   if (D->isFixed())
1633     dumpType(D->getIntegerType());
1634 }
1635 
1636 void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
1637   OS << ' ' << D->getKindName();
1638   dumpName(D);
1639   if (D->isModulePrivate())
1640     OS << " __module_private__";
1641   if (D->isCompleteDefinition())
1642     OS << " definition";
1643 }
1644 
1645 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
1646   dumpName(D);
1647   dumpType(D->getType());
1648 }
1649 
1650 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
1651   dumpName(D);
1652   dumpType(D->getType());
1653 
1654   for (const auto *Child : D->chain())
1655     dumpDeclRef(Child);
1656 }
1657 
1658 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
1659   dumpName(D);
1660   dumpType(D->getType());
1661 
1662   StorageClass SC = D->getStorageClass();
1663   if (SC != SC_None)
1664     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1665   if (D->isInlineSpecified())
1666     OS << " inline";
1667   if (D->isVirtualAsWritten())
1668     OS << " virtual";
1669   if (D->isModulePrivate())
1670     OS << " __module_private__";
1671 
1672   if (D->isPure())
1673     OS << " pure";
1674   if (D->isDefaulted()) {
1675     OS << " default";
1676     if (D->isDeleted())
1677       OS << "_delete";
1678   }
1679   if (D->isDeletedAsWritten())
1680     OS << " delete";
1681   if (D->isTrivial())
1682     OS << " trivial";
1683 
1684   if (D->isIneligibleOrNotSelected())
1685     OS << (isa<CXXDestructorDecl>(D) ? " not_selected" : " ineligible");
1686 
1687   if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
1688     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
1689     switch (EPI.ExceptionSpec.Type) {
1690     default:
1691       break;
1692     case EST_Unevaluated:
1693       OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
1694       break;
1695     case EST_Uninstantiated:
1696       OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
1697       break;
1698     }
1699   }
1700 
1701   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
1702     if (MD->size_overridden_methods() != 0) {
1703       auto dumpOverride = [=](const CXXMethodDecl *D) {
1704         SplitQualType T_split = D->getType().split();
1705         OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName()
1706            << " '" << QualType::getAsString(T_split, PrintPolicy) << "'";
1707       };
1708 
1709       AddChild([=] {
1710         auto Overrides = MD->overridden_methods();
1711         OS << "Overrides: [ ";
1712         dumpOverride(*Overrides.begin());
1713         for (const auto *Override :
1714              llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
1715           OS << ", ";
1716           dumpOverride(Override);
1717         }
1718         OS << " ]";
1719       });
1720     }
1721   }
1722 
1723   if (!D->isInlineSpecified() && D->isInlined()) {
1724     OS << " implicit-inline";
1725   }
1726   // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
1727   // the Params are set later, it is possible for a dump during debugging to
1728   // encounter a FunctionDecl that has been created but hasn't been assigned
1729   // ParmVarDecls yet.
1730   if (!D->param_empty() && !D->param_begin())
1731     OS << " <<<NULL params x " << D->getNumParams() << ">>>";
1732 }
1733 
1734 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
1735     const LifetimeExtendedTemporaryDecl *D) {
1736   OS << " extended by ";
1737   dumpBareDeclRef(D->getExtendingDecl());
1738   OS << " mangling ";
1739   {
1740     ColorScope Color(OS, ShowColors, ValueColor);
1741     OS << D->getManglingNumber();
1742   }
1743 }
1744 
1745 void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
1746   dumpName(D);
1747   dumpType(D->getType());
1748   if (D->isMutable())
1749     OS << " mutable";
1750   if (D->isModulePrivate())
1751     OS << " __module_private__";
1752 }
1753 
1754 void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
1755   dumpName(D);
1756   dumpType(D->getType());
1757   StorageClass SC = D->getStorageClass();
1758   if (SC != SC_None)
1759     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1760   switch (D->getTLSKind()) {
1761   case VarDecl::TLS_None:
1762     break;
1763   case VarDecl::TLS_Static:
1764     OS << " tls";
1765     break;
1766   case VarDecl::TLS_Dynamic:
1767     OS << " tls_dynamic";
1768     break;
1769   }
1770   if (D->isModulePrivate())
1771     OS << " __module_private__";
1772   if (D->isNRVOVariable())
1773     OS << " nrvo";
1774   if (D->isInline())
1775     OS << " inline";
1776   if (D->isConstexpr())
1777     OS << " constexpr";
1778   if (D->hasInit()) {
1779     switch (D->getInitStyle()) {
1780     case VarDecl::CInit:
1781       OS << " cinit";
1782       break;
1783     case VarDecl::CallInit:
1784       OS << " callinit";
1785       break;
1786     case VarDecl::ListInit:
1787       OS << " listinit";
1788       break;
1789     }
1790   }
1791   if (D->needsDestruction(D->getASTContext()))
1792     OS << " destroyed";
1793   if (D->isParameterPack())
1794     OS << " pack";
1795 
1796   if (D->hasInit()) {
1797     const Expr *E = D->getInit();
1798     // Only dump the value of constexpr VarDecls for now.
1799     if (E && !E->isValueDependent() && D->isConstexpr()) {
1800       const APValue *Value = D->evaluateValue();
1801       if (Value)
1802         AddChild("value", [=] { Visit(*Value, E->getType()); });
1803     }
1804   }
1805 }
1806 
1807 void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
1808   dumpName(D);
1809   dumpType(D->getType());
1810 }
1811 
1812 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
1813   if (D->isNothrow())
1814     OS << " nothrow";
1815 }
1816 
1817 void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
1818   OS << ' ' << D->getImportedModule()->getFullModuleName();
1819 
1820   for (Decl *InitD :
1821        D->getASTContext().getModuleInitializers(D->getImportedModule()))
1822     dumpDeclRef(InitD, "initializer");
1823 }
1824 
1825 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
1826   OS << ' ';
1827   switch (D->getCommentKind()) {
1828   case PCK_Unknown:
1829     llvm_unreachable("unexpected pragma comment kind");
1830   case PCK_Compiler:
1831     OS << "compiler";
1832     break;
1833   case PCK_ExeStr:
1834     OS << "exestr";
1835     break;
1836   case PCK_Lib:
1837     OS << "lib";
1838     break;
1839   case PCK_Linker:
1840     OS << "linker";
1841     break;
1842   case PCK_User:
1843     OS << "user";
1844     break;
1845   }
1846   StringRef Arg = D->getArg();
1847   if (!Arg.empty())
1848     OS << " \"" << Arg << "\"";
1849 }
1850 
1851 void TextNodeDumper::VisitPragmaDetectMismatchDecl(
1852     const PragmaDetectMismatchDecl *D) {
1853   OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
1854 }
1855 
1856 void TextNodeDumper::VisitOMPExecutableDirective(
1857     const OMPExecutableDirective *D) {
1858   if (D->isStandaloneDirective())
1859     OS << " openmp_standalone_directive";
1860 }
1861 
1862 void TextNodeDumper::VisitOMPDeclareReductionDecl(
1863     const OMPDeclareReductionDecl *D) {
1864   dumpName(D);
1865   dumpType(D->getType());
1866   OS << " combiner";
1867   dumpPointer(D->getCombiner());
1868   if (const auto *Initializer = D->getInitializer()) {
1869     OS << " initializer";
1870     dumpPointer(Initializer);
1871     switch (D->getInitializerKind()) {
1872     case OMPDeclareReductionDecl::DirectInit:
1873       OS << " omp_priv = ";
1874       break;
1875     case OMPDeclareReductionDecl::CopyInit:
1876       OS << " omp_priv ()";
1877       break;
1878     case OMPDeclareReductionDecl::CallInit:
1879       break;
1880     }
1881   }
1882 }
1883 
1884 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
1885   for (const auto *C : D->clauselists()) {
1886     AddChild([=] {
1887       if (!C) {
1888         ColorScope Color(OS, ShowColors, NullColor);
1889         OS << "<<<NULL>>> OMPClause";
1890         return;
1891       }
1892       {
1893         ColorScope Color(OS, ShowColors, AttrColor);
1894         StringRef ClauseName(
1895             llvm::omp::getOpenMPClauseName(C->getClauseKind()));
1896         OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
1897            << ClauseName.drop_front() << "Clause";
1898       }
1899       dumpPointer(C);
1900       dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
1901     });
1902   }
1903 }
1904 
1905 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
1906   dumpName(D);
1907   dumpType(D->getType());
1908 }
1909 
1910 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
1911   dumpName(D);
1912   if (D->isInline())
1913     OS << " inline";
1914   if (!D->isOriginalNamespace())
1915     dumpDeclRef(D->getOriginalNamespace(), "original");
1916 }
1917 
1918 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
1919   OS << ' ';
1920   dumpBareDeclRef(D->getNominatedNamespace());
1921 }
1922 
1923 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
1924   dumpName(D);
1925   dumpDeclRef(D->getAliasedNamespace());
1926 }
1927 
1928 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
1929   dumpName(D);
1930   dumpType(D->getUnderlyingType());
1931 }
1932 
1933 void TextNodeDumper::VisitTypeAliasTemplateDecl(
1934     const TypeAliasTemplateDecl *D) {
1935   dumpName(D);
1936 }
1937 
1938 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
1939   VisitRecordDecl(D);
1940   if (!D->isCompleteDefinition())
1941     return;
1942 
1943   AddChild([=] {
1944     {
1945       ColorScope Color(OS, ShowColors, DeclKindNameColor);
1946       OS << "DefinitionData";
1947     }
1948 #define FLAG(fn, name)                                                         \
1949   if (D->fn())                                                                 \
1950     OS << " " #name;
1951     FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
1952 
1953     FLAG(isGenericLambda, generic);
1954     FLAG(isLambda, lambda);
1955 
1956     FLAG(isAnonymousStructOrUnion, is_anonymous);
1957     FLAG(canPassInRegisters, pass_in_registers);
1958     FLAG(isEmpty, empty);
1959     FLAG(isAggregate, aggregate);
1960     FLAG(isStandardLayout, standard_layout);
1961     FLAG(isTriviallyCopyable, trivially_copyable);
1962     FLAG(isPOD, pod);
1963     FLAG(isTrivial, trivial);
1964     FLAG(isPolymorphic, polymorphic);
1965     FLAG(isAbstract, abstract);
1966     FLAG(isLiteral, literal);
1967 
1968     FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
1969     FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
1970     FLAG(hasMutableFields, has_mutable_fields);
1971     FLAG(hasVariantMembers, has_variant_members);
1972     FLAG(allowConstDefaultInit, can_const_default_init);
1973 
1974     AddChild([=] {
1975       {
1976         ColorScope Color(OS, ShowColors, DeclKindNameColor);
1977         OS << "DefaultConstructor";
1978       }
1979       FLAG(hasDefaultConstructor, exists);
1980       FLAG(hasTrivialDefaultConstructor, trivial);
1981       FLAG(hasNonTrivialDefaultConstructor, non_trivial);
1982       FLAG(hasUserProvidedDefaultConstructor, user_provided);
1983       FLAG(hasConstexprDefaultConstructor, constexpr);
1984       FLAG(needsImplicitDefaultConstructor, needs_implicit);
1985       FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
1986     });
1987 
1988     AddChild([=] {
1989       {
1990         ColorScope Color(OS, ShowColors, DeclKindNameColor);
1991         OS << "CopyConstructor";
1992       }
1993       FLAG(hasSimpleCopyConstructor, simple);
1994       FLAG(hasTrivialCopyConstructor, trivial);
1995       FLAG(hasNonTrivialCopyConstructor, non_trivial);
1996       FLAG(hasUserDeclaredCopyConstructor, user_declared);
1997       FLAG(hasCopyConstructorWithConstParam, has_const_param);
1998       FLAG(needsImplicitCopyConstructor, needs_implicit);
1999       FLAG(needsOverloadResolutionForCopyConstructor,
2000            needs_overload_resolution);
2001       if (!D->needsOverloadResolutionForCopyConstructor())
2002         FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
2003       FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
2004     });
2005 
2006     AddChild([=] {
2007       {
2008         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2009         OS << "MoveConstructor";
2010       }
2011       FLAG(hasMoveConstructor, exists);
2012       FLAG(hasSimpleMoveConstructor, simple);
2013       FLAG(hasTrivialMoveConstructor, trivial);
2014       FLAG(hasNonTrivialMoveConstructor, non_trivial);
2015       FLAG(hasUserDeclaredMoveConstructor, user_declared);
2016       FLAG(needsImplicitMoveConstructor, needs_implicit);
2017       FLAG(needsOverloadResolutionForMoveConstructor,
2018            needs_overload_resolution);
2019       if (!D->needsOverloadResolutionForMoveConstructor())
2020         FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
2021     });
2022 
2023     AddChild([=] {
2024       {
2025         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2026         OS << "CopyAssignment";
2027       }
2028       FLAG(hasSimpleCopyAssignment, simple);
2029       FLAG(hasTrivialCopyAssignment, trivial);
2030       FLAG(hasNonTrivialCopyAssignment, non_trivial);
2031       FLAG(hasCopyAssignmentWithConstParam, has_const_param);
2032       FLAG(hasUserDeclaredCopyAssignment, user_declared);
2033       FLAG(needsImplicitCopyAssignment, needs_implicit);
2034       FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
2035       FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
2036     });
2037 
2038     AddChild([=] {
2039       {
2040         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2041         OS << "MoveAssignment";
2042       }
2043       FLAG(hasMoveAssignment, exists);
2044       FLAG(hasSimpleMoveAssignment, simple);
2045       FLAG(hasTrivialMoveAssignment, trivial);
2046       FLAG(hasNonTrivialMoveAssignment, non_trivial);
2047       FLAG(hasUserDeclaredMoveAssignment, user_declared);
2048       FLAG(needsImplicitMoveAssignment, needs_implicit);
2049       FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
2050     });
2051 
2052     AddChild([=] {
2053       {
2054         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2055         OS << "Destructor";
2056       }
2057       FLAG(hasSimpleDestructor, simple);
2058       FLAG(hasIrrelevantDestructor, irrelevant);
2059       FLAG(hasTrivialDestructor, trivial);
2060       FLAG(hasNonTrivialDestructor, non_trivial);
2061       FLAG(hasUserDeclaredDestructor, user_declared);
2062       FLAG(hasConstexprDestructor, constexpr);
2063       FLAG(needsImplicitDestructor, needs_implicit);
2064       FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
2065       if (!D->needsOverloadResolutionForDestructor())
2066         FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
2067     });
2068   });
2069 
2070   for (const auto &I : D->bases()) {
2071     AddChild([=] {
2072       if (I.isVirtual())
2073         OS << "virtual ";
2074       dumpAccessSpecifier(I.getAccessSpecifier());
2075       dumpType(I.getType());
2076       if (I.isPackExpansion())
2077         OS << "...";
2078     });
2079   }
2080 }
2081 
2082 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
2083   dumpName(D);
2084 }
2085 
2086 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
2087   dumpName(D);
2088 }
2089 
2090 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
2091   dumpName(D);
2092 }
2093 
2094 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
2095   dumpName(D);
2096 }
2097 
2098 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2099   if (const auto *TC = D->getTypeConstraint()) {
2100     OS << " ";
2101     dumpBareDeclRef(TC->getNamedConcept());
2102     if (TC->getNamedConcept() != TC->getFoundDecl()) {
2103       OS << " (";
2104       dumpBareDeclRef(TC->getFoundDecl());
2105       OS << ")";
2106     }
2107   } else if (D->wasDeclaredWithTypename())
2108     OS << " typename";
2109   else
2110     OS << " class";
2111   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2112   if (D->isParameterPack())
2113     OS << " ...";
2114   dumpName(D);
2115 }
2116 
2117 void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2118     const NonTypeTemplateParmDecl *D) {
2119   dumpType(D->getType());
2120   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2121   if (D->isParameterPack())
2122     OS << " ...";
2123   dumpName(D);
2124 }
2125 
2126 void TextNodeDumper::VisitTemplateTemplateParmDecl(
2127     const TemplateTemplateParmDecl *D) {
2128   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2129   if (D->isParameterPack())
2130     OS << " ...";
2131   dumpName(D);
2132 }
2133 
2134 void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
2135   OS << ' ';
2136   if (D->getQualifier())
2137     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2138   OS << D->getDeclName();
2139 }
2140 
2141 void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) {
2142   OS << ' ';
2143   dumpBareDeclRef(D->getEnumDecl());
2144 }
2145 
2146 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2147     const UnresolvedUsingTypenameDecl *D) {
2148   OS << ' ';
2149   if (D->getQualifier())
2150     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2151   OS << D->getDeclName();
2152 }
2153 
2154 void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2155     const UnresolvedUsingValueDecl *D) {
2156   OS << ' ';
2157   if (D->getQualifier())
2158     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2159   OS << D->getDeclName();
2160   dumpType(D->getType());
2161 }
2162 
2163 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
2164   OS << ' ';
2165   dumpBareDeclRef(D->getTargetDecl());
2166 }
2167 
2168 void TextNodeDumper::VisitConstructorUsingShadowDecl(
2169     const ConstructorUsingShadowDecl *D) {
2170   if (D->constructsVirtualBase())
2171     OS << " virtual";
2172 
2173   AddChild([=] {
2174     OS << "target ";
2175     dumpBareDeclRef(D->getTargetDecl());
2176   });
2177 
2178   AddChild([=] {
2179     OS << "nominated ";
2180     dumpBareDeclRef(D->getNominatedBaseClass());
2181     OS << ' ';
2182     dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
2183   });
2184 
2185   AddChild([=] {
2186     OS << "constructed ";
2187     dumpBareDeclRef(D->getConstructedBaseClass());
2188     OS << ' ';
2189     dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
2190   });
2191 }
2192 
2193 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
2194   switch (D->getLanguage()) {
2195   case LinkageSpecDecl::lang_c:
2196     OS << " C";
2197     break;
2198   case LinkageSpecDecl::lang_cxx:
2199     OS << " C++";
2200     break;
2201   }
2202 }
2203 
2204 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
2205   OS << ' ';
2206   dumpAccessSpecifier(D->getAccess());
2207 }
2208 
2209 void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
2210   if (TypeSourceInfo *T = D->getFriendType())
2211     dumpType(T->getType());
2212 }
2213 
2214 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
2215   dumpName(D);
2216   dumpType(D->getType());
2217   if (D->getSynthesize())
2218     OS << " synthesize";
2219 
2220   switch (D->getAccessControl()) {
2221   case ObjCIvarDecl::None:
2222     OS << " none";
2223     break;
2224   case ObjCIvarDecl::Private:
2225     OS << " private";
2226     break;
2227   case ObjCIvarDecl::Protected:
2228     OS << " protected";
2229     break;
2230   case ObjCIvarDecl::Public:
2231     OS << " public";
2232     break;
2233   case ObjCIvarDecl::Package:
2234     OS << " package";
2235     break;
2236   }
2237 }
2238 
2239 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
2240   if (D->isInstanceMethod())
2241     OS << " -";
2242   else
2243     OS << " +";
2244   dumpName(D);
2245   dumpType(D->getReturnType());
2246 
2247   if (D->isVariadic())
2248     OS << " variadic";
2249 }
2250 
2251 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
2252   dumpName(D);
2253   switch (D->getVariance()) {
2254   case ObjCTypeParamVariance::Invariant:
2255     break;
2256 
2257   case ObjCTypeParamVariance::Covariant:
2258     OS << " covariant";
2259     break;
2260 
2261   case ObjCTypeParamVariance::Contravariant:
2262     OS << " contravariant";
2263     break;
2264   }
2265 
2266   if (D->hasExplicitBound())
2267     OS << " bounded";
2268   dumpType(D->getUnderlyingType());
2269 }
2270 
2271 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
2272   dumpName(D);
2273   dumpDeclRef(D->getClassInterface());
2274   dumpDeclRef(D->getImplementation());
2275   for (const auto *P : D->protocols())
2276     dumpDeclRef(P);
2277 }
2278 
2279 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
2280   dumpName(D);
2281   dumpDeclRef(D->getClassInterface());
2282   dumpDeclRef(D->getCategoryDecl());
2283 }
2284 
2285 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
2286   dumpName(D);
2287 
2288   for (const auto *Child : D->protocols())
2289     dumpDeclRef(Child);
2290 }
2291 
2292 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
2293   dumpName(D);
2294   dumpDeclRef(D->getSuperClass(), "super");
2295 
2296   dumpDeclRef(D->getImplementation());
2297   for (const auto *Child : D->protocols())
2298     dumpDeclRef(Child);
2299 }
2300 
2301 void TextNodeDumper::VisitObjCImplementationDecl(
2302     const ObjCImplementationDecl *D) {
2303   dumpName(D);
2304   dumpDeclRef(D->getSuperClass(), "super");
2305   dumpDeclRef(D->getClassInterface());
2306 }
2307 
2308 void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2309     const ObjCCompatibleAliasDecl *D) {
2310   dumpName(D);
2311   dumpDeclRef(D->getClassInterface());
2312 }
2313 
2314 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
2315   dumpName(D);
2316   dumpType(D->getType());
2317 
2318   if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
2319     OS << " required";
2320   else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
2321     OS << " optional";
2322 
2323   ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
2324   if (Attrs != ObjCPropertyAttribute::kind_noattr) {
2325     if (Attrs & ObjCPropertyAttribute::kind_readonly)
2326       OS << " readonly";
2327     if (Attrs & ObjCPropertyAttribute::kind_assign)
2328       OS << " assign";
2329     if (Attrs & ObjCPropertyAttribute::kind_readwrite)
2330       OS << " readwrite";
2331     if (Attrs & ObjCPropertyAttribute::kind_retain)
2332       OS << " retain";
2333     if (Attrs & ObjCPropertyAttribute::kind_copy)
2334       OS << " copy";
2335     if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
2336       OS << " nonatomic";
2337     if (Attrs & ObjCPropertyAttribute::kind_atomic)
2338       OS << " atomic";
2339     if (Attrs & ObjCPropertyAttribute::kind_weak)
2340       OS << " weak";
2341     if (Attrs & ObjCPropertyAttribute::kind_strong)
2342       OS << " strong";
2343     if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
2344       OS << " unsafe_unretained";
2345     if (Attrs & ObjCPropertyAttribute::kind_class)
2346       OS << " class";
2347     if (Attrs & ObjCPropertyAttribute::kind_direct)
2348       OS << " direct";
2349     if (Attrs & ObjCPropertyAttribute::kind_getter)
2350       dumpDeclRef(D->getGetterMethodDecl(), "getter");
2351     if (Attrs & ObjCPropertyAttribute::kind_setter)
2352       dumpDeclRef(D->getSetterMethodDecl(), "setter");
2353   }
2354 }
2355 
2356 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
2357   dumpName(D->getPropertyDecl());
2358   if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
2359     OS << " synthesize";
2360   else
2361     OS << " dynamic";
2362   dumpDeclRef(D->getPropertyDecl());
2363   dumpDeclRef(D->getPropertyIvarDecl());
2364 }
2365 
2366 void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
2367   if (D->isVariadic())
2368     OS << " variadic";
2369 
2370   if (D->capturesCXXThis())
2371     OS << " captures_this";
2372 }
2373 
2374 void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
2375   dumpName(D);
2376 }
2377 
2378 void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
2379   VisitStmt(S);
2380   if (S->hasStoredFPFeatures())
2381     printFPOptions(S->getStoredFPFeatures());
2382 }
2383