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/Type.h"
20 #include "clang/Basic/Module.h"
21 #include "clang/Basic/SourceManager.h"
22 #include "clang/Basic/Specifiers.h"
23 #include "clang/Basic/TypeTraits.h"
24 #include "llvm/ADT/StringExtras.h"
29 using namespace clang
;
31 static void dumpPreviousDeclImpl(raw_ostream
&OS
, ...) {}
34 static void dumpPreviousDeclImpl(raw_ostream
&OS
, const Mergeable
<T
> *D
) {
35 const T
*First
= D
->getFirstDecl();
37 OS
<< " first " << First
;
41 static void dumpPreviousDeclImpl(raw_ostream
&OS
, const Redeclarable
<T
> *D
) {
42 const T
*Prev
= D
->getPreviousDecl();
44 OS
<< " prev " << Prev
;
47 /// Dump the previous declaration in the redeclaration chain for a declaration,
49 static void dumpPreviousDecl(raw_ostream
&OS
, const Decl
*D
) {
50 switch (D
->getKind()) {
51 #define DECL(DERIVED, BASE) \
53 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
54 #define ABSTRACT_DECL(DECL)
55 #include "clang/AST/DeclNodes.inc"
57 llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
60 TextNodeDumper::TextNodeDumper(raw_ostream
&OS
, const ASTContext
&Context
,
62 : TextTreeStructure(OS
, ShowColors
), OS(OS
), ShowColors(ShowColors
),
63 Context(&Context
), SM(&Context
.getSourceManager()),
64 PrintPolicy(Context
.getPrintingPolicy()),
65 Traits(&Context
.getCommentCommandTraits()) {}
67 TextNodeDumper::TextNodeDumper(raw_ostream
&OS
, bool ShowColors
)
68 : TextTreeStructure(OS
, ShowColors
), OS(OS
), ShowColors(ShowColors
) {}
70 void TextNodeDumper::Visit(const comments::Comment
*C
,
71 const comments::FullComment
*FC
) {
73 ColorScope
Color(OS
, ShowColors
, NullColor
);
79 ColorScope
Color(OS
, ShowColors
, CommentColor
);
80 OS
<< C
->getCommentKindName();
83 dumpSourceRange(C
->getSourceRange());
85 ConstCommentVisitor
<TextNodeDumper
, void,
86 const comments::FullComment
*>::visit(C
, FC
);
89 void TextNodeDumper::Visit(const Attr
*A
) {
91 ColorScope
Color(OS
, ShowColors
, AttrColor
);
93 switch (A
->getKind()) {
98 #include "clang/Basic/AttrList.inc"
103 dumpSourceRange(A
->getRange());
104 if (A
->isInherited())
109 ConstAttrVisitor
<TextNodeDumper
>::Visit(A
);
112 void TextNodeDumper::Visit(const TemplateArgument
&TA
, SourceRange R
,
113 const Decl
*From
, StringRef Label
) {
114 OS
<< "TemplateArgument";
119 dumpDeclRef(From
, Label
);
121 ConstTemplateArgumentVisitor
<TextNodeDumper
>::Visit(TA
);
124 void TextNodeDumper::Visit(const Stmt
*Node
) {
126 ColorScope
Color(OS
, ShowColors
, NullColor
);
131 ColorScope
Color(OS
, ShowColors
, StmtColor
);
132 OS
<< Node
->getStmtClassName();
135 dumpSourceRange(Node
->getSourceRange());
137 if (const auto *E
= dyn_cast
<Expr
>(Node
)) {
138 dumpType(E
->getType());
140 if (E
->containsErrors()) {
141 ColorScope
Color(OS
, ShowColors
, ErrorsColor
);
142 OS
<< " contains-errors";
146 ColorScope
Color(OS
, ShowColors
, ValueKindColor
);
147 switch (E
->getValueKind()) {
160 ColorScope
Color(OS
, ShowColors
, ObjectKindColor
);
161 switch (E
->getObjectKind()) {
167 case OK_ObjCProperty
:
168 OS
<< " objcproperty";
170 case OK_ObjCSubscript
:
171 OS
<< " objcsubscript";
173 case OK_VectorComponent
:
174 OS
<< " vectorcomponent";
176 case OK_MatrixComponent
:
177 OS
<< " matrixcomponent";
183 ConstStmtVisitor
<TextNodeDumper
>::Visit(Node
);
186 void TextNodeDumper::Visit(const Type
*T
) {
188 ColorScope
Color(OS
, ShowColors
, NullColor
);
192 if (isa
<LocInfoType
>(T
)) {
194 ColorScope
Color(OS
, ShowColors
, TypeColor
);
195 OS
<< "LocInfo Type";
202 ColorScope
Color(OS
, ShowColors
, TypeColor
);
203 OS
<< T
->getTypeClassName() << "Type";
207 dumpBareType(QualType(T
, 0), false);
209 QualType SingleStepDesugar
=
210 T
->getLocallyUnqualifiedSingleStepDesugaredType();
211 if (SingleStepDesugar
!= QualType(T
, 0))
214 if (T
->containsErrors()) {
215 ColorScope
Color(OS
, ShowColors
, ErrorsColor
);
216 OS
<< " contains-errors";
219 if (T
->isDependentType())
221 else if (T
->isInstantiationDependentType())
222 OS
<< " instantiation_dependent";
224 if (T
->isVariablyModifiedType())
225 OS
<< " variably_modified";
226 if (T
->containsUnexpandedParameterPack())
227 OS
<< " contains_unexpanded_pack";
231 TypeVisitor
<TextNodeDumper
>::Visit(T
);
234 void TextNodeDumper::Visit(QualType T
) {
236 dumpPointer(T
.getAsOpaquePtr());
238 dumpBareType(T
, false);
239 OS
<< " " << T
.split().Quals
.getAsString();
242 void TextNodeDumper::Visit(const Decl
*D
) {
244 ColorScope
Color(OS
, ShowColors
, NullColor
);
250 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
251 OS
<< D
->getDeclKindName() << "Decl";
254 if (D
->getLexicalDeclContext() != D
->getDeclContext())
255 OS
<< " parent " << cast
<Decl
>(D
->getDeclContext());
256 dumpPreviousDecl(OS
, D
);
257 dumpSourceRange(D
->getSourceRange());
259 dumpLocation(D
->getLocation());
260 if (D
->isFromASTFile())
262 if (Module
*M
= D
->getOwningModule())
263 OS
<< " in " << M
->getFullModuleName();
264 if (auto *ND
= dyn_cast
<NamedDecl
>(D
))
265 for (Module
*M
: D
->getASTContext().getModulesWithMergedDefinition(
266 const_cast<NamedDecl
*>(ND
)))
267 AddChild([=] { OS
<< "also in " << M
->getFullModuleName(); });
268 if (const NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
))
269 if (!ND
->isUnconditionallyVisible())
276 else if (D
->isThisDeclarationReferenced())
279 if (D
->isInvalidDecl())
281 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
282 if (FD
->isConstexprSpecified())
284 if (FD
->isConsteval())
286 if (FD
->isMultiVersion())
287 OS
<< " multiversion";
290 if (!isa
<FunctionDecl
>(*D
)) {
291 const auto *MD
= dyn_cast
<ObjCMethodDecl
>(D
);
292 if (!MD
|| !MD
->isThisDeclarationADefinition()) {
293 const auto *DC
= dyn_cast
<DeclContext
>(D
);
294 if (DC
&& DC
->hasExternalLexicalStorage()) {
295 ColorScope
Color(OS
, ShowColors
, UndeserializedColor
);
296 OS
<< " <undeserialized declarations>";
301 ConstDeclVisitor
<TextNodeDumper
>::Visit(D
);
304 void TextNodeDumper::Visit(const CXXCtorInitializer
*Init
) {
305 OS
<< "CXXCtorInitializer";
306 if (Init
->isAnyMemberInitializer()) {
308 dumpBareDeclRef(Init
->getAnyMember());
309 } else if (Init
->isBaseInitializer()) {
310 dumpType(QualType(Init
->getBaseClass(), 0));
311 } else if (Init
->isDelegatingInitializer()) {
312 dumpType(Init
->getTypeSourceInfo()->getType());
314 llvm_unreachable("Unknown initializer type");
318 void TextNodeDumper::Visit(const BlockDecl::Capture
&C
) {
324 if (C
.getVariable()) {
326 dumpBareDeclRef(C
.getVariable());
330 void TextNodeDumper::Visit(const OMPClause
*C
) {
332 ColorScope
Color(OS
, ShowColors
, NullColor
);
333 OS
<< "<<<NULL>>> OMPClause";
337 ColorScope
Color(OS
, ShowColors
, AttrColor
);
338 StringRef
ClauseName(llvm::omp::getOpenMPClauseName(C
->getClauseKind()));
339 OS
<< "OMP" << ClauseName
.substr(/*Start=*/0, /*N=*/1).upper()
340 << ClauseName
.drop_front() << "Clause";
343 dumpSourceRange(SourceRange(C
->getBeginLoc(), C
->getEndLoc()));
348 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation
&A
) {
349 const TypeSourceInfo
*TSI
= A
.getTypeSourceInfo();
352 dumpType(TSI
->getType());
361 void TextNodeDumper::Visit(const concepts::Requirement
*R
) {
363 ColorScope
Color(OS
, ShowColors
, NullColor
);
364 OS
<< "<<<NULL>>> Requirement";
369 ColorScope
Color(OS
, ShowColors
, StmtColor
);
370 switch (R
->getKind()) {
371 case concepts::Requirement::RK_Type
:
372 OS
<< "TypeRequirement";
374 case concepts::Requirement::RK_Simple
:
375 OS
<< "SimpleRequirement";
377 case concepts::Requirement::RK_Compound
:
378 OS
<< "CompoundRequirement";
380 case concepts::Requirement::RK_Nested
:
381 OS
<< "NestedRequirement";
388 if (auto *ER
= dyn_cast
<concepts::ExprRequirement
>(R
)) {
389 if (ER
->hasNoexceptRequirement())
393 if (R
->isDependent())
396 OS
<< (R
->isSatisfied() ? " satisfied" : " unsatisfied");
397 if (R
->containsUnexpandedParameterPack())
398 OS
<< " contains_unexpanded_pack";
401 static double GetApproxValue(const llvm::APFloat
&F
) {
404 V
.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven
,
406 return V
.convertToDouble();
409 /// True if the \p APValue \p Value can be folded onto the current line.
410 static bool isSimpleAPValue(const APValue
&Value
) {
411 switch (Value
.getKind()) {
413 case APValue::Indeterminate
:
416 case APValue::FixedPoint
:
417 case APValue::ComplexInt
:
418 case APValue::ComplexFloat
:
419 case APValue::LValue
:
420 case APValue::MemberPointer
:
421 case APValue::AddrLabelDiff
:
423 case APValue::Vector
:
425 case APValue::Struct
:
428 return isSimpleAPValue(Value
.getUnionValue());
430 llvm_unreachable("unexpected APValue kind!");
433 /// Dump the children of the \p APValue \p Value.
435 /// \param[in] Value The \p APValue to visit
436 /// \param[in] Ty The \p QualType passed to \p Visit
438 /// \param[in] IdxToChildFun A function mapping an \p APValue and an index
439 /// to one of the child of the \p APValue
441 /// \param[in] NumChildren \p IdxToChildFun will be called on \p Value with
442 /// the indices in the range \p [0,NumChildren(
444 /// \param[in] LabelSingular The label to use on a line with a single child
445 /// \param[in] LabelPlurial The label to use on a line with multiple children
446 void TextNodeDumper::dumpAPValueChildren(
447 const APValue
&Value
, QualType Ty
,
448 const APValue
&(*IdxToChildFun
)(const APValue
&, unsigned),
449 unsigned NumChildren
, StringRef LabelSingular
, StringRef LabelPlurial
) {
450 // To save some vertical space we print up to MaxChildrenPerLine APValues
451 // considered to be simple (by isSimpleAPValue) on a single line.
452 constexpr unsigned MaxChildrenPerLine
= 4;
454 while (I
< NumChildren
) {
456 while (J
< NumChildren
) {
457 if (isSimpleAPValue(IdxToChildFun(Value
, J
)) &&
458 (J
- I
< MaxChildrenPerLine
)) {
465 J
= std::max(I
+ 1, J
);
467 // Print [I,J) on a single line.
468 AddChild(J
- I
> 1 ? LabelPlurial
: LabelSingular
, [=]() {
469 for (unsigned X
= I
; X
< J
; ++X
) {
470 Visit(IdxToChildFun(Value
, X
), Ty
);
479 void TextNodeDumper::Visit(const APValue
&Value
, QualType Ty
) {
480 ColorScope
Color(OS
, ShowColors
, ValueKindColor
);
481 switch (Value
.getKind()) {
485 case APValue::Indeterminate
:
486 OS
<< "Indeterminate";
491 ColorScope
Color(OS
, ShowColors
, ValueColor
);
492 OS
<< Value
.getInt();
498 ColorScope
Color(OS
, ShowColors
, ValueColor
);
499 OS
<< GetApproxValue(Value
.getFloat());
502 case APValue::FixedPoint
:
505 ColorScope
Color(OS
, ShowColors
, ValueColor
);
506 OS
<< Value
.getFixedPoint();
509 case APValue::Vector
: {
510 unsigned VectorLength
= Value
.getVectorLength();
511 OS
<< "Vector length=" << VectorLength
;
515 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
516 return Value
.getVectorElt(Index
);
518 VectorLength
, "element", "elements");
521 case APValue::ComplexInt
:
524 ColorScope
Color(OS
, ShowColors
, ValueColor
);
525 OS
<< Value
.getComplexIntReal() << " + " << Value
.getComplexIntImag()
529 case APValue::ComplexFloat
:
530 OS
<< "ComplexFloat ";
532 ColorScope
Color(OS
, ShowColors
, ValueColor
);
533 OS
<< GetApproxValue(Value
.getComplexFloatReal()) << " + "
534 << GetApproxValue(Value
.getComplexFloatImag()) << 'i';
537 case APValue::LValue
:
539 OS
<< "LValue <todo>";
541 case APValue::Array
: {
542 unsigned ArraySize
= Value
.getArraySize();
543 unsigned NumInitializedElements
= Value
.getArrayInitializedElts();
544 OS
<< "Array size=" << ArraySize
;
548 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
549 return Value
.getArrayInitializedElt(Index
);
551 NumInitializedElements
, "element", "elements");
553 if (Value
.hasArrayFiller()) {
554 AddChild("filler", [=] {
556 ColorScope
Color(OS
, ShowColors
, ValueColor
);
557 OS
<< ArraySize
- NumInitializedElements
<< " x ";
559 Visit(Value
.getArrayFiller(), Ty
);
565 case APValue::Struct
: {
570 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
571 return Value
.getStructBase(Index
);
573 Value
.getStructNumBases(), "base", "bases");
577 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
578 return Value
.getStructField(Index
);
580 Value
.getStructNumFields(), "field", "fields");
584 case APValue::Union
: {
587 ColorScope
Color(OS
, ShowColors
, ValueColor
);
588 if (const FieldDecl
*FD
= Value
.getUnionField())
589 OS
<< " ." << *cast
<NamedDecl
>(FD
);
591 // If the union value is considered to be simple, fold it into the
592 // current line to save some vertical space.
593 const APValue
&UnionValue
= Value
.getUnionValue();
594 if (isSimpleAPValue(UnionValue
)) {
596 Visit(UnionValue
, Ty
);
598 AddChild([=] { Visit(UnionValue
, Ty
); });
603 case APValue::MemberPointer
:
604 OS
<< "MemberPointer <todo>";
606 case APValue::AddrLabelDiff
:
607 OS
<< "AddrLabelDiff <todo>";
610 llvm_unreachable("Unknown APValue kind!");
613 void TextNodeDumper::dumpPointer(const void *Ptr
) {
614 ColorScope
Color(OS
, ShowColors
, AddressColor
);
618 void TextNodeDumper::dumpLocation(SourceLocation Loc
) {
622 ColorScope
Color(OS
, ShowColors
, LocationColor
);
623 SourceLocation SpellingLoc
= SM
->getSpellingLoc(Loc
);
625 // The general format we print out is filename:line:col, but we drop pieces
626 // that haven't changed since the last loc printed.
627 PresumedLoc PLoc
= SM
->getPresumedLoc(SpellingLoc
);
629 if (PLoc
.isInvalid()) {
630 OS
<< "<invalid sloc>";
634 if (strcmp(PLoc
.getFilename(), LastLocFilename
) != 0) {
635 OS
<< PLoc
.getFilename() << ':' << PLoc
.getLine() << ':'
637 LastLocFilename
= PLoc
.getFilename();
638 LastLocLine
= PLoc
.getLine();
639 } else if (PLoc
.getLine() != LastLocLine
) {
640 OS
<< "line" << ':' << PLoc
.getLine() << ':' << PLoc
.getColumn();
641 LastLocLine
= PLoc
.getLine();
643 OS
<< "col" << ':' << PLoc
.getColumn();
647 void TextNodeDumper::dumpSourceRange(SourceRange R
) {
648 // Can't translate locations if a SourceManager isn't available.
653 dumpLocation(R
.getBegin());
654 if (R
.getBegin() != R
.getEnd()) {
656 dumpLocation(R
.getEnd());
660 // <t2.c:123:421[blah], t2.c:412:321>
663 void TextNodeDumper::dumpBareType(QualType T
, bool Desugar
) {
664 ColorScope
Color(OS
, ShowColors
, TypeColor
);
666 SplitQualType T_split
= T
.split();
667 OS
<< "'" << QualType::getAsString(T_split
, PrintPolicy
) << "'";
669 if (Desugar
&& !T
.isNull()) {
670 // If the type is sugared, also dump a (shallow) desugared type.
671 SplitQualType D_split
= T
.getSplitDesugaredType();
672 if (T_split
!= D_split
)
673 OS
<< ":'" << QualType::getAsString(D_split
, PrintPolicy
) << "'";
677 void TextNodeDumper::dumpType(QualType T
) {
682 void TextNodeDumper::dumpBareDeclRef(const Decl
*D
) {
684 ColorScope
Color(OS
, ShowColors
, NullColor
);
690 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
691 OS
<< D
->getDeclKindName();
695 if (const NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
)) {
696 ColorScope
Color(OS
, ShowColors
, DeclNameColor
);
697 OS
<< " '" << ND
->getDeclName() << '\'';
700 if (const ValueDecl
*VD
= dyn_cast
<ValueDecl
>(D
))
701 dumpType(VD
->getType());
704 void TextNodeDumper::dumpName(const NamedDecl
*ND
) {
705 if (ND
->getDeclName()) {
706 ColorScope
Color(OS
, ShowColors
, DeclNameColor
);
707 OS
<< ' ' << ND
->getDeclName();
711 void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS
) {
712 const auto AccessSpelling
= getAccessSpelling(AS
);
713 if (AccessSpelling
.empty())
715 OS
<< AccessSpelling
;
718 void TextNodeDumper::dumpCleanupObject(
719 const ExprWithCleanups::CleanupObject
&C
) {
720 if (auto *BD
= C
.dyn_cast
<BlockDecl
*>())
721 dumpDeclRef(BD
, "cleanup");
722 else if (auto *CLE
= C
.dyn_cast
<CompoundLiteralExpr
*>())
726 ColorScope
Color(OS
, ShowColors
, StmtColor
);
727 OS
<< CLE
->getStmtClassName();
732 llvm_unreachable("unexpected cleanup type");
735 void TextNodeDumper::dumpDeclRef(const Decl
*D
, StringRef Label
) {
746 const char *TextNodeDumper::getCommandName(unsigned CommandID
) {
748 return Traits
->getCommandInfo(CommandID
)->Name
;
749 const comments::CommandInfo
*Info
=
750 comments::CommandTraits::getBuiltinCommandInfo(CommandID
);
753 return "<not a builtin command>";
756 void TextNodeDumper::printFPOptions(FPOptionsOverride FPO
) {
757 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
758 if (FPO.has##NAME##Override()) \
759 OS << " " #NAME "=" << FPO.get##NAME##Override();
760 #include "clang/Basic/FPOptions.def"
763 void TextNodeDumper::visitTextComment(const comments::TextComment
*C
,
764 const comments::FullComment
*) {
765 OS
<< " Text=\"" << C
->getText() << "\"";
768 void TextNodeDumper::visitInlineCommandComment(
769 const comments::InlineCommandComment
*C
, const comments::FullComment
*) {
770 OS
<< " Name=\"" << getCommandName(C
->getCommandID()) << "\"";
771 switch (C
->getRenderKind()) {
772 case comments::InlineCommandComment::RenderNormal
:
773 OS
<< " RenderNormal";
775 case comments::InlineCommandComment::RenderBold
:
778 case comments::InlineCommandComment::RenderMonospaced
:
779 OS
<< " RenderMonospaced";
781 case comments::InlineCommandComment::RenderEmphasized
:
782 OS
<< " RenderEmphasized";
784 case comments::InlineCommandComment::RenderAnchor
:
785 OS
<< " RenderAnchor";
789 for (unsigned i
= 0, e
= C
->getNumArgs(); i
!= e
; ++i
)
790 OS
<< " Arg[" << i
<< "]=\"" << C
->getArgText(i
) << "\"";
793 void TextNodeDumper::visitHTMLStartTagComment(
794 const comments::HTMLStartTagComment
*C
, const comments::FullComment
*) {
795 OS
<< " Name=\"" << C
->getTagName() << "\"";
796 if (C
->getNumAttrs() != 0) {
798 for (unsigned i
= 0, e
= C
->getNumAttrs(); i
!= e
; ++i
) {
799 const comments::HTMLStartTagComment::Attribute
&Attr
= C
->getAttr(i
);
800 OS
<< " \"" << Attr
.Name
<< "=\"" << Attr
.Value
<< "\"";
803 if (C
->isSelfClosing())
804 OS
<< " SelfClosing";
807 void TextNodeDumper::visitHTMLEndTagComment(
808 const comments::HTMLEndTagComment
*C
, const comments::FullComment
*) {
809 OS
<< " Name=\"" << C
->getTagName() << "\"";
812 void TextNodeDumper::visitBlockCommandComment(
813 const comments::BlockCommandComment
*C
, const comments::FullComment
*) {
814 OS
<< " Name=\"" << getCommandName(C
->getCommandID()) << "\"";
815 for (unsigned i
= 0, e
= C
->getNumArgs(); i
!= e
; ++i
)
816 OS
<< " Arg[" << i
<< "]=\"" << C
->getArgText(i
) << "\"";
819 void TextNodeDumper::visitParamCommandComment(
820 const comments::ParamCommandComment
*C
, const comments::FullComment
*FC
) {
822 << comments::ParamCommandComment::getDirectionAsString(C
->getDirection());
824 if (C
->isDirectionExplicit())
829 if (C
->hasParamName()) {
830 if (C
->isParamIndexValid())
831 OS
<< " Param=\"" << C
->getParamName(FC
) << "\"";
833 OS
<< " Param=\"" << C
->getParamNameAsWritten() << "\"";
836 if (C
->isParamIndexValid() && !C
->isVarArgParam())
837 OS
<< " ParamIndex=" << C
->getParamIndex();
840 void TextNodeDumper::visitTParamCommandComment(
841 const comments::TParamCommandComment
*C
, const comments::FullComment
*FC
) {
842 if (C
->hasParamName()) {
843 if (C
->isPositionValid())
844 OS
<< " Param=\"" << C
->getParamName(FC
) << "\"";
846 OS
<< " Param=\"" << C
->getParamNameAsWritten() << "\"";
849 if (C
->isPositionValid()) {
851 for (unsigned i
= 0, e
= C
->getDepth(); i
!= e
; ++i
) {
852 OS
<< C
->getIndex(i
);
860 void TextNodeDumper::visitVerbatimBlockComment(
861 const comments::VerbatimBlockComment
*C
, const comments::FullComment
*) {
862 OS
<< " Name=\"" << getCommandName(C
->getCommandID())
865 << C
->getCloseName() << "\"";
868 void TextNodeDumper::visitVerbatimBlockLineComment(
869 const comments::VerbatimBlockLineComment
*C
,
870 const comments::FullComment
*) {
871 OS
<< " Text=\"" << C
->getText() << "\"";
874 void TextNodeDumper::visitVerbatimLineComment(
875 const comments::VerbatimLineComment
*C
, const comments::FullComment
*) {
876 OS
<< " Text=\"" << C
->getText() << "\"";
879 void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument
&) {
883 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument
&TA
) {
885 dumpType(TA
.getAsType());
888 void TextNodeDumper::VisitDeclarationTemplateArgument(
889 const TemplateArgument
&TA
) {
891 dumpDeclRef(TA
.getAsDecl());
894 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument
&) {
898 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument
&TA
) {
899 OS
<< " integral " << TA
.getAsIntegral();
902 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument
&TA
) {
903 if (TA
.getAsTemplate().getKind() == TemplateName::UsingTemplate
)
906 TA
.getAsTemplate().dump(OS
);
909 void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
910 const TemplateArgument
&TA
) {
911 if (TA
.getAsTemplateOrTemplatePattern().getKind() ==
912 TemplateName::UsingTemplate
)
914 OS
<< " template expansion ";
915 TA
.getAsTemplateOrTemplatePattern().dump(OS
);
918 void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument
&) {
922 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument
&) {
926 static void dumpBasePath(raw_ostream
&OS
, const CastExpr
*Node
) {
927 if (Node
->path_empty())
932 for (CastExpr::path_const_iterator I
= Node
->path_begin(),
933 E
= Node
->path_end();
935 const CXXBaseSpecifier
*Base
= *I
;
940 cast
<CXXRecordDecl
>(Base
->getType()->castAs
<RecordType
>()->getDecl());
942 if (Base
->isVirtual())
951 void TextNodeDumper::VisitIfStmt(const IfStmt
*Node
) {
952 if (Node
->hasInitStorage())
954 if (Node
->hasVarStorage())
956 if (Node
->hasElseStorage())
958 if (Node
->isConstexpr())
960 if (Node
->isConsteval()) {
962 if (Node
->isNegatedConsteval())
968 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt
*Node
) {
969 if (Node
->hasInitStorage())
971 if (Node
->hasVarStorage())
975 void TextNodeDumper::VisitWhileStmt(const WhileStmt
*Node
) {
976 if (Node
->hasVarStorage())
980 void TextNodeDumper::VisitLabelStmt(const LabelStmt
*Node
) {
981 OS
<< " '" << Node
->getName() << "'";
982 if (Node
->isSideEntry())
986 void TextNodeDumper::VisitGotoStmt(const GotoStmt
*Node
) {
987 OS
<< " '" << Node
->getLabel()->getName() << "'";
988 dumpPointer(Node
->getLabel());
991 void TextNodeDumper::VisitCaseStmt(const CaseStmt
*Node
) {
992 if (Node
->caseStmtIsGNURange())
996 void TextNodeDumper::VisitConstantExpr(const ConstantExpr
*Node
) {
997 if (Node
->hasAPValueResult())
999 [=] { Visit(Node
->getAPValueResult(), Node
->getType()); });
1002 void TextNodeDumper::VisitCallExpr(const CallExpr
*Node
) {
1003 if (Node
->usesADL())
1005 if (Node
->hasStoredFPFeatures())
1006 printFPOptions(Node
->getFPFeatures());
1009 void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr
*Node
) {
1010 const char *OperatorSpelling
= clang::getOperatorSpelling(Node
->getOperator());
1011 if (OperatorSpelling
)
1012 OS
<< " '" << OperatorSpelling
<< "'";
1014 VisitCallExpr(Node
);
1017 void TextNodeDumper::VisitCastExpr(const CastExpr
*Node
) {
1020 ColorScope
Color(OS
, ShowColors
, CastColor
);
1021 OS
<< Node
->getCastKindName();
1023 dumpBasePath(OS
, Node
);
1025 if (Node
->hasStoredFPFeatures())
1026 printFPOptions(Node
->getFPFeatures());
1029 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr
*Node
) {
1030 VisitCastExpr(Node
);
1031 if (Node
->isPartOfExplicitCast())
1032 OS
<< " part_of_explicit_cast";
1035 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr
*Node
) {
1037 dumpBareDeclRef(Node
->getDecl());
1038 if (Node
->getDecl() != Node
->getFoundDecl()) {
1040 dumpBareDeclRef(Node
->getFoundDecl());
1043 switch (Node
->isNonOdrUse()) {
1044 case NOUR_None
: break;
1045 case NOUR_Unevaluated
: OS
<< " non_odr_use_unevaluated"; break;
1046 case NOUR_Constant
: OS
<< " non_odr_use_constant"; break;
1047 case NOUR_Discarded
: OS
<< " non_odr_use_discarded"; break;
1051 void TextNodeDumper::VisitUnresolvedLookupExpr(
1052 const UnresolvedLookupExpr
*Node
) {
1054 if (!Node
->requiresADL())
1056 OS
<< "ADL) = '" << Node
->getName() << '\'';
1058 UnresolvedLookupExpr::decls_iterator I
= Node
->decls_begin(),
1059 E
= Node
->decls_end();
1066 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr
*Node
) {
1068 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
1069 OS
<< " " << Node
->getDecl()->getDeclKindName() << "Decl";
1071 OS
<< "='" << *Node
->getDecl() << "'";
1072 dumpPointer(Node
->getDecl());
1073 if (Node
->isFreeIvar())
1074 OS
<< " isFreeIvar";
1077 void TextNodeDumper::VisitSYCLUniqueStableNameExpr(
1078 const SYCLUniqueStableNameExpr
*Node
) {
1079 dumpType(Node
->getTypeSourceInfo()->getType());
1082 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr
*Node
) {
1083 OS
<< " " << PredefinedExpr::getIdentKindName(Node
->getIdentKind());
1086 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral
*Node
) {
1087 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1088 OS
<< " " << Node
->getValue();
1091 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral
*Node
) {
1092 bool isSigned
= Node
->getType()->isSignedIntegerType();
1093 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1094 OS
<< " " << toString(Node
->getValue(), 10, isSigned
);
1097 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral
*Node
) {
1098 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1099 OS
<< " " << Node
->getValueAsString(/*Radix=*/10);
1102 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral
*Node
) {
1103 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1104 OS
<< " " << Node
->getValueAsApproximateDouble();
1107 void TextNodeDumper::VisitStringLiteral(const StringLiteral
*Str
) {
1108 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1110 Str
->outputString(OS
);
1113 void TextNodeDumper::VisitInitListExpr(const InitListExpr
*ILE
) {
1114 if (auto *Field
= ILE
->getInitializedFieldInUnion()) {
1116 dumpBareDeclRef(Field
);
1120 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr
*E
) {
1121 if (E
->isResultDependent())
1122 OS
<< " result_dependent";
1125 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator
*Node
) {
1126 OS
<< " " << (Node
->isPostfix() ? "postfix" : "prefix") << " '"
1127 << UnaryOperator::getOpcodeStr(Node
->getOpcode()) << "'";
1128 if (!Node
->canOverflow())
1129 OS
<< " cannot overflow";
1130 if (Node
->hasStoredFPFeatures())
1131 printFPOptions(Node
->getStoredFPFeatures());
1134 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1135 const UnaryExprOrTypeTraitExpr
*Node
) {
1136 OS
<< " " << getTraitSpelling(Node
->getKind());
1138 if (Node
->isArgumentType())
1139 dumpType(Node
->getArgumentType());
1142 void TextNodeDumper::VisitMemberExpr(const MemberExpr
*Node
) {
1143 OS
<< " " << (Node
->isArrow() ? "->" : ".") << *Node
->getMemberDecl();
1144 dumpPointer(Node
->getMemberDecl());
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;
1153 void TextNodeDumper::VisitExtVectorElementExpr(
1154 const ExtVectorElementExpr
*Node
) {
1155 OS
<< " " << Node
->getAccessor().getNameStart();
1158 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator
*Node
) {
1159 OS
<< " '" << BinaryOperator::getOpcodeStr(Node
->getOpcode()) << "'";
1160 if (Node
->hasStoredFPFeatures())
1161 printFPOptions(Node
->getStoredFPFeatures());
1164 void TextNodeDumper::VisitCompoundAssignOperator(
1165 const CompoundAssignOperator
*Node
) {
1166 OS
<< " '" << BinaryOperator::getOpcodeStr(Node
->getOpcode())
1167 << "' ComputeLHSTy=";
1168 dumpBareType(Node
->getComputationLHSType());
1169 OS
<< " ComputeResultTy=";
1170 dumpBareType(Node
->getComputationResultType());
1171 if (Node
->hasStoredFPFeatures())
1172 printFPOptions(Node
->getStoredFPFeatures());
1175 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr
*Node
) {
1176 OS
<< " " << Node
->getLabel()->getName();
1177 dumpPointer(Node
->getLabel());
1180 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr
*Node
) {
1181 OS
<< " " << Node
->getCastName() << "<"
1182 << Node
->getTypeAsWritten().getAsString() << ">"
1183 << " <" << Node
->getCastKindName();
1184 dumpBasePath(OS
, Node
);
1188 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr
*Node
) {
1189 OS
<< " " << (Node
->getValue() ? "true" : "false");
1192 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr
*Node
) {
1193 if (Node
->isImplicit())
1198 void TextNodeDumper::VisitCXXFunctionalCastExpr(
1199 const CXXFunctionalCastExpr
*Node
) {
1200 OS
<< " functional cast to " << Node
->getTypeAsWritten().getAsString() << " <"
1201 << Node
->getCastKindName() << ">";
1202 if (Node
->hasStoredFPFeatures())
1203 printFPOptions(Node
->getFPFeatures());
1206 void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr
*Node
) {
1207 VisitCXXNamedCastExpr(Node
);
1208 if (Node
->hasStoredFPFeatures())
1209 printFPOptions(Node
->getFPFeatures());
1212 void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
1213 const CXXUnresolvedConstructExpr
*Node
) {
1214 dumpType(Node
->getTypeAsWritten());
1215 if (Node
->isListInitialization())
1219 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr
*Node
) {
1220 CXXConstructorDecl
*Ctor
= Node
->getConstructor();
1221 dumpType(Ctor
->getType());
1222 if (Node
->isElidable())
1224 if (Node
->isListInitialization())
1226 if (Node
->isStdInitListInitialization())
1227 OS
<< " std::initializer_list";
1228 if (Node
->requiresZeroInitialization())
1232 void TextNodeDumper::VisitCXXBindTemporaryExpr(
1233 const CXXBindTemporaryExpr
*Node
) {
1234 OS
<< " (CXXTemporary";
1239 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr
*Node
) {
1240 if (Node
->isGlobalNew())
1242 if (Node
->isArray())
1244 if (Node
->getOperatorNew()) {
1246 dumpBareDeclRef(Node
->getOperatorNew());
1248 // We could dump the deallocation function used in case of error, but it's
1249 // usually not that interesting.
1252 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr
*Node
) {
1253 if (Node
->isGlobalDelete())
1255 if (Node
->isArrayForm())
1257 if (Node
->getOperatorDelete()) {
1259 dumpBareDeclRef(Node
->getOperatorDelete());
1263 void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr
*Node
) {
1264 OS
<< " " << getTraitSpelling(Node
->getTrait());
1267 void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr
*Node
) {
1268 OS
<< " " << getTraitSpelling(Node
->getTrait());
1271 void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr
*Node
) {
1272 OS
<< " " << getTraitSpelling(Node
->getTrait());
1275 void TextNodeDumper::VisitMaterializeTemporaryExpr(
1276 const MaterializeTemporaryExpr
*Node
) {
1277 if (const ValueDecl
*VD
= Node
->getExtendingDecl()) {
1278 OS
<< " extended by ";
1279 dumpBareDeclRef(VD
);
1283 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups
*Node
) {
1284 for (unsigned i
= 0, e
= Node
->getNumObjects(); i
!= e
; ++i
)
1285 dumpCleanupObject(Node
->getObject(i
));
1288 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr
*Node
) {
1289 dumpPointer(Node
->getPack());
1290 dumpName(Node
->getPack());
1293 void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
1294 const CXXDependentScopeMemberExpr
*Node
) {
1295 OS
<< " " << (Node
->isArrow() ? "->" : ".") << Node
->getMember();
1298 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr
*Node
) {
1300 Node
->getSelector().print(OS
);
1301 switch (Node
->getReceiverKind()) {
1302 case ObjCMessageExpr::Instance
:
1305 case ObjCMessageExpr::Class
:
1307 dumpBareType(Node
->getClassReceiver());
1310 case ObjCMessageExpr::SuperInstance
:
1311 OS
<< " super (instance)";
1314 case ObjCMessageExpr::SuperClass
:
1315 OS
<< " super (class)";
1320 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr
*Node
) {
1321 if (auto *BoxingMethod
= Node
->getBoxingMethod()) {
1323 BoxingMethod
->getSelector().print(OS
);
1327 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt
*Node
) {
1328 if (!Node
->getCatchParamDecl())
1332 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr
*Node
) {
1333 dumpType(Node
->getEncodedType());
1336 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr
*Node
) {
1338 Node
->getSelector().print(OS
);
1341 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr
*Node
) {
1342 OS
<< ' ' << *Node
->getProtocol();
1345 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr
*Node
) {
1346 if (Node
->isImplicitProperty()) {
1347 OS
<< " Kind=MethodRef Getter=\"";
1348 if (Node
->getImplicitPropertyGetter())
1349 Node
->getImplicitPropertyGetter()->getSelector().print(OS
);
1353 OS
<< "\" Setter=\"";
1354 if (ObjCMethodDecl
*Setter
= Node
->getImplicitPropertySetter())
1355 Setter
->getSelector().print(OS
);
1360 OS
<< " Kind=PropertyRef Property=\"" << *Node
->getExplicitProperty()
1364 if (Node
->isSuperReceiver())
1367 OS
<< " Messaging=";
1368 if (Node
->isMessagingGetter() && Node
->isMessagingSetter())
1369 OS
<< "Getter&Setter";
1370 else if (Node
->isMessagingGetter())
1372 else if (Node
->isMessagingSetter())
1376 void TextNodeDumper::VisitObjCSubscriptRefExpr(
1377 const ObjCSubscriptRefExpr
*Node
) {
1378 if (Node
->isArraySubscriptRefExpr())
1379 OS
<< " Kind=ArraySubscript GetterForArray=\"";
1381 OS
<< " Kind=DictionarySubscript GetterForDictionary=\"";
1382 if (Node
->getAtIndexMethodDecl())
1383 Node
->getAtIndexMethodDecl()->getSelector().print(OS
);
1387 if (Node
->isArraySubscriptRefExpr())
1388 OS
<< "\" SetterForArray=\"";
1390 OS
<< "\" SetterForDictionary=\"";
1391 if (Node
->setAtIndexMethodDecl())
1392 Node
->setAtIndexMethodDecl()->getSelector().print(OS
);
1397 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr
*Node
) {
1398 OS
<< " " << (Node
->getValue() ? "__objc_yes" : "__objc_no");
1401 void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr
*Node
) {
1403 for (unsigned I
= 0, E
= Node
->numOfIterators(); I
< E
; ++I
) {
1404 Visit(Node
->getIteratorDecl(I
));
1406 const OMPIteratorExpr::IteratorRange Range
= Node
->getIteratorRange(I
);
1418 void TextNodeDumper::VisitConceptSpecializationExpr(
1419 const ConceptSpecializationExpr
*Node
) {
1421 dumpBareDeclRef(Node
->getFoundDecl());
1424 void TextNodeDumper::VisitRequiresExpr(
1425 const RequiresExpr
*Node
) {
1426 if (!Node
->isValueDependent())
1427 OS
<< (Node
->isSatisfied() ? " satisfied" : " unsatisfied");
1430 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType
*T
) {
1431 if (T
->isSpelledAsLValue())
1432 OS
<< " written as lvalue reference";
1435 void TextNodeDumper::VisitArrayType(const ArrayType
*T
) {
1436 switch (T
->getSizeModifier()) {
1437 case ArrayType::Normal
:
1439 case ArrayType::Static
:
1442 case ArrayType::Star
:
1446 OS
<< " " << T
->getIndexTypeQualifiers().getAsString();
1449 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType
*T
) {
1450 OS
<< " " << T
->getSize();
1454 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType
*T
) {
1456 dumpSourceRange(T
->getBracketsRange());
1460 void TextNodeDumper::VisitDependentSizedArrayType(
1461 const DependentSizedArrayType
*T
) {
1464 dumpSourceRange(T
->getBracketsRange());
1467 void TextNodeDumper::VisitDependentSizedExtVectorType(
1468 const DependentSizedExtVectorType
*T
) {
1470 dumpLocation(T
->getAttributeLoc());
1473 void TextNodeDumper::VisitVectorType(const VectorType
*T
) {
1474 switch (T
->getVectorKind()) {
1475 case VectorType::GenericVector
:
1477 case VectorType::AltiVecVector
:
1480 case VectorType::AltiVecPixel
:
1481 OS
<< " altivec pixel";
1483 case VectorType::AltiVecBool
:
1484 OS
<< " altivec bool";
1486 case VectorType::NeonVector
:
1489 case VectorType::NeonPolyVector
:
1492 case VectorType::SveFixedLengthDataVector
:
1493 OS
<< " fixed-length sve data vector";
1495 case VectorType::SveFixedLengthPredicateVector
:
1496 OS
<< " fixed-length sve predicate vector";
1499 OS
<< " " << T
->getNumElements();
1502 void TextNodeDumper::VisitFunctionType(const FunctionType
*T
) {
1503 auto EI
= T
->getExtInfo();
1504 if (EI
.getNoReturn())
1506 if (EI
.getProducesResult())
1507 OS
<< " produces_result";
1508 if (EI
.getHasRegParm())
1509 OS
<< " regparm " << EI
.getRegParm();
1510 OS
<< " " << FunctionType::getNameForCallConv(EI
.getCC());
1513 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType
*T
) {
1514 auto EPI
= T
->getExtProtoInfo();
1515 if (EPI
.HasTrailingReturn
)
1516 OS
<< " trailing_return";
1519 if (T
->isVolatile())
1521 if (T
->isRestrict())
1523 if (T
->getExtProtoInfo().Variadic
)
1525 switch (EPI
.RefQualifier
) {
1535 // FIXME: Exception specification.
1536 // FIXME: Consumed parameters.
1537 VisitFunctionType(T
);
1540 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType
*T
) {
1541 dumpDeclRef(T
->getDecl());
1544 void TextNodeDumper::VisitUsingType(const UsingType
*T
) {
1545 dumpDeclRef(T
->getFoundDecl());
1546 if (!T
->typeMatchesDecl())
1550 void TextNodeDumper::VisitTypedefType(const TypedefType
*T
) {
1551 dumpDeclRef(T
->getDecl());
1552 if (!T
->typeMatchesDecl())
1556 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType
*T
) {
1557 switch (T
->getUTTKind()) {
1558 #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1559 case UnaryTransformType::Enum: \
1562 #include "clang/Basic/TransformTypeTraits.def"
1566 void TextNodeDumper::VisitTagType(const TagType
*T
) {
1567 dumpDeclRef(T
->getDecl());
1570 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType
*T
) {
1571 OS
<< " depth " << T
->getDepth() << " index " << T
->getIndex();
1572 if (T
->isParameterPack())
1574 dumpDeclRef(T
->getDecl());
1577 void TextNodeDumper::VisitSubstTemplateTypeParmType(
1578 const SubstTemplateTypeParmType
*T
) {
1579 dumpDeclRef(T
->getAssociatedDecl());
1580 VisitTemplateTypeParmDecl(T
->getReplacedParameter());
1581 if (auto PackIndex
= T
->getPackIndex())
1582 OS
<< " pack_index " << *PackIndex
;
1585 void TextNodeDumper::VisitSubstTemplateTypeParmPackType(
1586 const SubstTemplateTypeParmPackType
*T
) {
1587 dumpDeclRef(T
->getAssociatedDecl());
1588 VisitTemplateTypeParmDecl(T
->getReplacedParameter());
1591 void TextNodeDumper::VisitAutoType(const AutoType
*T
) {
1592 if (T
->isDecltypeAuto())
1593 OS
<< " decltype(auto)";
1594 if (!T
->isDeduced())
1596 if (T
->isConstrained()) {
1597 dumpDeclRef(T
->getTypeConstraintConcept());
1598 for (const auto &Arg
: T
->getTypeConstraintArguments())
1599 VisitTemplateArgument(Arg
);
1603 void TextNodeDumper::VisitDeducedTemplateSpecializationType(
1604 const DeducedTemplateSpecializationType
*T
) {
1605 if (T
->getTemplateName().getKind() == TemplateName::UsingTemplate
)
1609 void TextNodeDumper::VisitTemplateSpecializationType(
1610 const TemplateSpecializationType
*T
) {
1611 if (T
->isTypeAlias())
1613 if (T
->getTemplateName().getKind() == TemplateName::UsingTemplate
)
1616 T
->getTemplateName().dump(OS
);
1619 void TextNodeDumper::VisitInjectedClassNameType(
1620 const InjectedClassNameType
*T
) {
1621 dumpDeclRef(T
->getDecl());
1624 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType
*T
) {
1625 dumpDeclRef(T
->getDecl());
1628 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType
*T
) {
1629 if (auto N
= T
->getNumExpansions())
1630 OS
<< " expansions " << *N
;
1633 void TextNodeDumper::VisitLabelDecl(const LabelDecl
*D
) { dumpName(D
); }
1635 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl
*D
) {
1637 dumpType(D
->getUnderlyingType());
1638 if (D
->isModulePrivate())
1639 OS
<< " __module_private__";
1642 void TextNodeDumper::VisitEnumDecl(const EnumDecl
*D
) {
1643 if (D
->isScoped()) {
1644 if (D
->isScopedUsingClassTag())
1650 if (D
->isModulePrivate())
1651 OS
<< " __module_private__";
1653 dumpType(D
->getIntegerType());
1656 void TextNodeDumper::VisitRecordDecl(const RecordDecl
*D
) {
1657 OS
<< ' ' << D
->getKindName();
1659 if (D
->isModulePrivate())
1660 OS
<< " __module_private__";
1661 if (D
->isCompleteDefinition())
1662 OS
<< " definition";
1665 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl
*D
) {
1667 dumpType(D
->getType());
1670 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl
*D
) {
1672 dumpType(D
->getType());
1674 for (const auto *Child
: D
->chain())
1678 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl
*D
) {
1680 dumpType(D
->getType());
1682 StorageClass SC
= D
->getStorageClass();
1684 OS
<< ' ' << VarDecl::getStorageClassSpecifierString(SC
);
1685 if (D
->isInlineSpecified())
1687 if (D
->isVirtualAsWritten())
1689 if (D
->isModulePrivate())
1690 OS
<< " __module_private__";
1694 if (D
->isDefaulted()) {
1699 if (D
->isDeletedAsWritten())
1704 if (D
->isIneligibleOrNotSelected())
1705 OS
<< (isa
<CXXDestructorDecl
>(D
) ? " not_selected" : " ineligible");
1707 if (const auto *FPT
= D
->getType()->getAs
<FunctionProtoType
>()) {
1708 FunctionProtoType::ExtProtoInfo EPI
= FPT
->getExtProtoInfo();
1709 switch (EPI
.ExceptionSpec
.Type
) {
1712 case EST_Unevaluated
:
1713 OS
<< " noexcept-unevaluated " << EPI
.ExceptionSpec
.SourceDecl
;
1715 case EST_Uninstantiated
:
1716 OS
<< " noexcept-uninstantiated " << EPI
.ExceptionSpec
.SourceTemplate
;
1721 if (const auto *MD
= dyn_cast
<CXXMethodDecl
>(D
)) {
1722 if (MD
->size_overridden_methods() != 0) {
1723 auto dumpOverride
= [=](const CXXMethodDecl
*D
) {
1724 SplitQualType T_split
= D
->getType().split();
1725 OS
<< D
<< " " << D
->getParent()->getName() << "::" << D
->getDeclName()
1726 << " '" << QualType::getAsString(T_split
, PrintPolicy
) << "'";
1730 auto Overrides
= MD
->overridden_methods();
1731 OS
<< "Overrides: [ ";
1732 dumpOverride(*Overrides
.begin());
1733 for (const auto *Override
:
1734 llvm::make_range(Overrides
.begin() + 1, Overrides
.end())) {
1736 dumpOverride(Override
);
1743 if (!D
->isInlineSpecified() && D
->isInlined()) {
1744 OS
<< " implicit-inline";
1746 // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
1747 // the Params are set later, it is possible for a dump during debugging to
1748 // encounter a FunctionDecl that has been created but hasn't been assigned
1749 // ParmVarDecls yet.
1750 if (!D
->param_empty() && !D
->param_begin())
1751 OS
<< " <<<NULL params x " << D
->getNumParams() << ">>>";
1754 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
1755 const LifetimeExtendedTemporaryDecl
*D
) {
1756 OS
<< " extended by ";
1757 dumpBareDeclRef(D
->getExtendingDecl());
1760 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1761 OS
<< D
->getManglingNumber();
1765 void TextNodeDumper::VisitFieldDecl(const FieldDecl
*D
) {
1767 dumpType(D
->getType());
1770 if (D
->isModulePrivate())
1771 OS
<< " __module_private__";
1774 void TextNodeDumper::VisitVarDecl(const VarDecl
*D
) {
1776 dumpType(D
->getType());
1777 StorageClass SC
= D
->getStorageClass();
1779 OS
<< ' ' << VarDecl::getStorageClassSpecifierString(SC
);
1780 switch (D
->getTLSKind()) {
1781 case VarDecl::TLS_None
:
1783 case VarDecl::TLS_Static
:
1786 case VarDecl::TLS_Dynamic
:
1787 OS
<< " tls_dynamic";
1790 if (D
->isModulePrivate())
1791 OS
<< " __module_private__";
1792 if (D
->isNRVOVariable())
1796 if (D
->isConstexpr())
1799 switch (D
->getInitStyle()) {
1800 case VarDecl::CInit
:
1803 case VarDecl::CallInit
:
1806 case VarDecl::ListInit
:
1811 if (D
->needsDestruction(D
->getASTContext()))
1813 if (D
->isParameterPack())
1817 const Expr
*E
= D
->getInit();
1818 // Only dump the value of constexpr VarDecls for now.
1819 if (E
&& !E
->isValueDependent() && D
->isConstexpr()) {
1820 const APValue
*Value
= D
->evaluateValue();
1822 AddChild("value", [=] { Visit(*Value
, E
->getType()); });
1827 void TextNodeDumper::VisitBindingDecl(const BindingDecl
*D
) {
1829 dumpType(D
->getType());
1832 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl
*D
) {
1837 void TextNodeDumper::VisitImportDecl(const ImportDecl
*D
) {
1838 OS
<< ' ' << D
->getImportedModule()->getFullModuleName();
1841 D
->getASTContext().getModuleInitializers(D
->getImportedModule()))
1842 dumpDeclRef(InitD
, "initializer");
1845 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl
*D
) {
1847 switch (D
->getCommentKind()) {
1849 llvm_unreachable("unexpected pragma comment kind");
1866 StringRef Arg
= D
->getArg();
1868 OS
<< " \"" << Arg
<< "\"";
1871 void TextNodeDumper::VisitPragmaDetectMismatchDecl(
1872 const PragmaDetectMismatchDecl
*D
) {
1873 OS
<< " \"" << D
->getName() << "\" \"" << D
->getValue() << "\"";
1876 void TextNodeDumper::VisitOMPExecutableDirective(
1877 const OMPExecutableDirective
*D
) {
1878 if (D
->isStandaloneDirective())
1879 OS
<< " openmp_standalone_directive";
1882 void TextNodeDumper::VisitOMPDeclareReductionDecl(
1883 const OMPDeclareReductionDecl
*D
) {
1885 dumpType(D
->getType());
1887 dumpPointer(D
->getCombiner());
1888 if (const auto *Initializer
= D
->getInitializer()) {
1889 OS
<< " initializer";
1890 dumpPointer(Initializer
);
1891 switch (D
->getInitializerKind()) {
1892 case OMPDeclareReductionDecl::DirectInit
:
1893 OS
<< " omp_priv = ";
1895 case OMPDeclareReductionDecl::CopyInit
:
1896 OS
<< " omp_priv ()";
1898 case OMPDeclareReductionDecl::CallInit
:
1904 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl
*D
) {
1905 for (const auto *C
: D
->clauselists()) {
1908 ColorScope
Color(OS
, ShowColors
, NullColor
);
1909 OS
<< "<<<NULL>>> OMPClause";
1913 ColorScope
Color(OS
, ShowColors
, AttrColor
);
1914 StringRef
ClauseName(
1915 llvm::omp::getOpenMPClauseName(C
->getClauseKind()));
1916 OS
<< "OMP" << ClauseName
.substr(/*Start=*/0, /*N=*/1).upper()
1917 << ClauseName
.drop_front() << "Clause";
1920 dumpSourceRange(SourceRange(C
->getBeginLoc(), C
->getEndLoc()));
1925 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl
*D
) {
1927 dumpType(D
->getType());
1930 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl
*D
) {
1934 if (!D
->isOriginalNamespace())
1935 dumpDeclRef(D
->getOriginalNamespace(), "original");
1938 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl
*D
) {
1940 dumpBareDeclRef(D
->getNominatedNamespace());
1943 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl
*D
) {
1945 dumpDeclRef(D
->getAliasedNamespace());
1948 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl
*D
) {
1950 dumpType(D
->getUnderlyingType());
1953 void TextNodeDumper::VisitTypeAliasTemplateDecl(
1954 const TypeAliasTemplateDecl
*D
) {
1958 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl
*D
) {
1960 if (!D
->isCompleteDefinition())
1965 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
1966 OS
<< "DefinitionData";
1968 #define FLAG(fn, name) \
1971 FLAG(isParsingBaseSpecifiers
, parsing_base_specifiers
);
1973 FLAG(isGenericLambda
, generic
);
1974 FLAG(isLambda
, lambda
);
1976 FLAG(isAnonymousStructOrUnion
, is_anonymous
);
1977 FLAG(canPassInRegisters
, pass_in_registers
);
1978 FLAG(isEmpty
, empty
);
1979 FLAG(isAggregate
, aggregate
);
1980 FLAG(isStandardLayout
, standard_layout
);
1981 FLAG(isTriviallyCopyable
, trivially_copyable
);
1983 FLAG(isTrivial
, trivial
);
1984 FLAG(isPolymorphic
, polymorphic
);
1985 FLAG(isAbstract
, abstract
);
1986 FLAG(isLiteral
, literal
);
1988 FLAG(hasUserDeclaredConstructor
, has_user_declared_ctor
);
1989 FLAG(hasConstexprNonCopyMoveConstructor
, has_constexpr_non_copy_move_ctor
);
1990 FLAG(hasMutableFields
, has_mutable_fields
);
1991 FLAG(hasVariantMembers
, has_variant_members
);
1992 FLAG(allowConstDefaultInit
, can_const_default_init
);
1996 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
1997 OS
<< "DefaultConstructor";
1999 FLAG(hasDefaultConstructor
, exists
);
2000 FLAG(hasTrivialDefaultConstructor
, trivial
);
2001 FLAG(hasNonTrivialDefaultConstructor
, non_trivial
);
2002 FLAG(hasUserProvidedDefaultConstructor
, user_provided
);
2003 FLAG(hasConstexprDefaultConstructor
, constexpr);
2004 FLAG(needsImplicitDefaultConstructor
, needs_implicit
);
2005 FLAG(defaultedDefaultConstructorIsConstexpr
, defaulted_is_constexpr
);
2010 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2011 OS
<< "CopyConstructor";
2013 FLAG(hasSimpleCopyConstructor
, simple
);
2014 FLAG(hasTrivialCopyConstructor
, trivial
);
2015 FLAG(hasNonTrivialCopyConstructor
, non_trivial
);
2016 FLAG(hasUserDeclaredCopyConstructor
, user_declared
);
2017 FLAG(hasCopyConstructorWithConstParam
, has_const_param
);
2018 FLAG(needsImplicitCopyConstructor
, needs_implicit
);
2019 FLAG(needsOverloadResolutionForCopyConstructor
,
2020 needs_overload_resolution
);
2021 if (!D
->needsOverloadResolutionForCopyConstructor())
2022 FLAG(defaultedCopyConstructorIsDeleted
, defaulted_is_deleted
);
2023 FLAG(implicitCopyConstructorHasConstParam
, implicit_has_const_param
);
2028 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2029 OS
<< "MoveConstructor";
2031 FLAG(hasMoveConstructor
, exists
);
2032 FLAG(hasSimpleMoveConstructor
, simple
);
2033 FLAG(hasTrivialMoveConstructor
, trivial
);
2034 FLAG(hasNonTrivialMoveConstructor
, non_trivial
);
2035 FLAG(hasUserDeclaredMoveConstructor
, user_declared
);
2036 FLAG(needsImplicitMoveConstructor
, needs_implicit
);
2037 FLAG(needsOverloadResolutionForMoveConstructor
,
2038 needs_overload_resolution
);
2039 if (!D
->needsOverloadResolutionForMoveConstructor())
2040 FLAG(defaultedMoveConstructorIsDeleted
, defaulted_is_deleted
);
2045 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2046 OS
<< "CopyAssignment";
2048 FLAG(hasSimpleCopyAssignment
, simple
);
2049 FLAG(hasTrivialCopyAssignment
, trivial
);
2050 FLAG(hasNonTrivialCopyAssignment
, non_trivial
);
2051 FLAG(hasCopyAssignmentWithConstParam
, has_const_param
);
2052 FLAG(hasUserDeclaredCopyAssignment
, user_declared
);
2053 FLAG(needsImplicitCopyAssignment
, needs_implicit
);
2054 FLAG(needsOverloadResolutionForCopyAssignment
, needs_overload_resolution
);
2055 FLAG(implicitCopyAssignmentHasConstParam
, implicit_has_const_param
);
2060 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2061 OS
<< "MoveAssignment";
2063 FLAG(hasMoveAssignment
, exists
);
2064 FLAG(hasSimpleMoveAssignment
, simple
);
2065 FLAG(hasTrivialMoveAssignment
, trivial
);
2066 FLAG(hasNonTrivialMoveAssignment
, non_trivial
);
2067 FLAG(hasUserDeclaredMoveAssignment
, user_declared
);
2068 FLAG(needsImplicitMoveAssignment
, needs_implicit
);
2069 FLAG(needsOverloadResolutionForMoveAssignment
, needs_overload_resolution
);
2074 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2077 FLAG(hasSimpleDestructor
, simple
);
2078 FLAG(hasIrrelevantDestructor
, irrelevant
);
2079 FLAG(hasTrivialDestructor
, trivial
);
2080 FLAG(hasNonTrivialDestructor
, non_trivial
);
2081 FLAG(hasUserDeclaredDestructor
, user_declared
);
2082 FLAG(hasConstexprDestructor
, constexpr);
2083 FLAG(needsImplicitDestructor
, needs_implicit
);
2084 FLAG(needsOverloadResolutionForDestructor
, needs_overload_resolution
);
2085 if (!D
->needsOverloadResolutionForDestructor())
2086 FLAG(defaultedDestructorIsDeleted
, defaulted_is_deleted
);
2090 for (const auto &I
: D
->bases()) {
2094 dumpAccessSpecifier(I
.getAccessSpecifier());
2095 dumpType(I
.getType());
2096 if (I
.isPackExpansion())
2102 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl
*D
) {
2106 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl
*D
) {
2110 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl
*D
) {
2114 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl
*D
) {
2118 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl
*D
) {
2119 if (const auto *TC
= D
->getTypeConstraint()) {
2121 dumpBareDeclRef(TC
->getNamedConcept());
2122 if (TC
->getNamedConcept() != TC
->getFoundDecl()) {
2124 dumpBareDeclRef(TC
->getFoundDecl());
2127 } else if (D
->wasDeclaredWithTypename())
2131 OS
<< " depth " << D
->getDepth() << " index " << D
->getIndex();
2132 if (D
->isParameterPack())
2137 void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2138 const NonTypeTemplateParmDecl
*D
) {
2139 dumpType(D
->getType());
2140 OS
<< " depth " << D
->getDepth() << " index " << D
->getIndex();
2141 if (D
->isParameterPack())
2146 void TextNodeDumper::VisitTemplateTemplateParmDecl(
2147 const TemplateTemplateParmDecl
*D
) {
2148 OS
<< " depth " << D
->getDepth() << " index " << D
->getIndex();
2149 if (D
->isParameterPack())
2154 void TextNodeDumper::VisitUsingDecl(const UsingDecl
*D
) {
2156 if (D
->getQualifier())
2157 D
->getQualifier()->print(OS
, D
->getASTContext().getPrintingPolicy());
2158 OS
<< D
->getDeclName();
2161 void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl
*D
) {
2163 dumpBareDeclRef(D
->getEnumDecl());
2166 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2167 const UnresolvedUsingTypenameDecl
*D
) {
2169 if (D
->getQualifier())
2170 D
->getQualifier()->print(OS
, D
->getASTContext().getPrintingPolicy());
2171 OS
<< D
->getDeclName();
2174 void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2175 const UnresolvedUsingValueDecl
*D
) {
2177 if (D
->getQualifier())
2178 D
->getQualifier()->print(OS
, D
->getASTContext().getPrintingPolicy());
2179 OS
<< D
->getDeclName();
2180 dumpType(D
->getType());
2183 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl
*D
) {
2185 dumpBareDeclRef(D
->getTargetDecl());
2188 void TextNodeDumper::VisitConstructorUsingShadowDecl(
2189 const ConstructorUsingShadowDecl
*D
) {
2190 if (D
->constructsVirtualBase())
2195 dumpBareDeclRef(D
->getTargetDecl());
2200 dumpBareDeclRef(D
->getNominatedBaseClass());
2202 dumpBareDeclRef(D
->getNominatedBaseClassShadowDecl());
2206 OS
<< "constructed ";
2207 dumpBareDeclRef(D
->getConstructedBaseClass());
2209 dumpBareDeclRef(D
->getConstructedBaseClassShadowDecl());
2213 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl
*D
) {
2214 switch (D
->getLanguage()) {
2215 case LinkageSpecDecl::lang_c
:
2218 case LinkageSpecDecl::lang_cxx
:
2224 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl
*D
) {
2226 dumpAccessSpecifier(D
->getAccess());
2229 void TextNodeDumper::VisitFriendDecl(const FriendDecl
*D
) {
2230 if (TypeSourceInfo
*T
= D
->getFriendType())
2231 dumpType(T
->getType());
2234 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl
*D
) {
2236 dumpType(D
->getType());
2237 if (D
->getSynthesize())
2238 OS
<< " synthesize";
2240 switch (D
->getAccessControl()) {
2241 case ObjCIvarDecl::None
:
2244 case ObjCIvarDecl::Private
:
2247 case ObjCIvarDecl::Protected
:
2250 case ObjCIvarDecl::Public
:
2253 case ObjCIvarDecl::Package
:
2259 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl
*D
) {
2260 if (D
->isInstanceMethod())
2265 dumpType(D
->getReturnType());
2267 if (D
->isVariadic())
2271 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl
*D
) {
2273 switch (D
->getVariance()) {
2274 case ObjCTypeParamVariance::Invariant
:
2277 case ObjCTypeParamVariance::Covariant
:
2281 case ObjCTypeParamVariance::Contravariant
:
2282 OS
<< " contravariant";
2286 if (D
->hasExplicitBound())
2288 dumpType(D
->getUnderlyingType());
2291 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl
*D
) {
2293 dumpDeclRef(D
->getClassInterface());
2294 dumpDeclRef(D
->getImplementation());
2295 for (const auto *P
: D
->protocols())
2299 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl
*D
) {
2301 dumpDeclRef(D
->getClassInterface());
2302 dumpDeclRef(D
->getCategoryDecl());
2305 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl
*D
) {
2308 for (const auto *Child
: D
->protocols())
2312 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl
*D
) {
2314 dumpDeclRef(D
->getSuperClass(), "super");
2316 dumpDeclRef(D
->getImplementation());
2317 for (const auto *Child
: D
->protocols())
2321 void TextNodeDumper::VisitObjCImplementationDecl(
2322 const ObjCImplementationDecl
*D
) {
2324 dumpDeclRef(D
->getSuperClass(), "super");
2325 dumpDeclRef(D
->getClassInterface());
2328 void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2329 const ObjCCompatibleAliasDecl
*D
) {
2331 dumpDeclRef(D
->getClassInterface());
2334 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl
*D
) {
2336 dumpType(D
->getType());
2338 if (D
->getPropertyImplementation() == ObjCPropertyDecl::Required
)
2340 else if (D
->getPropertyImplementation() == ObjCPropertyDecl::Optional
)
2343 ObjCPropertyAttribute::Kind Attrs
= D
->getPropertyAttributes();
2344 if (Attrs
!= ObjCPropertyAttribute::kind_noattr
) {
2345 if (Attrs
& ObjCPropertyAttribute::kind_readonly
)
2347 if (Attrs
& ObjCPropertyAttribute::kind_assign
)
2349 if (Attrs
& ObjCPropertyAttribute::kind_readwrite
)
2351 if (Attrs
& ObjCPropertyAttribute::kind_retain
)
2353 if (Attrs
& ObjCPropertyAttribute::kind_copy
)
2355 if (Attrs
& ObjCPropertyAttribute::kind_nonatomic
)
2357 if (Attrs
& ObjCPropertyAttribute::kind_atomic
)
2359 if (Attrs
& ObjCPropertyAttribute::kind_weak
)
2361 if (Attrs
& ObjCPropertyAttribute::kind_strong
)
2363 if (Attrs
& ObjCPropertyAttribute::kind_unsafe_unretained
)
2364 OS
<< " unsafe_unretained";
2365 if (Attrs
& ObjCPropertyAttribute::kind_class
)
2367 if (Attrs
& ObjCPropertyAttribute::kind_direct
)
2369 if (Attrs
& ObjCPropertyAttribute::kind_getter
)
2370 dumpDeclRef(D
->getGetterMethodDecl(), "getter");
2371 if (Attrs
& ObjCPropertyAttribute::kind_setter
)
2372 dumpDeclRef(D
->getSetterMethodDecl(), "setter");
2376 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl
*D
) {
2377 dumpName(D
->getPropertyDecl());
2378 if (D
->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize
)
2379 OS
<< " synthesize";
2382 dumpDeclRef(D
->getPropertyDecl());
2383 dumpDeclRef(D
->getPropertyIvarDecl());
2386 void TextNodeDumper::VisitBlockDecl(const BlockDecl
*D
) {
2387 if (D
->isVariadic())
2390 if (D
->capturesCXXThis())
2391 OS
<< " captures_this";
2394 void TextNodeDumper::VisitConceptDecl(const ConceptDecl
*D
) {
2398 void TextNodeDumper::VisitCompoundStmt(const CompoundStmt
*S
) {
2400 if (S
->hasStoredFPFeatures())
2401 printFPOptions(S
->getStoredFPFeatures());
2404 void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl
*D
) {