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   OS << " template ";
904   TA.getAsTemplate().dump(OS);
905 }
906 
907 void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
908     const TemplateArgument &TA) {
909   OS << " template expansion ";
910   TA.getAsTemplateOrTemplatePattern().dump(OS);
911 }
912 
913 void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
914   OS << " expr";
915 }
916 
917 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
918   OS << " pack";
919 }
920 
921 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
922   if (Node->path_empty())
923     return;
924 
925   OS << " (";
926   bool First = true;
927   for (CastExpr::path_const_iterator I = Node->path_begin(),
928                                      E = Node->path_end();
929        I != E; ++I) {
930     const CXXBaseSpecifier *Base = *I;
931     if (!First)
932       OS << " -> ";
933 
934     const auto *RD =
935         cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
936 
937     if (Base->isVirtual())
938       OS << "virtual ";
939     OS << RD->getName();
940     First = false;
941   }
942 
943   OS << ')';
944 }
945 
946 void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
947   if (Node->hasInitStorage())
948     OS << " has_init";
949   if (Node->hasVarStorage())
950     OS << " has_var";
951   if (Node->hasElseStorage())
952     OS << " has_else";
953   if (Node->isConstexpr())
954     OS << " constexpr";
955   if (Node->isConsteval()) {
956     OS << " ";
957     if (Node->isNegatedConsteval())
958       OS << "!";
959     OS << "consteval";
960   }
961 }
962 
963 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
964   if (Node->hasInitStorage())
965     OS << " has_init";
966   if (Node->hasVarStorage())
967     OS << " has_var";
968 }
969 
970 void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
971   if (Node->hasVarStorage())
972     OS << " has_var";
973 }
974 
975 void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
976   OS << " '" << Node->getName() << "'";
977   if (Node->isSideEntry())
978     OS << " side_entry";
979 }
980 
981 void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
982   OS << " '" << Node->getLabel()->getName() << "'";
983   dumpPointer(Node->getLabel());
984 }
985 
986 void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
987   if (Node->caseStmtIsGNURange())
988     OS << " gnu_range";
989 }
990 
991 void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
992   if (Node->hasAPValueResult())
993     AddChild("value",
994              [=] { Visit(Node->getAPValueResult(), Node->getType()); });
995 }
996 
997 void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
998   if (Node->usesADL())
999     OS << " adl";
1000   if (Node->hasStoredFPFeatures())
1001     printFPOptions(Node->getFPFeatures());
1002 }
1003 
1004 void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) {
1005   const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator());
1006   if (OperatorSpelling)
1007     OS << " '" << OperatorSpelling << "'";
1008 
1009   VisitCallExpr(Node);
1010 }
1011 
1012 void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
1013   OS << " <";
1014   {
1015     ColorScope Color(OS, ShowColors, CastColor);
1016     OS << Node->getCastKindName();
1017   }
1018   dumpBasePath(OS, Node);
1019   OS << ">";
1020   if (Node->hasStoredFPFeatures())
1021     printFPOptions(Node->getFPFeatures());
1022 }
1023 
1024 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
1025   VisitCastExpr(Node);
1026   if (Node->isPartOfExplicitCast())
1027     OS << " part_of_explicit_cast";
1028 }
1029 
1030 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1031   OS << " ";
1032   dumpBareDeclRef(Node->getDecl());
1033   if (Node->getDecl() != Node->getFoundDecl()) {
1034     OS << " (";
1035     dumpBareDeclRef(Node->getFoundDecl());
1036     OS << ")";
1037   }
1038   switch (Node->isNonOdrUse()) {
1039   case NOUR_None: break;
1040   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1041   case NOUR_Constant: OS << " non_odr_use_constant"; break;
1042   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1043   }
1044 }
1045 
1046 void TextNodeDumper::VisitUnresolvedLookupExpr(
1047     const UnresolvedLookupExpr *Node) {
1048   OS << " (";
1049   if (!Node->requiresADL())
1050     OS << "no ";
1051   OS << "ADL) = '" << Node->getName() << '\'';
1052 
1053   UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
1054                                        E = Node->decls_end();
1055   if (I == E)
1056     OS << " empty";
1057   for (; I != E; ++I)
1058     dumpPointer(*I);
1059 }
1060 
1061 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
1062   {
1063     ColorScope Color(OS, ShowColors, DeclKindNameColor);
1064     OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
1065   }
1066   OS << "='" << *Node->getDecl() << "'";
1067   dumpPointer(Node->getDecl());
1068   if (Node->isFreeIvar())
1069     OS << " isFreeIvar";
1070 }
1071 
1072 void TextNodeDumper::VisitSYCLUniqueStableNameExpr(
1073     const SYCLUniqueStableNameExpr *Node) {
1074   dumpType(Node->getTypeSourceInfo()->getType());
1075 }
1076 
1077 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
1078   OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1079 }
1080 
1081 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1082   ColorScope Color(OS, ShowColors, ValueColor);
1083   OS << " " << Node->getValue();
1084 }
1085 
1086 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1087   bool isSigned = Node->getType()->isSignedIntegerType();
1088   ColorScope Color(OS, ShowColors, ValueColor);
1089   OS << " " << toString(Node->getValue(), 10, isSigned);
1090 }
1091 
1092 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
1093   ColorScope Color(OS, ShowColors, ValueColor);
1094   OS << " " << Node->getValueAsString(/*Radix=*/10);
1095 }
1096 
1097 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1098   ColorScope Color(OS, ShowColors, ValueColor);
1099   OS << " " << Node->getValueAsApproximateDouble();
1100 }
1101 
1102 void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
1103   ColorScope Color(OS, ShowColors, ValueColor);
1104   OS << " ";
1105   Str->outputString(OS);
1106 }
1107 
1108 void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
1109   if (auto *Field = ILE->getInitializedFieldInUnion()) {
1110     OS << " field ";
1111     dumpBareDeclRef(Field);
1112   }
1113 }
1114 
1115 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
1116   if (E->isResultDependent())
1117     OS << " result_dependent";
1118 }
1119 
1120 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1121   OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
1122      << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1123   if (!Node->canOverflow())
1124     OS << " cannot overflow";
1125   if (Node->hasStoredFPFeatures())
1126     printFPOptions(Node->getStoredFPFeatures());
1127 }
1128 
1129 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1130     const UnaryExprOrTypeTraitExpr *Node) {
1131   OS << " " << getTraitSpelling(Node->getKind());
1132 
1133   if (Node->isArgumentType())
1134     dumpType(Node->getArgumentType());
1135 }
1136 
1137 void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
1138   OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
1139   dumpPointer(Node->getMemberDecl());
1140   switch (Node->isNonOdrUse()) {
1141   case NOUR_None: break;
1142   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1143   case NOUR_Constant: OS << " non_odr_use_constant"; break;
1144   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1145   }
1146 }
1147 
1148 void TextNodeDumper::VisitExtVectorElementExpr(
1149     const ExtVectorElementExpr *Node) {
1150   OS << " " << Node->getAccessor().getNameStart();
1151 }
1152 
1153 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1154   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1155   if (Node->hasStoredFPFeatures())
1156     printFPOptions(Node->getStoredFPFeatures());
1157 }
1158 
1159 void TextNodeDumper::VisitCompoundAssignOperator(
1160     const CompoundAssignOperator *Node) {
1161   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1162      << "' ComputeLHSTy=";
1163   dumpBareType(Node->getComputationLHSType());
1164   OS << " ComputeResultTy=";
1165   dumpBareType(Node->getComputationResultType());
1166   if (Node->hasStoredFPFeatures())
1167     printFPOptions(Node->getStoredFPFeatures());
1168 }
1169 
1170 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
1171   OS << " " << Node->getLabel()->getName();
1172   dumpPointer(Node->getLabel());
1173 }
1174 
1175 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
1176   OS << " " << Node->getCastName() << "<"
1177      << Node->getTypeAsWritten().getAsString() << ">"
1178      << " <" << Node->getCastKindName();
1179   dumpBasePath(OS, Node);
1180   OS << ">";
1181 }
1182 
1183 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1184   OS << " " << (Node->getValue() ? "true" : "false");
1185 }
1186 
1187 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1188   if (Node->isImplicit())
1189     OS << " implicit";
1190   OS << " this";
1191 }
1192 
1193 void TextNodeDumper::VisitCXXFunctionalCastExpr(
1194     const CXXFunctionalCastExpr *Node) {
1195   OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
1196      << Node->getCastKindName() << ">";
1197   if (Node->hasStoredFPFeatures())
1198     printFPOptions(Node->getFPFeatures());
1199 }
1200 
1201 void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) {
1202   VisitCXXNamedCastExpr(Node);
1203   if (Node->hasStoredFPFeatures())
1204     printFPOptions(Node->getFPFeatures());
1205 }
1206 
1207 void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
1208     const CXXUnresolvedConstructExpr *Node) {
1209   dumpType(Node->getTypeAsWritten());
1210   if (Node->isListInitialization())
1211     OS << " list";
1212 }
1213 
1214 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1215   CXXConstructorDecl *Ctor = Node->getConstructor();
1216   dumpType(Ctor->getType());
1217   if (Node->isElidable())
1218     OS << " elidable";
1219   if (Node->isListInitialization())
1220     OS << " list";
1221   if (Node->isStdInitListInitialization())
1222     OS << " std::initializer_list";
1223   if (Node->requiresZeroInitialization())
1224     OS << " zeroing";
1225 }
1226 
1227 void TextNodeDumper::VisitCXXBindTemporaryExpr(
1228     const CXXBindTemporaryExpr *Node) {
1229   OS << " (CXXTemporary";
1230   dumpPointer(Node);
1231   OS << ")";
1232 }
1233 
1234 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
1235   if (Node->isGlobalNew())
1236     OS << " global";
1237   if (Node->isArray())
1238     OS << " array";
1239   if (Node->getOperatorNew()) {
1240     OS << ' ';
1241     dumpBareDeclRef(Node->getOperatorNew());
1242   }
1243   // We could dump the deallocation function used in case of error, but it's
1244   // usually not that interesting.
1245 }
1246 
1247 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
1248   if (Node->isGlobalDelete())
1249     OS << " global";
1250   if (Node->isArrayForm())
1251     OS << " array";
1252   if (Node->getOperatorDelete()) {
1253     OS << ' ';
1254     dumpBareDeclRef(Node->getOperatorDelete());
1255   }
1256 }
1257 
1258 void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) {
1259   OS << " " << getTraitSpelling(Node->getTrait());
1260 }
1261 
1262 void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) {
1263   OS << " " << getTraitSpelling(Node->getTrait());
1264 }
1265 
1266 void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) {
1267   OS << " " << getTraitSpelling(Node->getTrait());
1268 }
1269 
1270 void TextNodeDumper::VisitMaterializeTemporaryExpr(
1271     const MaterializeTemporaryExpr *Node) {
1272   if (const ValueDecl *VD = Node->getExtendingDecl()) {
1273     OS << " extended by ";
1274     dumpBareDeclRef(VD);
1275   }
1276 }
1277 
1278 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
1279   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
1280     dumpCleanupObject(Node->getObject(i));
1281 }
1282 
1283 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
1284   dumpPointer(Node->getPack());
1285   dumpName(Node->getPack());
1286 }
1287 
1288 void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
1289     const CXXDependentScopeMemberExpr *Node) {
1290   OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
1291 }
1292 
1293 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
1294   OS << " selector=";
1295   Node->getSelector().print(OS);
1296   switch (Node->getReceiverKind()) {
1297   case ObjCMessageExpr::Instance:
1298     break;
1299 
1300   case ObjCMessageExpr::Class:
1301     OS << " class=";
1302     dumpBareType(Node->getClassReceiver());
1303     break;
1304 
1305   case ObjCMessageExpr::SuperInstance:
1306     OS << " super (instance)";
1307     break;
1308 
1309   case ObjCMessageExpr::SuperClass:
1310     OS << " super (class)";
1311     break;
1312   }
1313 }
1314 
1315 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
1316   if (auto *BoxingMethod = Node->getBoxingMethod()) {
1317     OS << " selector=";
1318     BoxingMethod->getSelector().print(OS);
1319   }
1320 }
1321 
1322 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
1323   if (!Node->getCatchParamDecl())
1324     OS << " catch all";
1325 }
1326 
1327 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
1328   dumpType(Node->getEncodedType());
1329 }
1330 
1331 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1332   OS << " ";
1333   Node->getSelector().print(OS);
1334 }
1335 
1336 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
1337   OS << ' ' << *Node->getProtocol();
1338 }
1339 
1340 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
1341   if (Node->isImplicitProperty()) {
1342     OS << " Kind=MethodRef Getter=\"";
1343     if (Node->getImplicitPropertyGetter())
1344       Node->getImplicitPropertyGetter()->getSelector().print(OS);
1345     else
1346       OS << "(null)";
1347 
1348     OS << "\" Setter=\"";
1349     if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
1350       Setter->getSelector().print(OS);
1351     else
1352       OS << "(null)";
1353     OS << "\"";
1354   } else {
1355     OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
1356        << '"';
1357   }
1358 
1359   if (Node->isSuperReceiver())
1360     OS << " super";
1361 
1362   OS << " Messaging=";
1363   if (Node->isMessagingGetter() && Node->isMessagingSetter())
1364     OS << "Getter&Setter";
1365   else if (Node->isMessagingGetter())
1366     OS << "Getter";
1367   else if (Node->isMessagingSetter())
1368     OS << "Setter";
1369 }
1370 
1371 void TextNodeDumper::VisitObjCSubscriptRefExpr(
1372     const ObjCSubscriptRefExpr *Node) {
1373   if (Node->isArraySubscriptRefExpr())
1374     OS << " Kind=ArraySubscript GetterForArray=\"";
1375   else
1376     OS << " Kind=DictionarySubscript GetterForDictionary=\"";
1377   if (Node->getAtIndexMethodDecl())
1378     Node->getAtIndexMethodDecl()->getSelector().print(OS);
1379   else
1380     OS << "(null)";
1381 
1382   if (Node->isArraySubscriptRefExpr())
1383     OS << "\" SetterForArray=\"";
1384   else
1385     OS << "\" SetterForDictionary=\"";
1386   if (Node->setAtIndexMethodDecl())
1387     Node->setAtIndexMethodDecl()->getSelector().print(OS);
1388   else
1389     OS << "(null)";
1390 }
1391 
1392 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
1393   OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
1394 }
1395 
1396 void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) {
1397   OS << " ";
1398   for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1399     Visit(Node->getIteratorDecl(I));
1400     OS << " = ";
1401     const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1402     OS << " begin ";
1403     Visit(Range.Begin);
1404     OS << " end ";
1405     Visit(Range.End);
1406     if (Range.Step) {
1407       OS << " step ";
1408       Visit(Range.Step);
1409     }
1410   }
1411 }
1412 
1413 void TextNodeDumper::VisitConceptSpecializationExpr(
1414     const ConceptSpecializationExpr *Node) {
1415   OS << " ";
1416   dumpBareDeclRef(Node->getFoundDecl());
1417 }
1418 
1419 void TextNodeDumper::VisitRequiresExpr(
1420     const RequiresExpr *Node) {
1421   if (!Node->isValueDependent())
1422     OS << (Node->isSatisfied() ? " satisfied" : " unsatisfied");
1423 }
1424 
1425 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
1426   if (T->isSpelledAsLValue())
1427     OS << " written as lvalue reference";
1428 }
1429 
1430 void TextNodeDumper::VisitArrayType(const ArrayType *T) {
1431   switch (T->getSizeModifier()) {
1432   case ArrayType::Normal:
1433     break;
1434   case ArrayType::Static:
1435     OS << " static";
1436     break;
1437   case ArrayType::Star:
1438     OS << " *";
1439     break;
1440   }
1441   OS << " " << T->getIndexTypeQualifiers().getAsString();
1442 }
1443 
1444 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
1445   OS << " " << T->getSize();
1446   VisitArrayType(T);
1447 }
1448 
1449 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
1450   OS << " ";
1451   dumpSourceRange(T->getBracketsRange());
1452   VisitArrayType(T);
1453 }
1454 
1455 void TextNodeDumper::VisitDependentSizedArrayType(
1456     const DependentSizedArrayType *T) {
1457   VisitArrayType(T);
1458   OS << " ";
1459   dumpSourceRange(T->getBracketsRange());
1460 }
1461 
1462 void TextNodeDumper::VisitDependentSizedExtVectorType(
1463     const DependentSizedExtVectorType *T) {
1464   OS << " ";
1465   dumpLocation(T->getAttributeLoc());
1466 }
1467 
1468 void TextNodeDumper::VisitVectorType(const VectorType *T) {
1469   switch (T->getVectorKind()) {
1470   case VectorType::GenericVector:
1471     break;
1472   case VectorType::AltiVecVector:
1473     OS << " altivec";
1474     break;
1475   case VectorType::AltiVecPixel:
1476     OS << " altivec pixel";
1477     break;
1478   case VectorType::AltiVecBool:
1479     OS << " altivec bool";
1480     break;
1481   case VectorType::NeonVector:
1482     OS << " neon";
1483     break;
1484   case VectorType::NeonPolyVector:
1485     OS << " neon poly";
1486     break;
1487   case VectorType::SveFixedLengthDataVector:
1488     OS << " fixed-length sve data vector";
1489     break;
1490   case VectorType::SveFixedLengthPredicateVector:
1491     OS << " fixed-length sve predicate vector";
1492     break;
1493   }
1494   OS << " " << T->getNumElements();
1495 }
1496 
1497 void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
1498   auto EI = T->getExtInfo();
1499   if (EI.getNoReturn())
1500     OS << " noreturn";
1501   if (EI.getProducesResult())
1502     OS << " produces_result";
1503   if (EI.getHasRegParm())
1504     OS << " regparm " << EI.getRegParm();
1505   OS << " " << FunctionType::getNameForCallConv(EI.getCC());
1506 }
1507 
1508 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
1509   auto EPI = T->getExtProtoInfo();
1510   if (EPI.HasTrailingReturn)
1511     OS << " trailing_return";
1512   if (T->isConst())
1513     OS << " const";
1514   if (T->isVolatile())
1515     OS << " volatile";
1516   if (T->isRestrict())
1517     OS << " restrict";
1518   if (T->getExtProtoInfo().Variadic)
1519     OS << " variadic";
1520   switch (EPI.RefQualifier) {
1521   case RQ_None:
1522     break;
1523   case RQ_LValue:
1524     OS << " &";
1525     break;
1526   case RQ_RValue:
1527     OS << " &&";
1528     break;
1529   }
1530   // FIXME: Exception specification.
1531   // FIXME: Consumed parameters.
1532   VisitFunctionType(T);
1533 }
1534 
1535 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1536   dumpDeclRef(T->getDecl());
1537 }
1538 
1539 void TextNodeDumper::VisitUsingType(const UsingType *T) {
1540   dumpDeclRef(T->getFoundDecl());
1541 }
1542 
1543 void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
1544   dumpDeclRef(T->getDecl());
1545 }
1546 
1547 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
1548   switch (T->getUTTKind()) {
1549   case UnaryTransformType::EnumUnderlyingType:
1550     OS << " underlying_type";
1551     break;
1552   }
1553 }
1554 
1555 void TextNodeDumper::VisitTagType(const TagType *T) {
1556   dumpDeclRef(T->getDecl());
1557 }
1558 
1559 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1560   OS << " depth " << T->getDepth() << " index " << T->getIndex();
1561   if (T->isParameterPack())
1562     OS << " pack";
1563   dumpDeclRef(T->getDecl());
1564 }
1565 
1566 void TextNodeDumper::VisitAutoType(const AutoType *T) {
1567   if (T->isDecltypeAuto())
1568     OS << " decltype(auto)";
1569   if (!T->isDeduced())
1570     OS << " undeduced";
1571   if (T->isConstrained()) {
1572     dumpDeclRef(T->getTypeConstraintConcept());
1573     for (const auto &Arg : T->getTypeConstraintArguments())
1574       VisitTemplateArgument(Arg);
1575   }
1576 }
1577 
1578 void TextNodeDumper::VisitTemplateSpecializationType(
1579     const TemplateSpecializationType *T) {
1580   if (T->isTypeAlias())
1581     OS << " alias";
1582   OS << " ";
1583   T->getTemplateName().dump(OS);
1584 }
1585 
1586 void TextNodeDumper::VisitInjectedClassNameType(
1587     const InjectedClassNameType *T) {
1588   dumpDeclRef(T->getDecl());
1589 }
1590 
1591 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1592   dumpDeclRef(T->getDecl());
1593 }
1594 
1595 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
1596   if (auto N = T->getNumExpansions())
1597     OS << " expansions " << *N;
1598 }
1599 
1600 void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
1601 
1602 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
1603   dumpName(D);
1604   dumpType(D->getUnderlyingType());
1605   if (D->isModulePrivate())
1606     OS << " __module_private__";
1607 }
1608 
1609 void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
1610   if (D->isScoped()) {
1611     if (D->isScopedUsingClassTag())
1612       OS << " class";
1613     else
1614       OS << " struct";
1615   }
1616   dumpName(D);
1617   if (D->isModulePrivate())
1618     OS << " __module_private__";
1619   if (D->isFixed())
1620     dumpType(D->getIntegerType());
1621 }
1622 
1623 void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
1624   OS << ' ' << D->getKindName();
1625   dumpName(D);
1626   if (D->isModulePrivate())
1627     OS << " __module_private__";
1628   if (D->isCompleteDefinition())
1629     OS << " definition";
1630 }
1631 
1632 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
1633   dumpName(D);
1634   dumpType(D->getType());
1635 }
1636 
1637 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
1638   dumpName(D);
1639   dumpType(D->getType());
1640 
1641   for (const auto *Child : D->chain())
1642     dumpDeclRef(Child);
1643 }
1644 
1645 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
1646   dumpName(D);
1647   dumpType(D->getType());
1648 
1649   StorageClass SC = D->getStorageClass();
1650   if (SC != SC_None)
1651     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1652   if (D->isInlineSpecified())
1653     OS << " inline";
1654   if (D->isVirtualAsWritten())
1655     OS << " virtual";
1656   if (D->isModulePrivate())
1657     OS << " __module_private__";
1658 
1659   if (D->isPure())
1660     OS << " pure";
1661   if (D->isDefaulted()) {
1662     OS << " default";
1663     if (D->isDeleted())
1664       OS << "_delete";
1665   }
1666   if (D->isDeletedAsWritten())
1667     OS << " delete";
1668   if (D->isTrivial())
1669     OS << " trivial";
1670 
1671   if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
1672     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
1673     switch (EPI.ExceptionSpec.Type) {
1674     default:
1675       break;
1676     case EST_Unevaluated:
1677       OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
1678       break;
1679     case EST_Uninstantiated:
1680       OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
1681       break;
1682     }
1683   }
1684 
1685   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
1686     if (MD->size_overridden_methods() != 0) {
1687       auto dumpOverride = [=](const CXXMethodDecl *D) {
1688         SplitQualType T_split = D->getType().split();
1689         OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName()
1690            << " '" << QualType::getAsString(T_split, PrintPolicy) << "'";
1691       };
1692 
1693       AddChild([=] {
1694         auto Overrides = MD->overridden_methods();
1695         OS << "Overrides: [ ";
1696         dumpOverride(*Overrides.begin());
1697         for (const auto *Override :
1698              llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
1699           OS << ", ";
1700           dumpOverride(Override);
1701         }
1702         OS << " ]";
1703       });
1704     }
1705   }
1706 
1707   // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
1708   // the Params are set later, it is possible for a dump during debugging to
1709   // encounter a FunctionDecl that has been created but hasn't been assigned
1710   // ParmVarDecls yet.
1711   if (!D->param_empty() && !D->param_begin())
1712     OS << " <<<NULL params x " << D->getNumParams() << ">>>";
1713 }
1714 
1715 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
1716     const LifetimeExtendedTemporaryDecl *D) {
1717   OS << " extended by ";
1718   dumpBareDeclRef(D->getExtendingDecl());
1719   OS << " mangling ";
1720   {
1721     ColorScope Color(OS, ShowColors, ValueColor);
1722     OS << D->getManglingNumber();
1723   }
1724 }
1725 
1726 void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
1727   dumpName(D);
1728   dumpType(D->getType());
1729   if (D->isMutable())
1730     OS << " mutable";
1731   if (D->isModulePrivate())
1732     OS << " __module_private__";
1733 }
1734 
1735 void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
1736   dumpName(D);
1737   dumpType(D->getType());
1738   StorageClass SC = D->getStorageClass();
1739   if (SC != SC_None)
1740     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1741   switch (D->getTLSKind()) {
1742   case VarDecl::TLS_None:
1743     break;
1744   case VarDecl::TLS_Static:
1745     OS << " tls";
1746     break;
1747   case VarDecl::TLS_Dynamic:
1748     OS << " tls_dynamic";
1749     break;
1750   }
1751   if (D->isModulePrivate())
1752     OS << " __module_private__";
1753   if (D->isNRVOVariable())
1754     OS << " nrvo";
1755   if (D->isInline())
1756     OS << " inline";
1757   if (D->isConstexpr())
1758     OS << " constexpr";
1759   if (D->hasInit()) {
1760     switch (D->getInitStyle()) {
1761     case VarDecl::CInit:
1762       OS << " cinit";
1763       break;
1764     case VarDecl::CallInit:
1765       OS << " callinit";
1766       break;
1767     case VarDecl::ListInit:
1768       OS << " listinit";
1769       break;
1770     }
1771   }
1772   if (D->needsDestruction(D->getASTContext()))
1773     OS << " destroyed";
1774   if (D->isParameterPack())
1775     OS << " pack";
1776 
1777   if (D->hasInit()) {
1778     const Expr *E = D->getInit();
1779     // Only dump the value of constexpr VarDecls for now.
1780     if (E && !E->isValueDependent() && D->isConstexpr()) {
1781       const APValue *Value = D->evaluateValue();
1782       if (Value)
1783         AddChild("value", [=] { Visit(*Value, E->getType()); });
1784     }
1785   }
1786 }
1787 
1788 void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
1789   dumpName(D);
1790   dumpType(D->getType());
1791 }
1792 
1793 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
1794   if (D->isNothrow())
1795     OS << " nothrow";
1796 }
1797 
1798 void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
1799   OS << ' ' << D->getImportedModule()->getFullModuleName();
1800 
1801   for (Decl *InitD :
1802        D->getASTContext().getModuleInitializers(D->getImportedModule()))
1803     dumpDeclRef(InitD, "initializer");
1804 }
1805 
1806 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
1807   OS << ' ';
1808   switch (D->getCommentKind()) {
1809   case PCK_Unknown:
1810     llvm_unreachable("unexpected pragma comment kind");
1811   case PCK_Compiler:
1812     OS << "compiler";
1813     break;
1814   case PCK_ExeStr:
1815     OS << "exestr";
1816     break;
1817   case PCK_Lib:
1818     OS << "lib";
1819     break;
1820   case PCK_Linker:
1821     OS << "linker";
1822     break;
1823   case PCK_User:
1824     OS << "user";
1825     break;
1826   }
1827   StringRef Arg = D->getArg();
1828   if (!Arg.empty())
1829     OS << " \"" << Arg << "\"";
1830 }
1831 
1832 void TextNodeDumper::VisitPragmaDetectMismatchDecl(
1833     const PragmaDetectMismatchDecl *D) {
1834   OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
1835 }
1836 
1837 void TextNodeDumper::VisitOMPExecutableDirective(
1838     const OMPExecutableDirective *D) {
1839   if (D->isStandaloneDirective())
1840     OS << " openmp_standalone_directive";
1841 }
1842 
1843 void TextNodeDumper::VisitOMPDeclareReductionDecl(
1844     const OMPDeclareReductionDecl *D) {
1845   dumpName(D);
1846   dumpType(D->getType());
1847   OS << " combiner";
1848   dumpPointer(D->getCombiner());
1849   if (const auto *Initializer = D->getInitializer()) {
1850     OS << " initializer";
1851     dumpPointer(Initializer);
1852     switch (D->getInitializerKind()) {
1853     case OMPDeclareReductionDecl::DirectInit:
1854       OS << " omp_priv = ";
1855       break;
1856     case OMPDeclareReductionDecl::CopyInit:
1857       OS << " omp_priv ()";
1858       break;
1859     case OMPDeclareReductionDecl::CallInit:
1860       break;
1861     }
1862   }
1863 }
1864 
1865 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
1866   for (const auto *C : D->clauselists()) {
1867     AddChild([=] {
1868       if (!C) {
1869         ColorScope Color(OS, ShowColors, NullColor);
1870         OS << "<<<NULL>>> OMPClause";
1871         return;
1872       }
1873       {
1874         ColorScope Color(OS, ShowColors, AttrColor);
1875         StringRef ClauseName(
1876             llvm::omp::getOpenMPClauseName(C->getClauseKind()));
1877         OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
1878            << ClauseName.drop_front() << "Clause";
1879       }
1880       dumpPointer(C);
1881       dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
1882     });
1883   }
1884 }
1885 
1886 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
1887   dumpName(D);
1888   dumpType(D->getType());
1889 }
1890 
1891 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
1892   dumpName(D);
1893   if (D->isInline())
1894     OS << " inline";
1895   if (!D->isOriginalNamespace())
1896     dumpDeclRef(D->getOriginalNamespace(), "original");
1897 }
1898 
1899 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
1900   OS << ' ';
1901   dumpBareDeclRef(D->getNominatedNamespace());
1902 }
1903 
1904 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
1905   dumpName(D);
1906   dumpDeclRef(D->getAliasedNamespace());
1907 }
1908 
1909 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
1910   dumpName(D);
1911   dumpType(D->getUnderlyingType());
1912 }
1913 
1914 void TextNodeDumper::VisitTypeAliasTemplateDecl(
1915     const TypeAliasTemplateDecl *D) {
1916   dumpName(D);
1917 }
1918 
1919 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
1920   VisitRecordDecl(D);
1921   if (!D->isCompleteDefinition())
1922     return;
1923 
1924   AddChild([=] {
1925     {
1926       ColorScope Color(OS, ShowColors, DeclKindNameColor);
1927       OS << "DefinitionData";
1928     }
1929 #define FLAG(fn, name)                                                         \
1930   if (D->fn())                                                                 \
1931     OS << " " #name;
1932     FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
1933 
1934     FLAG(isGenericLambda, generic);
1935     FLAG(isLambda, lambda);
1936 
1937     FLAG(isAnonymousStructOrUnion, is_anonymous);
1938     FLAG(canPassInRegisters, pass_in_registers);
1939     FLAG(isEmpty, empty);
1940     FLAG(isAggregate, aggregate);
1941     FLAG(isStandardLayout, standard_layout);
1942     FLAG(isTriviallyCopyable, trivially_copyable);
1943     FLAG(isPOD, pod);
1944     FLAG(isTrivial, trivial);
1945     FLAG(isPolymorphic, polymorphic);
1946     FLAG(isAbstract, abstract);
1947     FLAG(isLiteral, literal);
1948 
1949     FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
1950     FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
1951     FLAG(hasMutableFields, has_mutable_fields);
1952     FLAG(hasVariantMembers, has_variant_members);
1953     FLAG(allowConstDefaultInit, can_const_default_init);
1954 
1955     AddChild([=] {
1956       {
1957         ColorScope Color(OS, ShowColors, DeclKindNameColor);
1958         OS << "DefaultConstructor";
1959       }
1960       FLAG(hasDefaultConstructor, exists);
1961       FLAG(hasTrivialDefaultConstructor, trivial);
1962       FLAG(hasNonTrivialDefaultConstructor, non_trivial);
1963       FLAG(hasUserProvidedDefaultConstructor, user_provided);
1964       FLAG(hasConstexprDefaultConstructor, constexpr);
1965       FLAG(needsImplicitDefaultConstructor, needs_implicit);
1966       FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
1967     });
1968 
1969     AddChild([=] {
1970       {
1971         ColorScope Color(OS, ShowColors, DeclKindNameColor);
1972         OS << "CopyConstructor";
1973       }
1974       FLAG(hasSimpleCopyConstructor, simple);
1975       FLAG(hasTrivialCopyConstructor, trivial);
1976       FLAG(hasNonTrivialCopyConstructor, non_trivial);
1977       FLAG(hasUserDeclaredCopyConstructor, user_declared);
1978       FLAG(hasCopyConstructorWithConstParam, has_const_param);
1979       FLAG(needsImplicitCopyConstructor, needs_implicit);
1980       FLAG(needsOverloadResolutionForCopyConstructor,
1981            needs_overload_resolution);
1982       if (!D->needsOverloadResolutionForCopyConstructor())
1983         FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
1984       FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
1985     });
1986 
1987     AddChild([=] {
1988       {
1989         ColorScope Color(OS, ShowColors, DeclKindNameColor);
1990         OS << "MoveConstructor";
1991       }
1992       FLAG(hasMoveConstructor, exists);
1993       FLAG(hasSimpleMoveConstructor, simple);
1994       FLAG(hasTrivialMoveConstructor, trivial);
1995       FLAG(hasNonTrivialMoveConstructor, non_trivial);
1996       FLAG(hasUserDeclaredMoveConstructor, user_declared);
1997       FLAG(needsImplicitMoveConstructor, needs_implicit);
1998       FLAG(needsOverloadResolutionForMoveConstructor,
1999            needs_overload_resolution);
2000       if (!D->needsOverloadResolutionForMoveConstructor())
2001         FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
2002     });
2003 
2004     AddChild([=] {
2005       {
2006         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2007         OS << "CopyAssignment";
2008       }
2009       FLAG(hasSimpleCopyAssignment, simple);
2010       FLAG(hasTrivialCopyAssignment, trivial);
2011       FLAG(hasNonTrivialCopyAssignment, non_trivial);
2012       FLAG(hasCopyAssignmentWithConstParam, has_const_param);
2013       FLAG(hasUserDeclaredCopyAssignment, user_declared);
2014       FLAG(needsImplicitCopyAssignment, needs_implicit);
2015       FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
2016       FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
2017     });
2018 
2019     AddChild([=] {
2020       {
2021         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2022         OS << "MoveAssignment";
2023       }
2024       FLAG(hasMoveAssignment, exists);
2025       FLAG(hasSimpleMoveAssignment, simple);
2026       FLAG(hasTrivialMoveAssignment, trivial);
2027       FLAG(hasNonTrivialMoveAssignment, non_trivial);
2028       FLAG(hasUserDeclaredMoveAssignment, user_declared);
2029       FLAG(needsImplicitMoveAssignment, needs_implicit);
2030       FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
2031     });
2032 
2033     AddChild([=] {
2034       {
2035         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2036         OS << "Destructor";
2037       }
2038       FLAG(hasSimpleDestructor, simple);
2039       FLAG(hasIrrelevantDestructor, irrelevant);
2040       FLAG(hasTrivialDestructor, trivial);
2041       FLAG(hasNonTrivialDestructor, non_trivial);
2042       FLAG(hasUserDeclaredDestructor, user_declared);
2043       FLAG(hasConstexprDestructor, constexpr);
2044       FLAG(needsImplicitDestructor, needs_implicit);
2045       FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
2046       if (!D->needsOverloadResolutionForDestructor())
2047         FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
2048     });
2049   });
2050 
2051   for (const auto &I : D->bases()) {
2052     AddChild([=] {
2053       if (I.isVirtual())
2054         OS << "virtual ";
2055       dumpAccessSpecifier(I.getAccessSpecifier());
2056       dumpType(I.getType());
2057       if (I.isPackExpansion())
2058         OS << "...";
2059     });
2060   }
2061 }
2062 
2063 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
2064   dumpName(D);
2065 }
2066 
2067 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
2068   dumpName(D);
2069 }
2070 
2071 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
2072   dumpName(D);
2073 }
2074 
2075 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
2076   dumpName(D);
2077 }
2078 
2079 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2080   if (const auto *TC = D->getTypeConstraint()) {
2081     OS << " ";
2082     dumpBareDeclRef(TC->getNamedConcept());
2083     if (TC->getNamedConcept() != TC->getFoundDecl()) {
2084       OS << " (";
2085       dumpBareDeclRef(TC->getFoundDecl());
2086       OS << ")";
2087     }
2088   } else if (D->wasDeclaredWithTypename())
2089     OS << " typename";
2090   else
2091     OS << " class";
2092   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2093   if (D->isParameterPack())
2094     OS << " ...";
2095   dumpName(D);
2096 }
2097 
2098 void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2099     const NonTypeTemplateParmDecl *D) {
2100   dumpType(D->getType());
2101   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2102   if (D->isParameterPack())
2103     OS << " ...";
2104   dumpName(D);
2105 }
2106 
2107 void TextNodeDumper::VisitTemplateTemplateParmDecl(
2108     const TemplateTemplateParmDecl *D) {
2109   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2110   if (D->isParameterPack())
2111     OS << " ...";
2112   dumpName(D);
2113 }
2114 
2115 void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
2116   OS << ' ';
2117   if (D->getQualifier())
2118     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2119   OS << D->getDeclName();
2120 }
2121 
2122 void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) {
2123   OS << ' ';
2124   dumpBareDeclRef(D->getEnumDecl());
2125 }
2126 
2127 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2128     const UnresolvedUsingTypenameDecl *D) {
2129   OS << ' ';
2130   if (D->getQualifier())
2131     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2132   OS << D->getDeclName();
2133 }
2134 
2135 void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2136     const UnresolvedUsingValueDecl *D) {
2137   OS << ' ';
2138   if (D->getQualifier())
2139     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2140   OS << D->getDeclName();
2141   dumpType(D->getType());
2142 }
2143 
2144 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
2145   OS << ' ';
2146   dumpBareDeclRef(D->getTargetDecl());
2147 }
2148 
2149 void TextNodeDumper::VisitConstructorUsingShadowDecl(
2150     const ConstructorUsingShadowDecl *D) {
2151   if (D->constructsVirtualBase())
2152     OS << " virtual";
2153 
2154   AddChild([=] {
2155     OS << "target ";
2156     dumpBareDeclRef(D->getTargetDecl());
2157   });
2158 
2159   AddChild([=] {
2160     OS << "nominated ";
2161     dumpBareDeclRef(D->getNominatedBaseClass());
2162     OS << ' ';
2163     dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
2164   });
2165 
2166   AddChild([=] {
2167     OS << "constructed ";
2168     dumpBareDeclRef(D->getConstructedBaseClass());
2169     OS << ' ';
2170     dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
2171   });
2172 }
2173 
2174 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
2175   switch (D->getLanguage()) {
2176   case LinkageSpecDecl::lang_c:
2177     OS << " C";
2178     break;
2179   case LinkageSpecDecl::lang_cxx:
2180     OS << " C++";
2181     break;
2182   }
2183 }
2184 
2185 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
2186   OS << ' ';
2187   dumpAccessSpecifier(D->getAccess());
2188 }
2189 
2190 void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
2191   if (TypeSourceInfo *T = D->getFriendType())
2192     dumpType(T->getType());
2193 }
2194 
2195 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
2196   dumpName(D);
2197   dumpType(D->getType());
2198   if (D->getSynthesize())
2199     OS << " synthesize";
2200 
2201   switch (D->getAccessControl()) {
2202   case ObjCIvarDecl::None:
2203     OS << " none";
2204     break;
2205   case ObjCIvarDecl::Private:
2206     OS << " private";
2207     break;
2208   case ObjCIvarDecl::Protected:
2209     OS << " protected";
2210     break;
2211   case ObjCIvarDecl::Public:
2212     OS << " public";
2213     break;
2214   case ObjCIvarDecl::Package:
2215     OS << " package";
2216     break;
2217   }
2218 }
2219 
2220 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
2221   if (D->isInstanceMethod())
2222     OS << " -";
2223   else
2224     OS << " +";
2225   dumpName(D);
2226   dumpType(D->getReturnType());
2227 
2228   if (D->isVariadic())
2229     OS << " variadic";
2230 }
2231 
2232 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
2233   dumpName(D);
2234   switch (D->getVariance()) {
2235   case ObjCTypeParamVariance::Invariant:
2236     break;
2237 
2238   case ObjCTypeParamVariance::Covariant:
2239     OS << " covariant";
2240     break;
2241 
2242   case ObjCTypeParamVariance::Contravariant:
2243     OS << " contravariant";
2244     break;
2245   }
2246 
2247   if (D->hasExplicitBound())
2248     OS << " bounded";
2249   dumpType(D->getUnderlyingType());
2250 }
2251 
2252 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
2253   dumpName(D);
2254   dumpDeclRef(D->getClassInterface());
2255   dumpDeclRef(D->getImplementation());
2256   for (const auto *P : D->protocols())
2257     dumpDeclRef(P);
2258 }
2259 
2260 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
2261   dumpName(D);
2262   dumpDeclRef(D->getClassInterface());
2263   dumpDeclRef(D->getCategoryDecl());
2264 }
2265 
2266 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
2267   dumpName(D);
2268 
2269   for (const auto *Child : D->protocols())
2270     dumpDeclRef(Child);
2271 }
2272 
2273 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
2274   dumpName(D);
2275   dumpDeclRef(D->getSuperClass(), "super");
2276 
2277   dumpDeclRef(D->getImplementation());
2278   for (const auto *Child : D->protocols())
2279     dumpDeclRef(Child);
2280 }
2281 
2282 void TextNodeDumper::VisitObjCImplementationDecl(
2283     const ObjCImplementationDecl *D) {
2284   dumpName(D);
2285   dumpDeclRef(D->getSuperClass(), "super");
2286   dumpDeclRef(D->getClassInterface());
2287 }
2288 
2289 void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2290     const ObjCCompatibleAliasDecl *D) {
2291   dumpName(D);
2292   dumpDeclRef(D->getClassInterface());
2293 }
2294 
2295 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
2296   dumpName(D);
2297   dumpType(D->getType());
2298 
2299   if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
2300     OS << " required";
2301   else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
2302     OS << " optional";
2303 
2304   ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
2305   if (Attrs != ObjCPropertyAttribute::kind_noattr) {
2306     if (Attrs & ObjCPropertyAttribute::kind_readonly)
2307       OS << " readonly";
2308     if (Attrs & ObjCPropertyAttribute::kind_assign)
2309       OS << " assign";
2310     if (Attrs & ObjCPropertyAttribute::kind_readwrite)
2311       OS << " readwrite";
2312     if (Attrs & ObjCPropertyAttribute::kind_retain)
2313       OS << " retain";
2314     if (Attrs & ObjCPropertyAttribute::kind_copy)
2315       OS << " copy";
2316     if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
2317       OS << " nonatomic";
2318     if (Attrs & ObjCPropertyAttribute::kind_atomic)
2319       OS << " atomic";
2320     if (Attrs & ObjCPropertyAttribute::kind_weak)
2321       OS << " weak";
2322     if (Attrs & ObjCPropertyAttribute::kind_strong)
2323       OS << " strong";
2324     if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
2325       OS << " unsafe_unretained";
2326     if (Attrs & ObjCPropertyAttribute::kind_class)
2327       OS << " class";
2328     if (Attrs & ObjCPropertyAttribute::kind_direct)
2329       OS << " direct";
2330     if (Attrs & ObjCPropertyAttribute::kind_getter)
2331       dumpDeclRef(D->getGetterMethodDecl(), "getter");
2332     if (Attrs & ObjCPropertyAttribute::kind_setter)
2333       dumpDeclRef(D->getSetterMethodDecl(), "setter");
2334   }
2335 }
2336 
2337 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
2338   dumpName(D->getPropertyDecl());
2339   if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
2340     OS << " synthesize";
2341   else
2342     OS << " dynamic";
2343   dumpDeclRef(D->getPropertyDecl());
2344   dumpDeclRef(D->getPropertyIvarDecl());
2345 }
2346 
2347 void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
2348   if (D->isVariadic())
2349     OS << " variadic";
2350 
2351   if (D->capturesCXXThis())
2352     OS << " captures_this";
2353 }
2354 
2355 void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
2356   dumpName(D);
2357 }
2358