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 (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
1685     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
1686     switch (EPI.ExceptionSpec.Type) {
1687     default:
1688       break;
1689     case EST_Unevaluated:
1690       OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
1691       break;
1692     case EST_Uninstantiated:
1693       OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
1694       break;
1695     }
1696   }
1697 
1698   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
1699     if (MD->size_overridden_methods() != 0) {
1700       auto dumpOverride = [=](const CXXMethodDecl *D) {
1701         SplitQualType T_split = D->getType().split();
1702         OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName()
1703            << " '" << QualType::getAsString(T_split, PrintPolicy) << "'";
1704       };
1705 
1706       AddChild([=] {
1707         auto Overrides = MD->overridden_methods();
1708         OS << "Overrides: [ ";
1709         dumpOverride(*Overrides.begin());
1710         for (const auto *Override :
1711              llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
1712           OS << ", ";
1713           dumpOverride(Override);
1714         }
1715         OS << " ]";
1716       });
1717     }
1718   }
1719 
1720   // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
1721   // the Params are set later, it is possible for a dump during debugging to
1722   // encounter a FunctionDecl that has been created but hasn't been assigned
1723   // ParmVarDecls yet.
1724   if (!D->param_empty() && !D->param_begin())
1725     OS << " <<<NULL params x " << D->getNumParams() << ">>>";
1726 }
1727 
1728 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
1729     const LifetimeExtendedTemporaryDecl *D) {
1730   OS << " extended by ";
1731   dumpBareDeclRef(D->getExtendingDecl());
1732   OS << " mangling ";
1733   {
1734     ColorScope Color(OS, ShowColors, ValueColor);
1735     OS << D->getManglingNumber();
1736   }
1737 }
1738 
1739 void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
1740   dumpName(D);
1741   dumpType(D->getType());
1742   if (D->isMutable())
1743     OS << " mutable";
1744   if (D->isModulePrivate())
1745     OS << " __module_private__";
1746 }
1747 
1748 void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
1749   dumpName(D);
1750   dumpType(D->getType());
1751   StorageClass SC = D->getStorageClass();
1752   if (SC != SC_None)
1753     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1754   switch (D->getTLSKind()) {
1755   case VarDecl::TLS_None:
1756     break;
1757   case VarDecl::TLS_Static:
1758     OS << " tls";
1759     break;
1760   case VarDecl::TLS_Dynamic:
1761     OS << " tls_dynamic";
1762     break;
1763   }
1764   if (D->isModulePrivate())
1765     OS << " __module_private__";
1766   if (D->isNRVOVariable())
1767     OS << " nrvo";
1768   if (D->isInline())
1769     OS << " inline";
1770   if (D->isConstexpr())
1771     OS << " constexpr";
1772   if (D->hasInit()) {
1773     switch (D->getInitStyle()) {
1774     case VarDecl::CInit:
1775       OS << " cinit";
1776       break;
1777     case VarDecl::CallInit:
1778       OS << " callinit";
1779       break;
1780     case VarDecl::ListInit:
1781       OS << " listinit";
1782       break;
1783     }
1784   }
1785   if (D->needsDestruction(D->getASTContext()))
1786     OS << " destroyed";
1787   if (D->isParameterPack())
1788     OS << " pack";
1789 
1790   if (D->hasInit()) {
1791     const Expr *E = D->getInit();
1792     // Only dump the value of constexpr VarDecls for now.
1793     if (E && !E->isValueDependent() && D->isConstexpr()) {
1794       const APValue *Value = D->evaluateValue();
1795       if (Value)
1796         AddChild("value", [=] { Visit(*Value, E->getType()); });
1797     }
1798   }
1799 }
1800 
1801 void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
1802   dumpName(D);
1803   dumpType(D->getType());
1804 }
1805 
1806 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
1807   if (D->isNothrow())
1808     OS << " nothrow";
1809 }
1810 
1811 void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
1812   OS << ' ' << D->getImportedModule()->getFullModuleName();
1813 
1814   for (Decl *InitD :
1815        D->getASTContext().getModuleInitializers(D->getImportedModule()))
1816     dumpDeclRef(InitD, "initializer");
1817 }
1818 
1819 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
1820   OS << ' ';
1821   switch (D->getCommentKind()) {
1822   case PCK_Unknown:
1823     llvm_unreachable("unexpected pragma comment kind");
1824   case PCK_Compiler:
1825     OS << "compiler";
1826     break;
1827   case PCK_ExeStr:
1828     OS << "exestr";
1829     break;
1830   case PCK_Lib:
1831     OS << "lib";
1832     break;
1833   case PCK_Linker:
1834     OS << "linker";
1835     break;
1836   case PCK_User:
1837     OS << "user";
1838     break;
1839   }
1840   StringRef Arg = D->getArg();
1841   if (!Arg.empty())
1842     OS << " \"" << Arg << "\"";
1843 }
1844 
1845 void TextNodeDumper::VisitPragmaDetectMismatchDecl(
1846     const PragmaDetectMismatchDecl *D) {
1847   OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
1848 }
1849 
1850 void TextNodeDumper::VisitOMPExecutableDirective(
1851     const OMPExecutableDirective *D) {
1852   if (D->isStandaloneDirective())
1853     OS << " openmp_standalone_directive";
1854 }
1855 
1856 void TextNodeDumper::VisitOMPDeclareReductionDecl(
1857     const OMPDeclareReductionDecl *D) {
1858   dumpName(D);
1859   dumpType(D->getType());
1860   OS << " combiner";
1861   dumpPointer(D->getCombiner());
1862   if (const auto *Initializer = D->getInitializer()) {
1863     OS << " initializer";
1864     dumpPointer(Initializer);
1865     switch (D->getInitializerKind()) {
1866     case OMPDeclareReductionDecl::DirectInit:
1867       OS << " omp_priv = ";
1868       break;
1869     case OMPDeclareReductionDecl::CopyInit:
1870       OS << " omp_priv ()";
1871       break;
1872     case OMPDeclareReductionDecl::CallInit:
1873       break;
1874     }
1875   }
1876 }
1877 
1878 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
1879   for (const auto *C : D->clauselists()) {
1880     AddChild([=] {
1881       if (!C) {
1882         ColorScope Color(OS, ShowColors, NullColor);
1883         OS << "<<<NULL>>> OMPClause";
1884         return;
1885       }
1886       {
1887         ColorScope Color(OS, ShowColors, AttrColor);
1888         StringRef ClauseName(
1889             llvm::omp::getOpenMPClauseName(C->getClauseKind()));
1890         OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
1891            << ClauseName.drop_front() << "Clause";
1892       }
1893       dumpPointer(C);
1894       dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
1895     });
1896   }
1897 }
1898 
1899 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
1900   dumpName(D);
1901   dumpType(D->getType());
1902 }
1903 
1904 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
1905   dumpName(D);
1906   if (D->isInline())
1907     OS << " inline";
1908   if (!D->isOriginalNamespace())
1909     dumpDeclRef(D->getOriginalNamespace(), "original");
1910 }
1911 
1912 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
1913   OS << ' ';
1914   dumpBareDeclRef(D->getNominatedNamespace());
1915 }
1916 
1917 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
1918   dumpName(D);
1919   dumpDeclRef(D->getAliasedNamespace());
1920 }
1921 
1922 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
1923   dumpName(D);
1924   dumpType(D->getUnderlyingType());
1925 }
1926 
1927 void TextNodeDumper::VisitTypeAliasTemplateDecl(
1928     const TypeAliasTemplateDecl *D) {
1929   dumpName(D);
1930 }
1931 
1932 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
1933   VisitRecordDecl(D);
1934   if (!D->isCompleteDefinition())
1935     return;
1936 
1937   AddChild([=] {
1938     {
1939       ColorScope Color(OS, ShowColors, DeclKindNameColor);
1940       OS << "DefinitionData";
1941     }
1942 #define FLAG(fn, name)                                                         \
1943   if (D->fn())                                                                 \
1944     OS << " " #name;
1945     FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
1946 
1947     FLAG(isGenericLambda, generic);
1948     FLAG(isLambda, lambda);
1949 
1950     FLAG(isAnonymousStructOrUnion, is_anonymous);
1951     FLAG(canPassInRegisters, pass_in_registers);
1952     FLAG(isEmpty, empty);
1953     FLAG(isAggregate, aggregate);
1954     FLAG(isStandardLayout, standard_layout);
1955     FLAG(isTriviallyCopyable, trivially_copyable);
1956     FLAG(isPOD, pod);
1957     FLAG(isTrivial, trivial);
1958     FLAG(isPolymorphic, polymorphic);
1959     FLAG(isAbstract, abstract);
1960     FLAG(isLiteral, literal);
1961 
1962     FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
1963     FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
1964     FLAG(hasMutableFields, has_mutable_fields);
1965     FLAG(hasVariantMembers, has_variant_members);
1966     FLAG(allowConstDefaultInit, can_const_default_init);
1967 
1968     AddChild([=] {
1969       {
1970         ColorScope Color(OS, ShowColors, DeclKindNameColor);
1971         OS << "DefaultConstructor";
1972       }
1973       FLAG(hasDefaultConstructor, exists);
1974       FLAG(hasTrivialDefaultConstructor, trivial);
1975       FLAG(hasNonTrivialDefaultConstructor, non_trivial);
1976       FLAG(hasUserProvidedDefaultConstructor, user_provided);
1977       FLAG(hasConstexprDefaultConstructor, constexpr);
1978       FLAG(needsImplicitDefaultConstructor, needs_implicit);
1979       FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
1980     });
1981 
1982     AddChild([=] {
1983       {
1984         ColorScope Color(OS, ShowColors, DeclKindNameColor);
1985         OS << "CopyConstructor";
1986       }
1987       FLAG(hasSimpleCopyConstructor, simple);
1988       FLAG(hasTrivialCopyConstructor, trivial);
1989       FLAG(hasNonTrivialCopyConstructor, non_trivial);
1990       FLAG(hasUserDeclaredCopyConstructor, user_declared);
1991       FLAG(hasCopyConstructorWithConstParam, has_const_param);
1992       FLAG(needsImplicitCopyConstructor, needs_implicit);
1993       FLAG(needsOverloadResolutionForCopyConstructor,
1994            needs_overload_resolution);
1995       if (!D->needsOverloadResolutionForCopyConstructor())
1996         FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
1997       FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
1998     });
1999 
2000     AddChild([=] {
2001       {
2002         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2003         OS << "MoveConstructor";
2004       }
2005       FLAG(hasMoveConstructor, exists);
2006       FLAG(hasSimpleMoveConstructor, simple);
2007       FLAG(hasTrivialMoveConstructor, trivial);
2008       FLAG(hasNonTrivialMoveConstructor, non_trivial);
2009       FLAG(hasUserDeclaredMoveConstructor, user_declared);
2010       FLAG(needsImplicitMoveConstructor, needs_implicit);
2011       FLAG(needsOverloadResolutionForMoveConstructor,
2012            needs_overload_resolution);
2013       if (!D->needsOverloadResolutionForMoveConstructor())
2014         FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
2015     });
2016 
2017     AddChild([=] {
2018       {
2019         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2020         OS << "CopyAssignment";
2021       }
2022       FLAG(hasSimpleCopyAssignment, simple);
2023       FLAG(hasTrivialCopyAssignment, trivial);
2024       FLAG(hasNonTrivialCopyAssignment, non_trivial);
2025       FLAG(hasCopyAssignmentWithConstParam, has_const_param);
2026       FLAG(hasUserDeclaredCopyAssignment, user_declared);
2027       FLAG(needsImplicitCopyAssignment, needs_implicit);
2028       FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
2029       FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
2030     });
2031 
2032     AddChild([=] {
2033       {
2034         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2035         OS << "MoveAssignment";
2036       }
2037       FLAG(hasMoveAssignment, exists);
2038       FLAG(hasSimpleMoveAssignment, simple);
2039       FLAG(hasTrivialMoveAssignment, trivial);
2040       FLAG(hasNonTrivialMoveAssignment, non_trivial);
2041       FLAG(hasUserDeclaredMoveAssignment, user_declared);
2042       FLAG(needsImplicitMoveAssignment, needs_implicit);
2043       FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
2044     });
2045 
2046     AddChild([=] {
2047       {
2048         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2049         OS << "Destructor";
2050       }
2051       FLAG(hasSimpleDestructor, simple);
2052       FLAG(hasIrrelevantDestructor, irrelevant);
2053       FLAG(hasTrivialDestructor, trivial);
2054       FLAG(hasNonTrivialDestructor, non_trivial);
2055       FLAG(hasUserDeclaredDestructor, user_declared);
2056       FLAG(hasConstexprDestructor, constexpr);
2057       FLAG(needsImplicitDestructor, needs_implicit);
2058       FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
2059       if (!D->needsOverloadResolutionForDestructor())
2060         FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
2061     });
2062   });
2063 
2064   for (const auto &I : D->bases()) {
2065     AddChild([=] {
2066       if (I.isVirtual())
2067         OS << "virtual ";
2068       dumpAccessSpecifier(I.getAccessSpecifier());
2069       dumpType(I.getType());
2070       if (I.isPackExpansion())
2071         OS << "...";
2072     });
2073   }
2074 }
2075 
2076 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
2077   dumpName(D);
2078 }
2079 
2080 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
2081   dumpName(D);
2082 }
2083 
2084 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
2085   dumpName(D);
2086 }
2087 
2088 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
2089   dumpName(D);
2090 }
2091 
2092 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2093   if (const auto *TC = D->getTypeConstraint()) {
2094     OS << " ";
2095     dumpBareDeclRef(TC->getNamedConcept());
2096     if (TC->getNamedConcept() != TC->getFoundDecl()) {
2097       OS << " (";
2098       dumpBareDeclRef(TC->getFoundDecl());
2099       OS << ")";
2100     }
2101   } else if (D->wasDeclaredWithTypename())
2102     OS << " typename";
2103   else
2104     OS << " class";
2105   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2106   if (D->isParameterPack())
2107     OS << " ...";
2108   dumpName(D);
2109 }
2110 
2111 void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2112     const NonTypeTemplateParmDecl *D) {
2113   dumpType(D->getType());
2114   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2115   if (D->isParameterPack())
2116     OS << " ...";
2117   dumpName(D);
2118 }
2119 
2120 void TextNodeDumper::VisitTemplateTemplateParmDecl(
2121     const TemplateTemplateParmDecl *D) {
2122   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2123   if (D->isParameterPack())
2124     OS << " ...";
2125   dumpName(D);
2126 }
2127 
2128 void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
2129   OS << ' ';
2130   if (D->getQualifier())
2131     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2132   OS << D->getDeclName();
2133 }
2134 
2135 void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) {
2136   OS << ' ';
2137   dumpBareDeclRef(D->getEnumDecl());
2138 }
2139 
2140 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2141     const UnresolvedUsingTypenameDecl *D) {
2142   OS << ' ';
2143   if (D->getQualifier())
2144     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2145   OS << D->getDeclName();
2146 }
2147 
2148 void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2149     const UnresolvedUsingValueDecl *D) {
2150   OS << ' ';
2151   if (D->getQualifier())
2152     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2153   OS << D->getDeclName();
2154   dumpType(D->getType());
2155 }
2156 
2157 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
2158   OS << ' ';
2159   dumpBareDeclRef(D->getTargetDecl());
2160 }
2161 
2162 void TextNodeDumper::VisitConstructorUsingShadowDecl(
2163     const ConstructorUsingShadowDecl *D) {
2164   if (D->constructsVirtualBase())
2165     OS << " virtual";
2166 
2167   AddChild([=] {
2168     OS << "target ";
2169     dumpBareDeclRef(D->getTargetDecl());
2170   });
2171 
2172   AddChild([=] {
2173     OS << "nominated ";
2174     dumpBareDeclRef(D->getNominatedBaseClass());
2175     OS << ' ';
2176     dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
2177   });
2178 
2179   AddChild([=] {
2180     OS << "constructed ";
2181     dumpBareDeclRef(D->getConstructedBaseClass());
2182     OS << ' ';
2183     dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
2184   });
2185 }
2186 
2187 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
2188   switch (D->getLanguage()) {
2189   case LinkageSpecDecl::lang_c:
2190     OS << " C";
2191     break;
2192   case LinkageSpecDecl::lang_cxx:
2193     OS << " C++";
2194     break;
2195   }
2196 }
2197 
2198 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
2199   OS << ' ';
2200   dumpAccessSpecifier(D->getAccess());
2201 }
2202 
2203 void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
2204   if (TypeSourceInfo *T = D->getFriendType())
2205     dumpType(T->getType());
2206 }
2207 
2208 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
2209   dumpName(D);
2210   dumpType(D->getType());
2211   if (D->getSynthesize())
2212     OS << " synthesize";
2213 
2214   switch (D->getAccessControl()) {
2215   case ObjCIvarDecl::None:
2216     OS << " none";
2217     break;
2218   case ObjCIvarDecl::Private:
2219     OS << " private";
2220     break;
2221   case ObjCIvarDecl::Protected:
2222     OS << " protected";
2223     break;
2224   case ObjCIvarDecl::Public:
2225     OS << " public";
2226     break;
2227   case ObjCIvarDecl::Package:
2228     OS << " package";
2229     break;
2230   }
2231 }
2232 
2233 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
2234   if (D->isInstanceMethod())
2235     OS << " -";
2236   else
2237     OS << " +";
2238   dumpName(D);
2239   dumpType(D->getReturnType());
2240 
2241   if (D->isVariadic())
2242     OS << " variadic";
2243 }
2244 
2245 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
2246   dumpName(D);
2247   switch (D->getVariance()) {
2248   case ObjCTypeParamVariance::Invariant:
2249     break;
2250 
2251   case ObjCTypeParamVariance::Covariant:
2252     OS << " covariant";
2253     break;
2254 
2255   case ObjCTypeParamVariance::Contravariant:
2256     OS << " contravariant";
2257     break;
2258   }
2259 
2260   if (D->hasExplicitBound())
2261     OS << " bounded";
2262   dumpType(D->getUnderlyingType());
2263 }
2264 
2265 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
2266   dumpName(D);
2267   dumpDeclRef(D->getClassInterface());
2268   dumpDeclRef(D->getImplementation());
2269   for (const auto *P : D->protocols())
2270     dumpDeclRef(P);
2271 }
2272 
2273 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
2274   dumpName(D);
2275   dumpDeclRef(D->getClassInterface());
2276   dumpDeclRef(D->getCategoryDecl());
2277 }
2278 
2279 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
2280   dumpName(D);
2281 
2282   for (const auto *Child : D->protocols())
2283     dumpDeclRef(Child);
2284 }
2285 
2286 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
2287   dumpName(D);
2288   dumpDeclRef(D->getSuperClass(), "super");
2289 
2290   dumpDeclRef(D->getImplementation());
2291   for (const auto *Child : D->protocols())
2292     dumpDeclRef(Child);
2293 }
2294 
2295 void TextNodeDumper::VisitObjCImplementationDecl(
2296     const ObjCImplementationDecl *D) {
2297   dumpName(D);
2298   dumpDeclRef(D->getSuperClass(), "super");
2299   dumpDeclRef(D->getClassInterface());
2300 }
2301 
2302 void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2303     const ObjCCompatibleAliasDecl *D) {
2304   dumpName(D);
2305   dumpDeclRef(D->getClassInterface());
2306 }
2307 
2308 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
2309   dumpName(D);
2310   dumpType(D->getType());
2311 
2312   if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
2313     OS << " required";
2314   else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
2315     OS << " optional";
2316 
2317   ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
2318   if (Attrs != ObjCPropertyAttribute::kind_noattr) {
2319     if (Attrs & ObjCPropertyAttribute::kind_readonly)
2320       OS << " readonly";
2321     if (Attrs & ObjCPropertyAttribute::kind_assign)
2322       OS << " assign";
2323     if (Attrs & ObjCPropertyAttribute::kind_readwrite)
2324       OS << " readwrite";
2325     if (Attrs & ObjCPropertyAttribute::kind_retain)
2326       OS << " retain";
2327     if (Attrs & ObjCPropertyAttribute::kind_copy)
2328       OS << " copy";
2329     if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
2330       OS << " nonatomic";
2331     if (Attrs & ObjCPropertyAttribute::kind_atomic)
2332       OS << " atomic";
2333     if (Attrs & ObjCPropertyAttribute::kind_weak)
2334       OS << " weak";
2335     if (Attrs & ObjCPropertyAttribute::kind_strong)
2336       OS << " strong";
2337     if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
2338       OS << " unsafe_unretained";
2339     if (Attrs & ObjCPropertyAttribute::kind_class)
2340       OS << " class";
2341     if (Attrs & ObjCPropertyAttribute::kind_direct)
2342       OS << " direct";
2343     if (Attrs & ObjCPropertyAttribute::kind_getter)
2344       dumpDeclRef(D->getGetterMethodDecl(), "getter");
2345     if (Attrs & ObjCPropertyAttribute::kind_setter)
2346       dumpDeclRef(D->getSetterMethodDecl(), "setter");
2347   }
2348 }
2349 
2350 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
2351   dumpName(D->getPropertyDecl());
2352   if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
2353     OS << " synthesize";
2354   else
2355     OS << " dynamic";
2356   dumpDeclRef(D->getPropertyDecl());
2357   dumpDeclRef(D->getPropertyIvarDecl());
2358 }
2359 
2360 void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
2361   if (D->isVariadic())
2362     OS << " variadic";
2363 
2364   if (D->capturesCXXThis())
2365     OS << " captures_this";
2366 }
2367 
2368 void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
2369   dumpName(D);
2370 }
2371