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