1 //===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements AST dumping of components of individual AST nodes.
11 //===----------------------------------------------------------------------===//
13 #include "clang/AST/TextNodeDumper.h"
14 #include "clang/AST/APValue.h"
15 #include "clang/AST/DeclFriend.h"
16 #include "clang/AST/DeclOpenMP.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/LocInfoType.h"
19 #include "clang/AST/NestedNameSpecifier.h"
20 #include "clang/AST/Type.h"
21 #include "clang/Basic/Module.h"
22 #include "clang/Basic/SourceManager.h"
23 #include "clang/Basic/Specifiers.h"
24 #include "clang/Basic/TypeTraits.h"
25 #include "llvm/ADT/StringExtras.h"
30 using namespace clang
;
32 static void dumpPreviousDeclImpl(raw_ostream
&OS
, ...) {}
35 static void dumpPreviousDeclImpl(raw_ostream
&OS
, const Mergeable
<T
> *D
) {
36 const T
*First
= D
->getFirstDecl();
38 OS
<< " first " << First
;
42 static void dumpPreviousDeclImpl(raw_ostream
&OS
, const Redeclarable
<T
> *D
) {
43 const T
*Prev
= D
->getPreviousDecl();
45 OS
<< " prev " << Prev
;
48 /// Dump the previous declaration in the redeclaration chain for a declaration,
50 static void dumpPreviousDecl(raw_ostream
&OS
, const Decl
*D
) {
51 switch (D
->getKind()) {
52 #define DECL(DERIVED, BASE) \
54 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
55 #define ABSTRACT_DECL(DECL)
56 #include "clang/AST/DeclNodes.inc"
58 llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
61 TextNodeDumper::TextNodeDumper(raw_ostream
&OS
, const ASTContext
&Context
,
63 : TextTreeStructure(OS
, ShowColors
), OS(OS
), ShowColors(ShowColors
),
64 Context(&Context
), SM(&Context
.getSourceManager()),
65 PrintPolicy(Context
.getPrintingPolicy()),
66 Traits(&Context
.getCommentCommandTraits()) {}
68 TextNodeDumper::TextNodeDumper(raw_ostream
&OS
, bool ShowColors
)
69 : TextTreeStructure(OS
, ShowColors
), OS(OS
), ShowColors(ShowColors
) {}
71 void TextNodeDumper::Visit(const comments::Comment
*C
,
72 const comments::FullComment
*FC
) {
74 ColorScope
Color(OS
, ShowColors
, NullColor
);
80 ColorScope
Color(OS
, ShowColors
, CommentColor
);
81 OS
<< C
->getCommentKindName();
84 dumpSourceRange(C
->getSourceRange());
86 ConstCommentVisitor
<TextNodeDumper
, void,
87 const comments::FullComment
*>::visit(C
, FC
);
90 void TextNodeDumper::Visit(const Attr
*A
) {
92 ColorScope
Color(OS
, ShowColors
, AttrColor
);
94 switch (A
->getKind()) {
99 #include "clang/Basic/AttrList.inc"
104 dumpSourceRange(A
->getRange());
105 if (A
->isInherited())
110 ConstAttrVisitor
<TextNodeDumper
>::Visit(A
);
113 void TextNodeDumper::Visit(const TemplateArgument
&TA
, SourceRange R
,
114 const Decl
*From
, StringRef Label
) {
115 OS
<< "TemplateArgument";
120 dumpDeclRef(From
, Label
);
122 ConstTemplateArgumentVisitor
<TextNodeDumper
>::Visit(TA
);
125 void TextNodeDumper::Visit(const Stmt
*Node
) {
127 ColorScope
Color(OS
, ShowColors
, NullColor
);
132 ColorScope
Color(OS
, ShowColors
, StmtColor
);
133 OS
<< Node
->getStmtClassName();
136 dumpSourceRange(Node
->getSourceRange());
138 if (const auto *E
= dyn_cast
<Expr
>(Node
)) {
139 dumpType(E
->getType());
141 if (E
->containsErrors()) {
142 ColorScope
Color(OS
, ShowColors
, ErrorsColor
);
143 OS
<< " contains-errors";
147 ColorScope
Color(OS
, ShowColors
, ValueKindColor
);
148 switch (E
->getValueKind()) {
161 ColorScope
Color(OS
, ShowColors
, ObjectKindColor
);
162 switch (E
->getObjectKind()) {
168 case OK_ObjCProperty
:
169 OS
<< " objcproperty";
171 case OK_ObjCSubscript
:
172 OS
<< " objcsubscript";
174 case OK_VectorComponent
:
175 OS
<< " vectorcomponent";
177 case OK_MatrixComponent
:
178 OS
<< " matrixcomponent";
184 ConstStmtVisitor
<TextNodeDumper
>::Visit(Node
);
187 void TextNodeDumper::Visit(const Type
*T
) {
189 ColorScope
Color(OS
, ShowColors
, NullColor
);
193 if (isa
<LocInfoType
>(T
)) {
195 ColorScope
Color(OS
, ShowColors
, TypeColor
);
196 OS
<< "LocInfo Type";
203 ColorScope
Color(OS
, ShowColors
, TypeColor
);
204 OS
<< T
->getTypeClassName() << "Type";
208 dumpBareType(QualType(T
, 0), false);
210 QualType SingleStepDesugar
=
211 T
->getLocallyUnqualifiedSingleStepDesugaredType();
212 if (SingleStepDesugar
!= QualType(T
, 0))
215 if (T
->containsErrors()) {
216 ColorScope
Color(OS
, ShowColors
, ErrorsColor
);
217 OS
<< " contains-errors";
220 if (T
->isDependentType())
222 else if (T
->isInstantiationDependentType())
223 OS
<< " instantiation_dependent";
225 if (T
->isVariablyModifiedType())
226 OS
<< " variably_modified";
227 if (T
->containsUnexpandedParameterPack())
228 OS
<< " contains_unexpanded_pack";
232 TypeVisitor
<TextNodeDumper
>::Visit(T
);
235 void TextNodeDumper::Visit(QualType T
) {
237 dumpPointer(T
.getAsOpaquePtr());
239 dumpBareType(T
, false);
240 OS
<< " " << T
.split().Quals
.getAsString();
243 void TextNodeDumper::Visit(const Decl
*D
) {
245 ColorScope
Color(OS
, ShowColors
, NullColor
);
251 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
252 OS
<< D
->getDeclKindName() << "Decl";
255 if (D
->getLexicalDeclContext() != D
->getDeclContext())
256 OS
<< " parent " << cast
<Decl
>(D
->getDeclContext());
257 dumpPreviousDecl(OS
, D
);
258 dumpSourceRange(D
->getSourceRange());
260 dumpLocation(D
->getLocation());
261 if (D
->isFromASTFile())
263 if (Module
*M
= D
->getOwningModule())
264 OS
<< " in " << M
->getFullModuleName();
265 if (auto *ND
= dyn_cast
<NamedDecl
>(D
))
266 for (Module
*M
: D
->getASTContext().getModulesWithMergedDefinition(
267 const_cast<NamedDecl
*>(ND
)))
268 AddChild([=] { OS
<< "also in " << M
->getFullModuleName(); });
269 if (const NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
))
270 if (!ND
->isUnconditionallyVisible())
277 else if (D
->isThisDeclarationReferenced())
280 if (D
->isInvalidDecl())
282 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
283 if (FD
->isConstexprSpecified())
285 if (FD
->isConsteval())
287 else if (FD
->isImmediateFunction())
289 if (FD
->isMultiVersion())
290 OS
<< " multiversion";
293 if (!isa
<FunctionDecl
>(*D
)) {
294 const auto *MD
= dyn_cast
<ObjCMethodDecl
>(D
);
295 if (!MD
|| !MD
->isThisDeclarationADefinition()) {
296 const auto *DC
= dyn_cast
<DeclContext
>(D
);
297 if (DC
&& DC
->hasExternalLexicalStorage()) {
298 ColorScope
Color(OS
, ShowColors
, UndeserializedColor
);
299 OS
<< " <undeserialized declarations>";
304 switch (D
->getFriendObjectKind()) {
307 case Decl::FOK_Declared
:
310 case Decl::FOK_Undeclared
:
311 OS
<< " friend_undeclared";
315 ConstDeclVisitor
<TextNodeDumper
>::Visit(D
);
318 void TextNodeDumper::Visit(const CXXCtorInitializer
*Init
) {
319 OS
<< "CXXCtorInitializer";
320 if (Init
->isAnyMemberInitializer()) {
322 dumpBareDeclRef(Init
->getAnyMember());
323 } else if (Init
->isBaseInitializer()) {
324 dumpType(QualType(Init
->getBaseClass(), 0));
325 } else if (Init
->isDelegatingInitializer()) {
326 dumpType(Init
->getTypeSourceInfo()->getType());
328 llvm_unreachable("Unknown initializer type");
332 void TextNodeDumper::Visit(const BlockDecl::Capture
&C
) {
338 if (C
.getVariable()) {
340 dumpBareDeclRef(C
.getVariable());
344 void TextNodeDumper::Visit(const OMPClause
*C
) {
346 ColorScope
Color(OS
, ShowColors
, NullColor
);
347 OS
<< "<<<NULL>>> OMPClause";
351 ColorScope
Color(OS
, ShowColors
, AttrColor
);
352 StringRef
ClauseName(llvm::omp::getOpenMPClauseName(C
->getClauseKind()));
353 OS
<< "OMP" << ClauseName
.substr(/*Start=*/0, /*N=*/1).upper()
354 << ClauseName
.drop_front() << "Clause";
357 dumpSourceRange(SourceRange(C
->getBeginLoc(), C
->getEndLoc()));
362 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation
&A
) {
363 const TypeSourceInfo
*TSI
= A
.getTypeSourceInfo();
366 dumpType(TSI
->getType());
375 void TextNodeDumper::Visit(const ConceptReference
*R
) {
377 ColorScope
Color(OS
, ShowColors
, NullColor
);
378 OS
<< "<<<NULL>>> ConceptReference";
382 OS
<< "ConceptReference";
384 dumpSourceRange(R
->getSourceRange());
386 dumpBareDeclRef(R
->getNamedConcept());
389 void TextNodeDumper::Visit(const concepts::Requirement
*R
) {
391 ColorScope
Color(OS
, ShowColors
, NullColor
);
392 OS
<< "<<<NULL>>> Requirement";
397 ColorScope
Color(OS
, ShowColors
, StmtColor
);
398 switch (R
->getKind()) {
399 case concepts::Requirement::RK_Type
:
400 OS
<< "TypeRequirement";
402 case concepts::Requirement::RK_Simple
:
403 OS
<< "SimpleRequirement";
405 case concepts::Requirement::RK_Compound
:
406 OS
<< "CompoundRequirement";
408 case concepts::Requirement::RK_Nested
:
409 OS
<< "NestedRequirement";
416 if (auto *ER
= dyn_cast
<concepts::ExprRequirement
>(R
)) {
417 if (ER
->hasNoexceptRequirement())
421 if (R
->isDependent())
424 OS
<< (R
->isSatisfied() ? " satisfied" : " unsatisfied");
425 if (R
->containsUnexpandedParameterPack())
426 OS
<< " contains_unexpanded_pack";
429 static double GetApproxValue(const llvm::APFloat
&F
) {
432 V
.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven
,
434 return V
.convertToDouble();
437 /// True if the \p APValue \p Value can be folded onto the current line.
438 static bool isSimpleAPValue(const APValue
&Value
) {
439 switch (Value
.getKind()) {
441 case APValue::Indeterminate
:
444 case APValue::FixedPoint
:
445 case APValue::ComplexInt
:
446 case APValue::ComplexFloat
:
447 case APValue::LValue
:
448 case APValue::MemberPointer
:
449 case APValue::AddrLabelDiff
:
451 case APValue::Vector
:
453 case APValue::Struct
:
456 return isSimpleAPValue(Value
.getUnionValue());
458 llvm_unreachable("unexpected APValue kind!");
461 /// Dump the children of the \p APValue \p Value.
463 /// \param[in] Value The \p APValue to visit
464 /// \param[in] Ty The \p QualType passed to \p Visit
466 /// \param[in] IdxToChildFun A function mapping an \p APValue and an index
467 /// to one of the child of the \p APValue
469 /// \param[in] NumChildren \p IdxToChildFun will be called on \p Value with
470 /// the indices in the range \p [0,NumChildren(
472 /// \param[in] LabelSingular The label to use on a line with a single child
473 /// \param[in] LabelPlurial The label to use on a line with multiple children
474 void TextNodeDumper::dumpAPValueChildren(
475 const APValue
&Value
, QualType Ty
,
476 const APValue
&(*IdxToChildFun
)(const APValue
&, unsigned),
477 unsigned NumChildren
, StringRef LabelSingular
, StringRef LabelPlurial
) {
478 // To save some vertical space we print up to MaxChildrenPerLine APValues
479 // considered to be simple (by isSimpleAPValue) on a single line.
480 constexpr unsigned MaxChildrenPerLine
= 4;
482 while (I
< NumChildren
) {
484 while (J
< NumChildren
) {
485 if (isSimpleAPValue(IdxToChildFun(Value
, J
)) &&
486 (J
- I
< MaxChildrenPerLine
)) {
493 J
= std::max(I
+ 1, J
);
495 // Print [I,J) on a single line.
496 AddChild(J
- I
> 1 ? LabelPlurial
: LabelSingular
, [=]() {
497 for (unsigned X
= I
; X
< J
; ++X
) {
498 Visit(IdxToChildFun(Value
, X
), Ty
);
507 void TextNodeDumper::Visit(const APValue
&Value
, QualType Ty
) {
508 ColorScope
Color(OS
, ShowColors
, ValueKindColor
);
509 switch (Value
.getKind()) {
513 case APValue::Indeterminate
:
514 OS
<< "Indeterminate";
519 ColorScope
Color(OS
, ShowColors
, ValueColor
);
520 OS
<< Value
.getInt();
526 ColorScope
Color(OS
, ShowColors
, ValueColor
);
527 OS
<< GetApproxValue(Value
.getFloat());
530 case APValue::FixedPoint
:
533 ColorScope
Color(OS
, ShowColors
, ValueColor
);
534 OS
<< Value
.getFixedPoint();
537 case APValue::Vector
: {
538 unsigned VectorLength
= Value
.getVectorLength();
539 OS
<< "Vector length=" << VectorLength
;
543 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
544 return Value
.getVectorElt(Index
);
546 VectorLength
, "element", "elements");
549 case APValue::ComplexInt
:
552 ColorScope
Color(OS
, ShowColors
, ValueColor
);
553 OS
<< Value
.getComplexIntReal() << " + " << Value
.getComplexIntImag()
557 case APValue::ComplexFloat
:
558 OS
<< "ComplexFloat ";
560 ColorScope
Color(OS
, ShowColors
, ValueColor
);
561 OS
<< GetApproxValue(Value
.getComplexFloatReal()) << " + "
562 << GetApproxValue(Value
.getComplexFloatImag()) << 'i';
565 case APValue::LValue
:
567 OS
<< "LValue <todo>";
569 case APValue::Array
: {
570 unsigned ArraySize
= Value
.getArraySize();
571 unsigned NumInitializedElements
= Value
.getArrayInitializedElts();
572 OS
<< "Array size=" << ArraySize
;
576 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
577 return Value
.getArrayInitializedElt(Index
);
579 NumInitializedElements
, "element", "elements");
581 if (Value
.hasArrayFiller()) {
582 AddChild("filler", [=] {
584 ColorScope
Color(OS
, ShowColors
, ValueColor
);
585 OS
<< ArraySize
- NumInitializedElements
<< " x ";
587 Visit(Value
.getArrayFiller(), Ty
);
593 case APValue::Struct
: {
598 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
599 return Value
.getStructBase(Index
);
601 Value
.getStructNumBases(), "base", "bases");
605 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
606 return Value
.getStructField(Index
);
608 Value
.getStructNumFields(), "field", "fields");
612 case APValue::Union
: {
615 ColorScope
Color(OS
, ShowColors
, ValueColor
);
616 if (const FieldDecl
*FD
= Value
.getUnionField())
617 OS
<< " ." << *cast
<NamedDecl
>(FD
);
619 // If the union value is considered to be simple, fold it into the
620 // current line to save some vertical space.
621 const APValue
&UnionValue
= Value
.getUnionValue();
622 if (isSimpleAPValue(UnionValue
)) {
624 Visit(UnionValue
, Ty
);
626 AddChild([=] { Visit(UnionValue
, Ty
); });
631 case APValue::MemberPointer
:
632 OS
<< "MemberPointer <todo>";
634 case APValue::AddrLabelDiff
:
635 OS
<< "AddrLabelDiff <todo>";
638 llvm_unreachable("Unknown APValue kind!");
641 void TextNodeDumper::dumpPointer(const void *Ptr
) {
642 ColorScope
Color(OS
, ShowColors
, AddressColor
);
646 void TextNodeDumper::dumpLocation(SourceLocation Loc
) {
650 ColorScope
Color(OS
, ShowColors
, LocationColor
);
651 SourceLocation SpellingLoc
= SM
->getSpellingLoc(Loc
);
653 // The general format we print out is filename:line:col, but we drop pieces
654 // that haven't changed since the last loc printed.
655 PresumedLoc PLoc
= SM
->getPresumedLoc(SpellingLoc
);
657 if (PLoc
.isInvalid()) {
658 OS
<< "<invalid sloc>";
662 if (strcmp(PLoc
.getFilename(), LastLocFilename
) != 0) {
663 OS
<< PLoc
.getFilename() << ':' << PLoc
.getLine() << ':'
665 LastLocFilename
= PLoc
.getFilename();
666 LastLocLine
= PLoc
.getLine();
667 } else if (PLoc
.getLine() != LastLocLine
) {
668 OS
<< "line" << ':' << PLoc
.getLine() << ':' << PLoc
.getColumn();
669 LastLocLine
= PLoc
.getLine();
671 OS
<< "col" << ':' << PLoc
.getColumn();
675 void TextNodeDumper::dumpSourceRange(SourceRange R
) {
676 // Can't translate locations if a SourceManager isn't available.
681 dumpLocation(R
.getBegin());
682 if (R
.getBegin() != R
.getEnd()) {
684 dumpLocation(R
.getEnd());
688 // <t2.c:123:421[blah], t2.c:412:321>
691 void TextNodeDumper::dumpBareType(QualType T
, bool Desugar
) {
692 ColorScope
Color(OS
, ShowColors
, TypeColor
);
694 SplitQualType T_split
= T
.split();
695 std::string T_str
= QualType::getAsString(T_split
, PrintPolicy
);
696 OS
<< "'" << T_str
<< "'";
698 if (Desugar
&& !T
.isNull()) {
699 // If the type is sugared, also dump a (shallow) desugared type when
700 // it is visibly different.
701 SplitQualType D_split
= T
.getSplitDesugaredType();
702 if (T_split
!= D_split
) {
703 std::string D_str
= QualType::getAsString(D_split
, PrintPolicy
);
705 OS
<< ":'" << QualType::getAsString(D_split
, PrintPolicy
) << "'";
710 void TextNodeDumper::dumpType(QualType T
) {
715 void TextNodeDumper::dumpBareDeclRef(const Decl
*D
) {
717 ColorScope
Color(OS
, ShowColors
, NullColor
);
723 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
724 OS
<< D
->getDeclKindName();
728 if (const NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
)) {
729 ColorScope
Color(OS
, ShowColors
, DeclNameColor
);
730 OS
<< " '" << ND
->getDeclName() << '\'';
733 if (const ValueDecl
*VD
= dyn_cast
<ValueDecl
>(D
))
734 dumpType(VD
->getType());
737 void TextNodeDumper::dumpName(const NamedDecl
*ND
) {
738 if (ND
->getDeclName()) {
739 ColorScope
Color(OS
, ShowColors
, DeclNameColor
);
740 OS
<< ' ' << ND
->getDeclName();
744 void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS
) {
745 const auto AccessSpelling
= getAccessSpelling(AS
);
746 if (AccessSpelling
.empty())
748 OS
<< AccessSpelling
;
751 void TextNodeDumper::dumpCleanupObject(
752 const ExprWithCleanups::CleanupObject
&C
) {
753 if (auto *BD
= C
.dyn_cast
<BlockDecl
*>())
754 dumpDeclRef(BD
, "cleanup");
755 else if (auto *CLE
= C
.dyn_cast
<CompoundLiteralExpr
*>())
759 ColorScope
Color(OS
, ShowColors
, StmtColor
);
760 OS
<< CLE
->getStmtClassName();
765 llvm_unreachable("unexpected cleanup type");
768 void clang::TextNodeDumper::dumpTemplateSpecializationKind(
769 TemplateSpecializationKind TSK
) {
773 case TSK_ImplicitInstantiation
:
774 OS
<< " implicit_instantiation";
776 case TSK_ExplicitSpecialization
:
777 OS
<< " explicit_specialization";
779 case TSK_ExplicitInstantiationDeclaration
:
780 OS
<< " explicit_instantiation_declaration";
782 case TSK_ExplicitInstantiationDefinition
:
783 OS
<< " explicit_instantiation_definition";
788 void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier
*NNS
) {
793 OS
<< "NestedNameSpecifier";
795 switch (NNS
->getKind()) {
796 case NestedNameSpecifier::Identifier
:
798 OS
<< " '" << NNS
->getAsIdentifier()->getName() << "'";
800 case NestedNameSpecifier::Namespace
:
801 OS
<< " "; // "Namespace" is printed as the decl kind.
802 dumpBareDeclRef(NNS
->getAsNamespace());
804 case NestedNameSpecifier::NamespaceAlias
:
805 OS
<< " "; // "NamespaceAlias" is printed as the decl kind.
806 dumpBareDeclRef(NNS
->getAsNamespaceAlias());
808 case NestedNameSpecifier::TypeSpec
:
810 dumpType(QualType(NNS
->getAsType(), 0));
812 case NestedNameSpecifier::TypeSpecWithTemplate
:
813 OS
<< " TypeSpecWithTemplate";
814 dumpType(QualType(NNS
->getAsType(), 0));
816 case NestedNameSpecifier::Global
:
819 case NestedNameSpecifier::Super
:
824 dumpNestedNameSpecifier(NNS
->getPrefix());
828 void TextNodeDumper::dumpDeclRef(const Decl
*D
, StringRef Label
) {
839 const char *TextNodeDumper::getCommandName(unsigned CommandID
) {
841 return Traits
->getCommandInfo(CommandID
)->Name
;
842 const comments::CommandInfo
*Info
=
843 comments::CommandTraits::getBuiltinCommandInfo(CommandID
);
846 return "<not a builtin command>";
849 void TextNodeDumper::printFPOptions(FPOptionsOverride FPO
) {
850 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
851 if (FPO.has##NAME##Override()) \
852 OS << " " #NAME "=" << FPO.get##NAME##Override();
853 #include "clang/Basic/FPOptions.def"
856 void TextNodeDumper::visitTextComment(const comments::TextComment
*C
,
857 const comments::FullComment
*) {
858 OS
<< " Text=\"" << C
->getText() << "\"";
861 void TextNodeDumper::visitInlineCommandComment(
862 const comments::InlineCommandComment
*C
, const comments::FullComment
*) {
863 OS
<< " Name=\"" << getCommandName(C
->getCommandID()) << "\"";
864 switch (C
->getRenderKind()) {
865 case comments::InlineCommandComment::RenderNormal
:
866 OS
<< " RenderNormal";
868 case comments::InlineCommandComment::RenderBold
:
871 case comments::InlineCommandComment::RenderMonospaced
:
872 OS
<< " RenderMonospaced";
874 case comments::InlineCommandComment::RenderEmphasized
:
875 OS
<< " RenderEmphasized";
877 case comments::InlineCommandComment::RenderAnchor
:
878 OS
<< " RenderAnchor";
882 for (unsigned i
= 0, e
= C
->getNumArgs(); i
!= e
; ++i
)
883 OS
<< " Arg[" << i
<< "]=\"" << C
->getArgText(i
) << "\"";
886 void TextNodeDumper::visitHTMLStartTagComment(
887 const comments::HTMLStartTagComment
*C
, const comments::FullComment
*) {
888 OS
<< " Name=\"" << C
->getTagName() << "\"";
889 if (C
->getNumAttrs() != 0) {
891 for (unsigned i
= 0, e
= C
->getNumAttrs(); i
!= e
; ++i
) {
892 const comments::HTMLStartTagComment::Attribute
&Attr
= C
->getAttr(i
);
893 OS
<< " \"" << Attr
.Name
<< "=\"" << Attr
.Value
<< "\"";
896 if (C
->isSelfClosing())
897 OS
<< " SelfClosing";
900 void TextNodeDumper::visitHTMLEndTagComment(
901 const comments::HTMLEndTagComment
*C
, const comments::FullComment
*) {
902 OS
<< " Name=\"" << C
->getTagName() << "\"";
905 void TextNodeDumper::visitBlockCommandComment(
906 const comments::BlockCommandComment
*C
, const comments::FullComment
*) {
907 OS
<< " Name=\"" << getCommandName(C
->getCommandID()) << "\"";
908 for (unsigned i
= 0, e
= C
->getNumArgs(); i
!= e
; ++i
)
909 OS
<< " Arg[" << i
<< "]=\"" << C
->getArgText(i
) << "\"";
912 void TextNodeDumper::visitParamCommandComment(
913 const comments::ParamCommandComment
*C
, const comments::FullComment
*FC
) {
915 << comments::ParamCommandComment::getDirectionAsString(C
->getDirection());
917 if (C
->isDirectionExplicit())
922 if (C
->hasParamName()) {
923 if (C
->isParamIndexValid())
924 OS
<< " Param=\"" << C
->getParamName(FC
) << "\"";
926 OS
<< " Param=\"" << C
->getParamNameAsWritten() << "\"";
929 if (C
->isParamIndexValid() && !C
->isVarArgParam())
930 OS
<< " ParamIndex=" << C
->getParamIndex();
933 void TextNodeDumper::visitTParamCommandComment(
934 const comments::TParamCommandComment
*C
, const comments::FullComment
*FC
) {
935 if (C
->hasParamName()) {
936 if (C
->isPositionValid())
937 OS
<< " Param=\"" << C
->getParamName(FC
) << "\"";
939 OS
<< " Param=\"" << C
->getParamNameAsWritten() << "\"";
942 if (C
->isPositionValid()) {
944 for (unsigned i
= 0, e
= C
->getDepth(); i
!= e
; ++i
) {
945 OS
<< C
->getIndex(i
);
953 void TextNodeDumper::visitVerbatimBlockComment(
954 const comments::VerbatimBlockComment
*C
, const comments::FullComment
*) {
955 OS
<< " Name=\"" << getCommandName(C
->getCommandID())
958 << C
->getCloseName() << "\"";
961 void TextNodeDumper::visitVerbatimBlockLineComment(
962 const comments::VerbatimBlockLineComment
*C
,
963 const comments::FullComment
*) {
964 OS
<< " Text=\"" << C
->getText() << "\"";
967 void TextNodeDumper::visitVerbatimLineComment(
968 const comments::VerbatimLineComment
*C
, const comments::FullComment
*) {
969 OS
<< " Text=\"" << C
->getText() << "\"";
972 void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument
&) {
976 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument
&TA
) {
978 dumpType(TA
.getAsType());
981 void TextNodeDumper::VisitDeclarationTemplateArgument(
982 const TemplateArgument
&TA
) {
984 dumpDeclRef(TA
.getAsDecl());
987 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument
&) {
991 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument
&TA
) {
992 OS
<< " integral " << TA
.getAsIntegral();
995 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument
&TA
) {
996 if (TA
.getAsTemplate().getKind() == TemplateName::UsingTemplate
)
999 TA
.getAsTemplate().dump(OS
);
1002 void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
1003 const TemplateArgument
&TA
) {
1004 if (TA
.getAsTemplateOrTemplatePattern().getKind() ==
1005 TemplateName::UsingTemplate
)
1007 OS
<< " template expansion ";
1008 TA
.getAsTemplateOrTemplatePattern().dump(OS
);
1011 void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument
&) {
1015 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument
&) {
1019 static void dumpBasePath(raw_ostream
&OS
, const CastExpr
*Node
) {
1020 if (Node
->path_empty())
1025 for (CastExpr::path_const_iterator I
= Node
->path_begin(),
1026 E
= Node
->path_end();
1028 const CXXBaseSpecifier
*Base
= *I
;
1033 cast
<CXXRecordDecl
>(Base
->getType()->castAs
<RecordType
>()->getDecl());
1035 if (Base
->isVirtual())
1037 OS
<< RD
->getName();
1044 void TextNodeDumper::VisitIfStmt(const IfStmt
*Node
) {
1045 if (Node
->hasInitStorage())
1047 if (Node
->hasVarStorage())
1049 if (Node
->hasElseStorage())
1051 if (Node
->isConstexpr())
1053 if (Node
->isConsteval()) {
1055 if (Node
->isNegatedConsteval())
1061 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt
*Node
) {
1062 if (Node
->hasInitStorage())
1064 if (Node
->hasVarStorage())
1068 void TextNodeDumper::VisitWhileStmt(const WhileStmt
*Node
) {
1069 if (Node
->hasVarStorage())
1073 void TextNodeDumper::VisitLabelStmt(const LabelStmt
*Node
) {
1074 OS
<< " '" << Node
->getName() << "'";
1075 if (Node
->isSideEntry())
1076 OS
<< " side_entry";
1079 void TextNodeDumper::VisitGotoStmt(const GotoStmt
*Node
) {
1080 OS
<< " '" << Node
->getLabel()->getName() << "'";
1081 dumpPointer(Node
->getLabel());
1084 void TextNodeDumper::VisitCaseStmt(const CaseStmt
*Node
) {
1085 if (Node
->caseStmtIsGNURange())
1089 void clang::TextNodeDumper::VisitReturnStmt(const ReturnStmt
*Node
) {
1090 if (const VarDecl
*Cand
= Node
->getNRVOCandidate()) {
1091 OS
<< " nrvo_candidate(";
1092 dumpBareDeclRef(Cand
);
1097 void TextNodeDumper::VisitConstantExpr(const ConstantExpr
*Node
) {
1098 if (Node
->hasAPValueResult())
1100 [=] { Visit(Node
->getAPValueResult(), Node
->getType()); });
1103 void TextNodeDumper::VisitCallExpr(const CallExpr
*Node
) {
1104 if (Node
->usesADL())
1106 if (Node
->hasStoredFPFeatures())
1107 printFPOptions(Node
->getFPFeatures());
1110 void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr
*Node
) {
1111 const char *OperatorSpelling
= clang::getOperatorSpelling(Node
->getOperator());
1112 if (OperatorSpelling
)
1113 OS
<< " '" << OperatorSpelling
<< "'";
1115 VisitCallExpr(Node
);
1118 void TextNodeDumper::VisitCastExpr(const CastExpr
*Node
) {
1121 ColorScope
Color(OS
, ShowColors
, CastColor
);
1122 OS
<< Node
->getCastKindName();
1124 dumpBasePath(OS
, Node
);
1126 if (Node
->hasStoredFPFeatures())
1127 printFPOptions(Node
->getFPFeatures());
1130 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr
*Node
) {
1131 VisitCastExpr(Node
);
1132 if (Node
->isPartOfExplicitCast())
1133 OS
<< " part_of_explicit_cast";
1136 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr
*Node
) {
1138 dumpBareDeclRef(Node
->getDecl());
1139 dumpNestedNameSpecifier(Node
->getQualifier());
1140 if (Node
->getDecl() != Node
->getFoundDecl()) {
1142 dumpBareDeclRef(Node
->getFoundDecl());
1145 switch (Node
->isNonOdrUse()) {
1146 case NOUR_None
: break;
1147 case NOUR_Unevaluated
: OS
<< " non_odr_use_unevaluated"; break;
1148 case NOUR_Constant
: OS
<< " non_odr_use_constant"; break;
1149 case NOUR_Discarded
: OS
<< " non_odr_use_discarded"; break;
1151 if (Node
->refersToEnclosingVariableOrCapture())
1152 OS
<< " refers_to_enclosing_variable_or_capture";
1153 if (Node
->isImmediateEscalating())
1154 OS
<< " immediate-escalating";
1157 void clang::TextNodeDumper::VisitDependentScopeDeclRefExpr(
1158 const DependentScopeDeclRefExpr
*Node
) {
1160 dumpNestedNameSpecifier(Node
->getQualifier());
1163 void TextNodeDumper::VisitUnresolvedLookupExpr(
1164 const UnresolvedLookupExpr
*Node
) {
1166 if (!Node
->requiresADL())
1168 OS
<< "ADL) = '" << Node
->getName() << '\'';
1170 UnresolvedLookupExpr::decls_iterator I
= Node
->decls_begin(),
1171 E
= Node
->decls_end();
1178 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr
*Node
) {
1180 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
1181 OS
<< " " << Node
->getDecl()->getDeclKindName() << "Decl";
1183 OS
<< "='" << *Node
->getDecl() << "'";
1184 dumpPointer(Node
->getDecl());
1185 if (Node
->isFreeIvar())
1186 OS
<< " isFreeIvar";
1189 void TextNodeDumper::VisitSYCLUniqueStableNameExpr(
1190 const SYCLUniqueStableNameExpr
*Node
) {
1191 dumpType(Node
->getTypeSourceInfo()->getType());
1194 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr
*Node
) {
1195 OS
<< " " << PredefinedExpr::getIdentKindName(Node
->getIdentKind());
1198 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral
*Node
) {
1199 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1200 OS
<< " " << Node
->getValue();
1203 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral
*Node
) {
1204 bool isSigned
= Node
->getType()->isSignedIntegerType();
1205 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1206 OS
<< " " << toString(Node
->getValue(), 10, isSigned
);
1209 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral
*Node
) {
1210 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1211 OS
<< " " << Node
->getValueAsString(/*Radix=*/10);
1214 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral
*Node
) {
1215 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1216 OS
<< " " << Node
->getValueAsApproximateDouble();
1219 void TextNodeDumper::VisitStringLiteral(const StringLiteral
*Str
) {
1220 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1222 Str
->outputString(OS
);
1225 void TextNodeDumper::VisitInitListExpr(const InitListExpr
*ILE
) {
1226 if (auto *Field
= ILE
->getInitializedFieldInUnion()) {
1228 dumpBareDeclRef(Field
);
1232 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr
*E
) {
1233 if (E
->isResultDependent())
1234 OS
<< " result_dependent";
1237 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator
*Node
) {
1238 OS
<< " " << (Node
->isPostfix() ? "postfix" : "prefix") << " '"
1239 << UnaryOperator::getOpcodeStr(Node
->getOpcode()) << "'";
1240 if (!Node
->canOverflow())
1241 OS
<< " cannot overflow";
1242 if (Node
->hasStoredFPFeatures())
1243 printFPOptions(Node
->getStoredFPFeatures());
1246 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1247 const UnaryExprOrTypeTraitExpr
*Node
) {
1248 OS
<< " " << getTraitSpelling(Node
->getKind());
1250 if (Node
->isArgumentType())
1251 dumpType(Node
->getArgumentType());
1254 void TextNodeDumper::VisitMemberExpr(const MemberExpr
*Node
) {
1255 OS
<< " " << (Node
->isArrow() ? "->" : ".") << *Node
->getMemberDecl();
1256 dumpPointer(Node
->getMemberDecl());
1257 dumpNestedNameSpecifier(Node
->getQualifier());
1258 switch (Node
->isNonOdrUse()) {
1259 case NOUR_None
: break;
1260 case NOUR_Unevaluated
: OS
<< " non_odr_use_unevaluated"; break;
1261 case NOUR_Constant
: OS
<< " non_odr_use_constant"; break;
1262 case NOUR_Discarded
: OS
<< " non_odr_use_discarded"; break;
1266 void TextNodeDumper::VisitExtVectorElementExpr(
1267 const ExtVectorElementExpr
*Node
) {
1268 OS
<< " " << Node
->getAccessor().getNameStart();
1271 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator
*Node
) {
1272 OS
<< " '" << BinaryOperator::getOpcodeStr(Node
->getOpcode()) << "'";
1273 if (Node
->hasStoredFPFeatures())
1274 printFPOptions(Node
->getStoredFPFeatures());
1277 void TextNodeDumper::VisitCompoundAssignOperator(
1278 const CompoundAssignOperator
*Node
) {
1279 OS
<< " '" << BinaryOperator::getOpcodeStr(Node
->getOpcode())
1280 << "' ComputeLHSTy=";
1281 dumpBareType(Node
->getComputationLHSType());
1282 OS
<< " ComputeResultTy=";
1283 dumpBareType(Node
->getComputationResultType());
1284 if (Node
->hasStoredFPFeatures())
1285 printFPOptions(Node
->getStoredFPFeatures());
1288 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr
*Node
) {
1289 OS
<< " " << Node
->getLabel()->getName();
1290 dumpPointer(Node
->getLabel());
1293 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr
*Node
) {
1294 OS
<< " " << Node
->getCastName() << "<"
1295 << Node
->getTypeAsWritten().getAsString() << ">"
1296 << " <" << Node
->getCastKindName();
1297 dumpBasePath(OS
, Node
);
1301 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr
*Node
) {
1302 OS
<< " " << (Node
->getValue() ? "true" : "false");
1305 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr
*Node
) {
1306 if (Node
->isImplicit())
1311 void TextNodeDumper::VisitCXXFunctionalCastExpr(
1312 const CXXFunctionalCastExpr
*Node
) {
1313 OS
<< " functional cast to " << Node
->getTypeAsWritten().getAsString() << " <"
1314 << Node
->getCastKindName() << ">";
1315 if (Node
->hasStoredFPFeatures())
1316 printFPOptions(Node
->getFPFeatures());
1319 void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr
*Node
) {
1320 VisitCXXNamedCastExpr(Node
);
1321 if (Node
->hasStoredFPFeatures())
1322 printFPOptions(Node
->getFPFeatures());
1325 void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
1326 const CXXUnresolvedConstructExpr
*Node
) {
1327 dumpType(Node
->getTypeAsWritten());
1328 if (Node
->isListInitialization())
1332 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr
*Node
) {
1333 CXXConstructorDecl
*Ctor
= Node
->getConstructor();
1334 dumpType(Ctor
->getType());
1335 if (Node
->isElidable())
1337 if (Node
->isListInitialization())
1339 if (Node
->isStdInitListInitialization())
1340 OS
<< " std::initializer_list";
1341 if (Node
->requiresZeroInitialization())
1343 if (Node
->isImmediateEscalating())
1344 OS
<< " immediate-escalating";
1347 void TextNodeDumper::VisitCXXBindTemporaryExpr(
1348 const CXXBindTemporaryExpr
*Node
) {
1349 OS
<< " (CXXTemporary";
1354 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr
*Node
) {
1355 if (Node
->isGlobalNew())
1357 if (Node
->isArray())
1359 if (Node
->getOperatorNew()) {
1361 dumpBareDeclRef(Node
->getOperatorNew());
1363 // We could dump the deallocation function used in case of error, but it's
1364 // usually not that interesting.
1367 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr
*Node
) {
1368 if (Node
->isGlobalDelete())
1370 if (Node
->isArrayForm())
1372 if (Node
->getOperatorDelete()) {
1374 dumpBareDeclRef(Node
->getOperatorDelete());
1378 void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr
*Node
) {
1379 OS
<< " " << getTraitSpelling(Node
->getTrait());
1382 void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr
*Node
) {
1383 OS
<< " " << getTraitSpelling(Node
->getTrait());
1386 void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr
*Node
) {
1387 OS
<< " " << getTraitSpelling(Node
->getTrait());
1390 void TextNodeDumper::VisitMaterializeTemporaryExpr(
1391 const MaterializeTemporaryExpr
*Node
) {
1392 if (const ValueDecl
*VD
= Node
->getExtendingDecl()) {
1393 OS
<< " extended by ";
1394 dumpBareDeclRef(VD
);
1398 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups
*Node
) {
1399 for (unsigned i
= 0, e
= Node
->getNumObjects(); i
!= e
; ++i
)
1400 dumpCleanupObject(Node
->getObject(i
));
1403 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr
*Node
) {
1404 dumpPointer(Node
->getPack());
1405 dumpName(Node
->getPack());
1408 void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
1409 const CXXDependentScopeMemberExpr
*Node
) {
1410 OS
<< " " << (Node
->isArrow() ? "->" : ".") << Node
->getMember();
1413 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr
*Node
) {
1415 Node
->getSelector().print(OS
);
1416 switch (Node
->getReceiverKind()) {
1417 case ObjCMessageExpr::Instance
:
1420 case ObjCMessageExpr::Class
:
1422 dumpBareType(Node
->getClassReceiver());
1425 case ObjCMessageExpr::SuperInstance
:
1426 OS
<< " super (instance)";
1429 case ObjCMessageExpr::SuperClass
:
1430 OS
<< " super (class)";
1435 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr
*Node
) {
1436 if (auto *BoxingMethod
= Node
->getBoxingMethod()) {
1438 BoxingMethod
->getSelector().print(OS
);
1442 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt
*Node
) {
1443 if (!Node
->getCatchParamDecl())
1447 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr
*Node
) {
1448 dumpType(Node
->getEncodedType());
1451 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr
*Node
) {
1453 Node
->getSelector().print(OS
);
1456 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr
*Node
) {
1457 OS
<< ' ' << *Node
->getProtocol();
1460 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr
*Node
) {
1461 if (Node
->isImplicitProperty()) {
1462 OS
<< " Kind=MethodRef Getter=\"";
1463 if (Node
->getImplicitPropertyGetter())
1464 Node
->getImplicitPropertyGetter()->getSelector().print(OS
);
1468 OS
<< "\" Setter=\"";
1469 if (ObjCMethodDecl
*Setter
= Node
->getImplicitPropertySetter())
1470 Setter
->getSelector().print(OS
);
1475 OS
<< " Kind=PropertyRef Property=\"" << *Node
->getExplicitProperty()
1479 if (Node
->isSuperReceiver())
1482 OS
<< " Messaging=";
1483 if (Node
->isMessagingGetter() && Node
->isMessagingSetter())
1484 OS
<< "Getter&Setter";
1485 else if (Node
->isMessagingGetter())
1487 else if (Node
->isMessagingSetter())
1491 void TextNodeDumper::VisitObjCSubscriptRefExpr(
1492 const ObjCSubscriptRefExpr
*Node
) {
1493 if (Node
->isArraySubscriptRefExpr())
1494 OS
<< " Kind=ArraySubscript GetterForArray=\"";
1496 OS
<< " Kind=DictionarySubscript GetterForDictionary=\"";
1497 if (Node
->getAtIndexMethodDecl())
1498 Node
->getAtIndexMethodDecl()->getSelector().print(OS
);
1502 if (Node
->isArraySubscriptRefExpr())
1503 OS
<< "\" SetterForArray=\"";
1505 OS
<< "\" SetterForDictionary=\"";
1506 if (Node
->setAtIndexMethodDecl())
1507 Node
->setAtIndexMethodDecl()->getSelector().print(OS
);
1512 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr
*Node
) {
1513 OS
<< " " << (Node
->getValue() ? "__objc_yes" : "__objc_no");
1516 void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr
*Node
) {
1518 for (unsigned I
= 0, E
= Node
->numOfIterators(); I
< E
; ++I
) {
1519 Visit(Node
->getIteratorDecl(I
));
1521 const OMPIteratorExpr::IteratorRange Range
= Node
->getIteratorRange(I
);
1533 void TextNodeDumper::VisitConceptSpecializationExpr(
1534 const ConceptSpecializationExpr
*Node
) {
1536 dumpBareDeclRef(Node
->getFoundDecl());
1539 void TextNodeDumper::VisitRequiresExpr(
1540 const RequiresExpr
*Node
) {
1541 if (!Node
->isValueDependent())
1542 OS
<< (Node
->isSatisfied() ? " satisfied" : " unsatisfied");
1545 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType
*T
) {
1546 if (T
->isSpelledAsLValue())
1547 OS
<< " written as lvalue reference";
1550 void TextNodeDumper::VisitArrayType(const ArrayType
*T
) {
1551 switch (T
->getSizeModifier()) {
1552 case ArraySizeModifier::Normal
:
1554 case ArraySizeModifier::Static
:
1557 case ArraySizeModifier::Star
:
1561 OS
<< " " << T
->getIndexTypeQualifiers().getAsString();
1564 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType
*T
) {
1565 OS
<< " " << T
->getSize();
1569 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType
*T
) {
1571 dumpSourceRange(T
->getBracketsRange());
1575 void TextNodeDumper::VisitDependentSizedArrayType(
1576 const DependentSizedArrayType
*T
) {
1579 dumpSourceRange(T
->getBracketsRange());
1582 void TextNodeDumper::VisitDependentSizedExtVectorType(
1583 const DependentSizedExtVectorType
*T
) {
1585 dumpLocation(T
->getAttributeLoc());
1588 void TextNodeDumper::VisitVectorType(const VectorType
*T
) {
1589 switch (T
->getVectorKind()) {
1590 case VectorKind::Generic
:
1592 case VectorKind::AltiVecVector
:
1595 case VectorKind::AltiVecPixel
:
1596 OS
<< " altivec pixel";
1598 case VectorKind::AltiVecBool
:
1599 OS
<< " altivec bool";
1601 case VectorKind::Neon
:
1604 case VectorKind::NeonPoly
:
1607 case VectorKind::SveFixedLengthData
:
1608 OS
<< " fixed-length sve data vector";
1610 case VectorKind::SveFixedLengthPredicate
:
1611 OS
<< " fixed-length sve predicate vector";
1613 case VectorKind::RVVFixedLengthData
:
1614 OS
<< " fixed-length rvv data vector";
1617 OS
<< " " << T
->getNumElements();
1620 void TextNodeDumper::VisitFunctionType(const FunctionType
*T
) {
1621 auto EI
= T
->getExtInfo();
1622 if (EI
.getNoReturn())
1624 if (EI
.getProducesResult())
1625 OS
<< " produces_result";
1626 if (EI
.getHasRegParm())
1627 OS
<< " regparm " << EI
.getRegParm();
1628 OS
<< " " << FunctionType::getNameForCallConv(EI
.getCC());
1631 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType
*T
) {
1632 auto EPI
= T
->getExtProtoInfo();
1633 if (EPI
.HasTrailingReturn
)
1634 OS
<< " trailing_return";
1637 if (T
->isVolatile())
1639 if (T
->isRestrict())
1641 if (T
->getExtProtoInfo().Variadic
)
1643 switch (EPI
.RefQualifier
) {
1654 switch (EPI
.ExceptionSpec
.Type
) {
1657 case EST_DynamicNone
:
1658 OS
<< " exceptionspec_dynamic_none";
1661 OS
<< " exceptionspec_dynamic";
1664 OS
<< " exceptionspec_ms_any";
1667 OS
<< " exceptionspec_nothrow";
1669 case EST_BasicNoexcept
:
1670 OS
<< " exceptionspec_basic_noexcept";
1672 case EST_DependentNoexcept
:
1673 OS
<< " exceptionspec_dependent_noexcept";
1675 case EST_NoexceptFalse
:
1676 OS
<< " exceptionspec_noexcept_false";
1678 case EST_NoexceptTrue
:
1679 OS
<< " exceptionspec_noexcept_true";
1681 case EST_Unevaluated
:
1682 OS
<< " exceptionspec_unevaluated";
1684 case EST_Uninstantiated
:
1685 OS
<< " exceptionspec_uninstantiated";
1688 OS
<< " exceptionspec_unparsed";
1691 if (!EPI
.ExceptionSpec
.Exceptions
.empty()) {
1693 OS
<< "Exceptions:";
1694 for (unsigned I
= 0, N
= EPI
.ExceptionSpec
.Exceptions
.size(); I
!= N
;
1698 dumpType(EPI
.ExceptionSpec
.Exceptions
[I
]);
1702 if (EPI
.ExceptionSpec
.NoexceptExpr
) {
1704 OS
<< "NoexceptExpr: ";
1705 Visit(EPI
.ExceptionSpec
.NoexceptExpr
);
1708 dumpDeclRef(EPI
.ExceptionSpec
.SourceDecl
, "ExceptionSourceDecl");
1709 dumpDeclRef(EPI
.ExceptionSpec
.SourceTemplate
, "ExceptionSourceTemplate");
1711 // FIXME: Consumed parameters.
1712 VisitFunctionType(T
);
1715 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType
*T
) {
1716 dumpDeclRef(T
->getDecl());
1719 void TextNodeDumper::VisitUsingType(const UsingType
*T
) {
1720 dumpDeclRef(T
->getFoundDecl());
1721 if (!T
->typeMatchesDecl())
1725 void TextNodeDumper::VisitTypedefType(const TypedefType
*T
) {
1726 dumpDeclRef(T
->getDecl());
1727 if (!T
->typeMatchesDecl())
1731 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType
*T
) {
1732 switch (T
->getUTTKind()) {
1733 #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1734 case UnaryTransformType::Enum: \
1737 #include "clang/Basic/TransformTypeTraits.def"
1741 void TextNodeDumper::VisitTagType(const TagType
*T
) {
1742 dumpDeclRef(T
->getDecl());
1745 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType
*T
) {
1746 OS
<< " depth " << T
->getDepth() << " index " << T
->getIndex();
1747 if (T
->isParameterPack())
1749 dumpDeclRef(T
->getDecl());
1752 void TextNodeDumper::VisitSubstTemplateTypeParmType(
1753 const SubstTemplateTypeParmType
*T
) {
1754 dumpDeclRef(T
->getAssociatedDecl());
1755 VisitTemplateTypeParmDecl(T
->getReplacedParameter());
1756 if (auto PackIndex
= T
->getPackIndex())
1757 OS
<< " pack_index " << *PackIndex
;
1760 void TextNodeDumper::VisitSubstTemplateTypeParmPackType(
1761 const SubstTemplateTypeParmPackType
*T
) {
1762 dumpDeclRef(T
->getAssociatedDecl());
1763 VisitTemplateTypeParmDecl(T
->getReplacedParameter());
1766 void TextNodeDumper::VisitAutoType(const AutoType
*T
) {
1767 if (T
->isDecltypeAuto())
1768 OS
<< " decltype(auto)";
1769 if (!T
->isDeduced())
1771 if (T
->isConstrained()) {
1772 dumpDeclRef(T
->getTypeConstraintConcept());
1773 for (const auto &Arg
: T
->getTypeConstraintArguments())
1774 VisitTemplateArgument(Arg
);
1778 void TextNodeDumper::VisitDeducedTemplateSpecializationType(
1779 const DeducedTemplateSpecializationType
*T
) {
1780 if (T
->getTemplateName().getKind() == TemplateName::UsingTemplate
)
1784 void TextNodeDumper::VisitTemplateSpecializationType(
1785 const TemplateSpecializationType
*T
) {
1786 if (T
->isTypeAlias())
1788 if (T
->getTemplateName().getKind() == TemplateName::UsingTemplate
)
1791 T
->getTemplateName().dump(OS
);
1794 void TextNodeDumper::VisitInjectedClassNameType(
1795 const InjectedClassNameType
*T
) {
1796 dumpDeclRef(T
->getDecl());
1799 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType
*T
) {
1800 dumpDeclRef(T
->getDecl());
1803 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType
*T
) {
1804 if (auto N
= T
->getNumExpansions())
1805 OS
<< " expansions " << *N
;
1808 void TextNodeDumper::VisitLabelDecl(const LabelDecl
*D
) { dumpName(D
); }
1810 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl
*D
) {
1812 dumpType(D
->getUnderlyingType());
1813 if (D
->isModulePrivate())
1814 OS
<< " __module_private__";
1817 void TextNodeDumper::VisitEnumDecl(const EnumDecl
*D
) {
1818 if (D
->isScoped()) {
1819 if (D
->isScopedUsingClassTag())
1825 if (D
->isModulePrivate())
1826 OS
<< " __module_private__";
1828 dumpType(D
->getIntegerType());
1831 void TextNodeDumper::VisitRecordDecl(const RecordDecl
*D
) {
1832 OS
<< ' ' << D
->getKindName();
1834 if (D
->isModulePrivate())
1835 OS
<< " __module_private__";
1836 if (D
->isCompleteDefinition())
1837 OS
<< " definition";
1840 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl
*D
) {
1842 dumpType(D
->getType());
1845 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl
*D
) {
1847 dumpType(D
->getType());
1849 for (const auto *Child
: D
->chain())
1853 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl
*D
) {
1855 dumpType(D
->getType());
1856 dumpTemplateSpecializationKind(D
->getTemplateSpecializationKind());
1858 StorageClass SC
= D
->getStorageClass();
1860 OS
<< ' ' << VarDecl::getStorageClassSpecifierString(SC
);
1861 if (D
->isInlineSpecified())
1863 if (D
->isVirtualAsWritten())
1865 if (D
->isModulePrivate())
1866 OS
<< " __module_private__";
1870 if (D
->isDefaulted()) {
1875 if (D
->isDeletedAsWritten())
1880 if (D
->isIneligibleOrNotSelected())
1881 OS
<< (isa
<CXXDestructorDecl
>(D
) ? " not_selected" : " ineligible");
1883 if (const auto *FPT
= D
->getType()->getAs
<FunctionProtoType
>()) {
1884 FunctionProtoType::ExtProtoInfo EPI
= FPT
->getExtProtoInfo();
1885 switch (EPI
.ExceptionSpec
.Type
) {
1888 case EST_Unevaluated
:
1889 OS
<< " noexcept-unevaluated " << EPI
.ExceptionSpec
.SourceDecl
;
1891 case EST_Uninstantiated
:
1892 OS
<< " noexcept-uninstantiated " << EPI
.ExceptionSpec
.SourceTemplate
;
1897 if (const auto *MD
= dyn_cast
<CXXMethodDecl
>(D
)) {
1898 if (MD
->size_overridden_methods() != 0) {
1899 auto dumpOverride
= [=](const CXXMethodDecl
*D
) {
1900 SplitQualType T_split
= D
->getType().split();
1901 OS
<< D
<< " " << D
->getParent()->getName() << "::" << D
->getDeclName()
1902 << " '" << QualType::getAsString(T_split
, PrintPolicy
) << "'";
1906 auto Overrides
= MD
->overridden_methods();
1907 OS
<< "Overrides: [ ";
1908 dumpOverride(*Overrides
.begin());
1909 for (const auto *Override
: llvm::drop_begin(Overrides
)) {
1911 dumpOverride(Override
);
1918 if (!D
->isInlineSpecified() && D
->isInlined()) {
1919 OS
<< " implicit-inline";
1921 // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
1922 // the Params are set later, it is possible for a dump during debugging to
1923 // encounter a FunctionDecl that has been created but hasn't been assigned
1924 // ParmVarDecls yet.
1925 if (!D
->param_empty() && !D
->param_begin())
1926 OS
<< " <<<NULL params x " << D
->getNumParams() << ">>>";
1928 if (const auto *Instance
= D
->getInstantiatedFromMemberFunction()) {
1929 OS
<< " instantiated_from";
1930 dumpPointer(Instance
);
1934 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
1935 const LifetimeExtendedTemporaryDecl
*D
) {
1936 OS
<< " extended by ";
1937 dumpBareDeclRef(D
->getExtendingDecl());
1940 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1941 OS
<< D
->getManglingNumber();
1945 void TextNodeDumper::VisitFieldDecl(const FieldDecl
*D
) {
1947 dumpType(D
->getType());
1950 if (D
->isModulePrivate())
1951 OS
<< " __module_private__";
1954 void TextNodeDumper::VisitVarDecl(const VarDecl
*D
) {
1955 dumpNestedNameSpecifier(D
->getQualifier());
1957 if (const auto *P
= dyn_cast
<ParmVarDecl
>(D
);
1958 P
&& P
->isExplicitObjectParameter())
1961 dumpType(D
->getType());
1962 dumpTemplateSpecializationKind(D
->getTemplateSpecializationKind());
1963 StorageClass SC
= D
->getStorageClass();
1965 OS
<< ' ' << VarDecl::getStorageClassSpecifierString(SC
);
1966 switch (D
->getTLSKind()) {
1967 case VarDecl::TLS_None
:
1969 case VarDecl::TLS_Static
:
1972 case VarDecl::TLS_Dynamic
:
1973 OS
<< " tls_dynamic";
1976 if (D
->isModulePrivate())
1977 OS
<< " __module_private__";
1978 if (D
->isNRVOVariable())
1982 if (D
->isConstexpr())
1985 switch (D
->getInitStyle()) {
1986 case VarDecl::CInit
:
1989 case VarDecl::CallInit
:
1992 case VarDecl::ListInit
:
1995 case VarDecl::ParenListInit
:
1996 OS
<< " parenlistinit";
1999 if (D
->needsDestruction(D
->getASTContext()))
2001 if (D
->isParameterPack())
2005 const Expr
*E
= D
->getInit();
2006 // Only dump the value of constexpr VarDecls for now.
2007 if (E
&& !E
->isValueDependent() && D
->isConstexpr() &&
2008 !D
->getType()->isDependentType()) {
2009 const APValue
*Value
= D
->evaluateValue();
2011 AddChild("value", [=] { Visit(*Value
, E
->getType()); });
2016 void TextNodeDumper::VisitBindingDecl(const BindingDecl
*D
) {
2018 dumpType(D
->getType());
2021 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl
*D
) {
2026 void TextNodeDumper::VisitImportDecl(const ImportDecl
*D
) {
2027 OS
<< ' ' << D
->getImportedModule()->getFullModuleName();
2030 D
->getASTContext().getModuleInitializers(D
->getImportedModule()))
2031 dumpDeclRef(InitD
, "initializer");
2034 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl
*D
) {
2036 switch (D
->getCommentKind()) {
2038 llvm_unreachable("unexpected pragma comment kind");
2055 StringRef Arg
= D
->getArg();
2057 OS
<< " \"" << Arg
<< "\"";
2060 void TextNodeDumper::VisitPragmaDetectMismatchDecl(
2061 const PragmaDetectMismatchDecl
*D
) {
2062 OS
<< " \"" << D
->getName() << "\" \"" << D
->getValue() << "\"";
2065 void TextNodeDumper::VisitOMPExecutableDirective(
2066 const OMPExecutableDirective
*D
) {
2067 if (D
->isStandaloneDirective())
2068 OS
<< " openmp_standalone_directive";
2071 void TextNodeDumper::VisitOMPDeclareReductionDecl(
2072 const OMPDeclareReductionDecl
*D
) {
2074 dumpType(D
->getType());
2076 dumpPointer(D
->getCombiner());
2077 if (const auto *Initializer
= D
->getInitializer()) {
2078 OS
<< " initializer";
2079 dumpPointer(Initializer
);
2080 switch (D
->getInitializerKind()) {
2081 case OMPDeclareReductionInitKind::Direct
:
2082 OS
<< " omp_priv = ";
2084 case OMPDeclareReductionInitKind::Copy
:
2085 OS
<< " omp_priv ()";
2087 case OMPDeclareReductionInitKind::Call
:
2093 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl
*D
) {
2094 for (const auto *C
: D
->clauselists()) {
2097 ColorScope
Color(OS
, ShowColors
, NullColor
);
2098 OS
<< "<<<NULL>>> OMPClause";
2102 ColorScope
Color(OS
, ShowColors
, AttrColor
);
2103 StringRef
ClauseName(
2104 llvm::omp::getOpenMPClauseName(C
->getClauseKind()));
2105 OS
<< "OMP" << ClauseName
.substr(/*Start=*/0, /*N=*/1).upper()
2106 << ClauseName
.drop_front() << "Clause";
2109 dumpSourceRange(SourceRange(C
->getBeginLoc(), C
->getEndLoc()));
2114 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl
*D
) {
2116 dumpType(D
->getType());
2119 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl
*D
) {
2125 if (!D
->isOriginalNamespace())
2126 dumpDeclRef(D
->getOriginalNamespace(), "original");
2129 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl
*D
) {
2131 dumpBareDeclRef(D
->getNominatedNamespace());
2134 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl
*D
) {
2136 dumpDeclRef(D
->getAliasedNamespace());
2139 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl
*D
) {
2141 dumpType(D
->getUnderlyingType());
2144 void TextNodeDumper::VisitTypeAliasTemplateDecl(
2145 const TypeAliasTemplateDecl
*D
) {
2149 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl
*D
) {
2151 if (const auto *Instance
= D
->getInstantiatedFromMemberClass()) {
2152 OS
<< " instantiated_from";
2153 dumpPointer(Instance
);
2155 if (const auto *CTSD
= dyn_cast
<ClassTemplateSpecializationDecl
>(D
))
2156 dumpTemplateSpecializationKind(CTSD
->getSpecializationKind());
2158 dumpNestedNameSpecifier(D
->getQualifier());
2160 if (!D
->isCompleteDefinition())
2165 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2166 OS
<< "DefinitionData";
2168 #define FLAG(fn, name) \
2171 FLAG(isParsingBaseSpecifiers
, parsing_base_specifiers
);
2173 FLAG(isGenericLambda
, generic
);
2174 FLAG(isLambda
, lambda
);
2176 FLAG(isAnonymousStructOrUnion
, is_anonymous
);
2177 FLAG(canPassInRegisters
, pass_in_registers
);
2178 FLAG(isEmpty
, empty
);
2179 FLAG(isAggregate
, aggregate
);
2180 FLAG(isStandardLayout
, standard_layout
);
2181 FLAG(isTriviallyCopyable
, trivially_copyable
);
2183 FLAG(isTrivial
, trivial
);
2184 FLAG(isPolymorphic
, polymorphic
);
2185 FLAG(isAbstract
, abstract
);
2186 FLAG(isLiteral
, literal
);
2188 FLAG(hasUserDeclaredConstructor
, has_user_declared_ctor
);
2189 FLAG(hasConstexprNonCopyMoveConstructor
, has_constexpr_non_copy_move_ctor
);
2190 FLAG(hasMutableFields
, has_mutable_fields
);
2191 FLAG(hasVariantMembers
, has_variant_members
);
2192 FLAG(allowConstDefaultInit
, can_const_default_init
);
2196 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2197 OS
<< "DefaultConstructor";
2199 FLAG(hasDefaultConstructor
, exists
);
2200 FLAG(hasTrivialDefaultConstructor
, trivial
);
2201 FLAG(hasNonTrivialDefaultConstructor
, non_trivial
);
2202 FLAG(hasUserProvidedDefaultConstructor
, user_provided
);
2203 FLAG(hasConstexprDefaultConstructor
, constexpr);
2204 FLAG(needsImplicitDefaultConstructor
, needs_implicit
);
2205 FLAG(defaultedDefaultConstructorIsConstexpr
, defaulted_is_constexpr
);
2210 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2211 OS
<< "CopyConstructor";
2213 FLAG(hasSimpleCopyConstructor
, simple
);
2214 FLAG(hasTrivialCopyConstructor
, trivial
);
2215 FLAG(hasNonTrivialCopyConstructor
, non_trivial
);
2216 FLAG(hasUserDeclaredCopyConstructor
, user_declared
);
2217 FLAG(hasCopyConstructorWithConstParam
, has_const_param
);
2218 FLAG(needsImplicitCopyConstructor
, needs_implicit
);
2219 FLAG(needsOverloadResolutionForCopyConstructor
,
2220 needs_overload_resolution
);
2221 if (!D
->needsOverloadResolutionForCopyConstructor())
2222 FLAG(defaultedCopyConstructorIsDeleted
, defaulted_is_deleted
);
2223 FLAG(implicitCopyConstructorHasConstParam
, implicit_has_const_param
);
2228 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2229 OS
<< "MoveConstructor";
2231 FLAG(hasMoveConstructor
, exists
);
2232 FLAG(hasSimpleMoveConstructor
, simple
);
2233 FLAG(hasTrivialMoveConstructor
, trivial
);
2234 FLAG(hasNonTrivialMoveConstructor
, non_trivial
);
2235 FLAG(hasUserDeclaredMoveConstructor
, user_declared
);
2236 FLAG(needsImplicitMoveConstructor
, needs_implicit
);
2237 FLAG(needsOverloadResolutionForMoveConstructor
,
2238 needs_overload_resolution
);
2239 if (!D
->needsOverloadResolutionForMoveConstructor())
2240 FLAG(defaultedMoveConstructorIsDeleted
, defaulted_is_deleted
);
2245 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2246 OS
<< "CopyAssignment";
2248 FLAG(hasSimpleCopyAssignment
, simple
);
2249 FLAG(hasTrivialCopyAssignment
, trivial
);
2250 FLAG(hasNonTrivialCopyAssignment
, non_trivial
);
2251 FLAG(hasCopyAssignmentWithConstParam
, has_const_param
);
2252 FLAG(hasUserDeclaredCopyAssignment
, user_declared
);
2253 FLAG(needsImplicitCopyAssignment
, needs_implicit
);
2254 FLAG(needsOverloadResolutionForCopyAssignment
, needs_overload_resolution
);
2255 FLAG(implicitCopyAssignmentHasConstParam
, implicit_has_const_param
);
2260 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2261 OS
<< "MoveAssignment";
2263 FLAG(hasMoveAssignment
, exists
);
2264 FLAG(hasSimpleMoveAssignment
, simple
);
2265 FLAG(hasTrivialMoveAssignment
, trivial
);
2266 FLAG(hasNonTrivialMoveAssignment
, non_trivial
);
2267 FLAG(hasUserDeclaredMoveAssignment
, user_declared
);
2268 FLAG(needsImplicitMoveAssignment
, needs_implicit
);
2269 FLAG(needsOverloadResolutionForMoveAssignment
, needs_overload_resolution
);
2274 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2277 FLAG(hasSimpleDestructor
, simple
);
2278 FLAG(hasIrrelevantDestructor
, irrelevant
);
2279 FLAG(hasTrivialDestructor
, trivial
);
2280 FLAG(hasNonTrivialDestructor
, non_trivial
);
2281 FLAG(hasUserDeclaredDestructor
, user_declared
);
2282 FLAG(hasConstexprDestructor
, constexpr);
2283 FLAG(needsImplicitDestructor
, needs_implicit
);
2284 FLAG(needsOverloadResolutionForDestructor
, needs_overload_resolution
);
2285 if (!D
->needsOverloadResolutionForDestructor())
2286 FLAG(defaultedDestructorIsDeleted
, defaulted_is_deleted
);
2290 for (const auto &I
: D
->bases()) {
2294 dumpAccessSpecifier(I
.getAccessSpecifier());
2295 dumpType(I
.getType());
2296 if (I
.isPackExpansion())
2302 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl
*D
) {
2306 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl
*D
) {
2310 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl
*D
) {
2314 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl
*D
) {
2318 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl
*D
) {
2319 if (const auto *TC
= D
->getTypeConstraint()) {
2321 dumpBareDeclRef(TC
->getNamedConcept());
2322 if (TC
->getNamedConcept() != TC
->getFoundDecl()) {
2324 dumpBareDeclRef(TC
->getFoundDecl());
2327 } else if (D
->wasDeclaredWithTypename())
2331 OS
<< " depth " << D
->getDepth() << " index " << D
->getIndex();
2332 if (D
->isParameterPack())
2337 void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2338 const NonTypeTemplateParmDecl
*D
) {
2339 dumpType(D
->getType());
2340 OS
<< " depth " << D
->getDepth() << " index " << D
->getIndex();
2341 if (D
->isParameterPack())
2346 void TextNodeDumper::VisitTemplateTemplateParmDecl(
2347 const TemplateTemplateParmDecl
*D
) {
2348 OS
<< " depth " << D
->getDepth() << " index " << D
->getIndex();
2349 if (D
->isParameterPack())
2354 void TextNodeDumper::VisitUsingDecl(const UsingDecl
*D
) {
2356 if (D
->getQualifier())
2357 D
->getQualifier()->print(OS
, D
->getASTContext().getPrintingPolicy());
2358 OS
<< D
->getDeclName();
2359 dumpNestedNameSpecifier(D
->getQualifier());
2362 void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl
*D
) {
2364 dumpBareDeclRef(D
->getEnumDecl());
2367 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2368 const UnresolvedUsingTypenameDecl
*D
) {
2370 if (D
->getQualifier())
2371 D
->getQualifier()->print(OS
, D
->getASTContext().getPrintingPolicy());
2372 OS
<< D
->getDeclName();
2375 void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2376 const UnresolvedUsingValueDecl
*D
) {
2378 if (D
->getQualifier())
2379 D
->getQualifier()->print(OS
, D
->getASTContext().getPrintingPolicy());
2380 OS
<< D
->getDeclName();
2381 dumpType(D
->getType());
2384 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl
*D
) {
2386 dumpBareDeclRef(D
->getTargetDecl());
2389 void TextNodeDumper::VisitConstructorUsingShadowDecl(
2390 const ConstructorUsingShadowDecl
*D
) {
2391 if (D
->constructsVirtualBase())
2396 dumpBareDeclRef(D
->getTargetDecl());
2401 dumpBareDeclRef(D
->getNominatedBaseClass());
2403 dumpBareDeclRef(D
->getNominatedBaseClassShadowDecl());
2407 OS
<< "constructed ";
2408 dumpBareDeclRef(D
->getConstructedBaseClass());
2410 dumpBareDeclRef(D
->getConstructedBaseClassShadowDecl());
2414 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl
*D
) {
2415 switch (D
->getLanguage()) {
2416 case LinkageSpecLanguageIDs::C
:
2419 case LinkageSpecLanguageIDs::CXX
:
2425 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl
*D
) {
2427 dumpAccessSpecifier(D
->getAccess());
2430 void TextNodeDumper::VisitFriendDecl(const FriendDecl
*D
) {
2431 if (TypeSourceInfo
*T
= D
->getFriendType())
2432 dumpType(T
->getType());
2435 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl
*D
) {
2437 dumpType(D
->getType());
2438 if (D
->getSynthesize())
2439 OS
<< " synthesize";
2441 switch (D
->getAccessControl()) {
2442 case ObjCIvarDecl::None
:
2445 case ObjCIvarDecl::Private
:
2448 case ObjCIvarDecl::Protected
:
2451 case ObjCIvarDecl::Public
:
2454 case ObjCIvarDecl::Package
:
2460 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl
*D
) {
2461 if (D
->isInstanceMethod())
2466 dumpType(D
->getReturnType());
2468 if (D
->isVariadic())
2472 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl
*D
) {
2474 switch (D
->getVariance()) {
2475 case ObjCTypeParamVariance::Invariant
:
2478 case ObjCTypeParamVariance::Covariant
:
2482 case ObjCTypeParamVariance::Contravariant
:
2483 OS
<< " contravariant";
2487 if (D
->hasExplicitBound())
2489 dumpType(D
->getUnderlyingType());
2492 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl
*D
) {
2494 dumpDeclRef(D
->getClassInterface());
2495 dumpDeclRef(D
->getImplementation());
2496 for (const auto *P
: D
->protocols())
2500 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl
*D
) {
2502 dumpDeclRef(D
->getClassInterface());
2503 dumpDeclRef(D
->getCategoryDecl());
2506 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl
*D
) {
2509 for (const auto *Child
: D
->protocols())
2513 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl
*D
) {
2515 dumpDeclRef(D
->getSuperClass(), "super");
2517 dumpDeclRef(D
->getImplementation());
2518 for (const auto *Child
: D
->protocols())
2522 void TextNodeDumper::VisitObjCImplementationDecl(
2523 const ObjCImplementationDecl
*D
) {
2525 dumpDeclRef(D
->getSuperClass(), "super");
2526 dumpDeclRef(D
->getClassInterface());
2529 void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2530 const ObjCCompatibleAliasDecl
*D
) {
2532 dumpDeclRef(D
->getClassInterface());
2535 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl
*D
) {
2537 dumpType(D
->getType());
2539 if (D
->getPropertyImplementation() == ObjCPropertyDecl::Required
)
2541 else if (D
->getPropertyImplementation() == ObjCPropertyDecl::Optional
)
2544 ObjCPropertyAttribute::Kind Attrs
= D
->getPropertyAttributes();
2545 if (Attrs
!= ObjCPropertyAttribute::kind_noattr
) {
2546 if (Attrs
& ObjCPropertyAttribute::kind_readonly
)
2548 if (Attrs
& ObjCPropertyAttribute::kind_assign
)
2550 if (Attrs
& ObjCPropertyAttribute::kind_readwrite
)
2552 if (Attrs
& ObjCPropertyAttribute::kind_retain
)
2554 if (Attrs
& ObjCPropertyAttribute::kind_copy
)
2556 if (Attrs
& ObjCPropertyAttribute::kind_nonatomic
)
2558 if (Attrs
& ObjCPropertyAttribute::kind_atomic
)
2560 if (Attrs
& ObjCPropertyAttribute::kind_weak
)
2562 if (Attrs
& ObjCPropertyAttribute::kind_strong
)
2564 if (Attrs
& ObjCPropertyAttribute::kind_unsafe_unretained
)
2565 OS
<< " unsafe_unretained";
2566 if (Attrs
& ObjCPropertyAttribute::kind_class
)
2568 if (Attrs
& ObjCPropertyAttribute::kind_direct
)
2570 if (Attrs
& ObjCPropertyAttribute::kind_getter
)
2571 dumpDeclRef(D
->getGetterMethodDecl(), "getter");
2572 if (Attrs
& ObjCPropertyAttribute::kind_setter
)
2573 dumpDeclRef(D
->getSetterMethodDecl(), "setter");
2577 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl
*D
) {
2578 dumpName(D
->getPropertyDecl());
2579 if (D
->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize
)
2580 OS
<< " synthesize";
2583 dumpDeclRef(D
->getPropertyDecl());
2584 dumpDeclRef(D
->getPropertyIvarDecl());
2587 void TextNodeDumper::VisitBlockDecl(const BlockDecl
*D
) {
2588 if (D
->isVariadic())
2591 if (D
->capturesCXXThis())
2592 OS
<< " captures_this";
2595 void TextNodeDumper::VisitConceptDecl(const ConceptDecl
*D
) {
2599 void TextNodeDumper::VisitCompoundStmt(const CompoundStmt
*S
) {
2601 if (S
->hasStoredFPFeatures())
2602 printFPOptions(S
->getStoredFPFeatures());
2605 void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl
*D
) {