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