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