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