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/AST/TypeLocVisitor.h"
22 #include "clang/Basic/Module.h"
23 #include "clang/Basic/SourceManager.h"
24 #include "clang/Basic/Specifiers.h"
25 #include "clang/Basic/TypeTraits.h"
26 #include "llvm/ADT/StringExtras.h"
31 using namespace clang
;
33 static void dumpPreviousDeclImpl(raw_ostream
&OS
, ...) {}
36 static void dumpPreviousDeclImpl(raw_ostream
&OS
, const Mergeable
<T
> *D
) {
37 const T
*First
= D
->getFirstDecl();
39 OS
<< " first " << First
;
43 static void dumpPreviousDeclImpl(raw_ostream
&OS
, const Redeclarable
<T
> *D
) {
44 const T
*Prev
= D
->getPreviousDecl();
46 OS
<< " prev " << Prev
;
49 /// Dump the previous declaration in the redeclaration chain for a declaration,
51 static void dumpPreviousDecl(raw_ostream
&OS
, const Decl
*D
) {
52 switch (D
->getKind()) {
53 #define DECL(DERIVED, BASE) \
55 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
56 #define ABSTRACT_DECL(DECL)
57 #include "clang/AST/DeclNodes.inc"
59 llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
62 TextNodeDumper::TextNodeDumper(raw_ostream
&OS
, const ASTContext
&Context
,
64 : TextTreeStructure(OS
, ShowColors
), OS(OS
), ShowColors(ShowColors
),
65 Context(&Context
), SM(&Context
.getSourceManager()),
66 PrintPolicy(Context
.getPrintingPolicy()),
67 Traits(&Context
.getCommentCommandTraits()) {}
69 TextNodeDumper::TextNodeDumper(raw_ostream
&OS
, bool ShowColors
)
70 : TextTreeStructure(OS
, ShowColors
), OS(OS
), ShowColors(ShowColors
) {}
72 void TextNodeDumper::Visit(const comments::Comment
*C
,
73 const comments::FullComment
*FC
) {
75 ColorScope
Color(OS
, ShowColors
, NullColor
);
81 ColorScope
Color(OS
, ShowColors
, CommentColor
);
82 OS
<< C
->getCommentKindName();
85 dumpSourceRange(C
->getSourceRange());
87 ConstCommentVisitor
<TextNodeDumper
, void,
88 const comments::FullComment
*>::visit(C
, FC
);
91 void TextNodeDumper::Visit(const Attr
*A
) {
93 ColorScope
Color(OS
, ShowColors
, AttrColor
);
95 switch (A
->getKind()) {
100 #include "clang/Basic/AttrList.inc"
105 dumpSourceRange(A
->getRange());
106 if (A
->isInherited())
111 ConstAttrVisitor
<TextNodeDumper
>::Visit(A
);
114 void TextNodeDumper::Visit(const TemplateArgument
&TA
, SourceRange R
,
115 const Decl
*From
, StringRef Label
) {
116 OS
<< "TemplateArgument";
121 dumpDeclRef(From
, Label
);
123 ConstTemplateArgumentVisitor
<TextNodeDumper
>::Visit(TA
);
126 void TextNodeDumper::Visit(const Stmt
*Node
) {
128 ColorScope
Color(OS
, ShowColors
, NullColor
);
133 ColorScope
Color(OS
, ShowColors
, StmtColor
);
134 OS
<< Node
->getStmtClassName();
137 dumpSourceRange(Node
->getSourceRange());
139 if (const auto *E
= dyn_cast
<Expr
>(Node
)) {
140 dumpType(E
->getType());
142 if (E
->containsErrors()) {
143 ColorScope
Color(OS
, ShowColors
, ErrorsColor
);
144 OS
<< " contains-errors";
148 ColorScope
Color(OS
, ShowColors
, ValueKindColor
);
149 switch (E
->getValueKind()) {
162 ColorScope
Color(OS
, ShowColors
, ObjectKindColor
);
163 switch (E
->getObjectKind()) {
169 case OK_ObjCProperty
:
170 OS
<< " objcproperty";
172 case OK_ObjCSubscript
:
173 OS
<< " objcsubscript";
175 case OK_VectorComponent
:
176 OS
<< " vectorcomponent";
178 case OK_MatrixComponent
:
179 OS
<< " matrixcomponent";
185 ConstStmtVisitor
<TextNodeDumper
>::Visit(Node
);
188 void TextNodeDumper::Visit(const Type
*T
) {
190 ColorScope
Color(OS
, ShowColors
, NullColor
);
194 if (isa
<LocInfoType
>(T
)) {
196 ColorScope
Color(OS
, ShowColors
, TypeColor
);
197 OS
<< "LocInfo Type";
204 ColorScope
Color(OS
, ShowColors
, TypeColor
);
205 OS
<< T
->getTypeClassName() << "Type";
209 dumpBareType(QualType(T
, 0), false);
211 QualType SingleStepDesugar
=
212 T
->getLocallyUnqualifiedSingleStepDesugaredType();
213 if (SingleStepDesugar
!= QualType(T
, 0))
216 if (T
->containsErrors()) {
217 ColorScope
Color(OS
, ShowColors
, ErrorsColor
);
218 OS
<< " contains-errors";
221 if (T
->isDependentType())
223 else if (T
->isInstantiationDependentType())
224 OS
<< " instantiation_dependent";
226 if (T
->isVariablyModifiedType())
227 OS
<< " variably_modified";
228 if (T
->containsUnexpandedParameterPack())
229 OS
<< " contains_unexpanded_pack";
233 TypeVisitor
<TextNodeDumper
>::Visit(T
);
236 void TextNodeDumper::Visit(QualType T
) {
238 dumpPointer(T
.getAsOpaquePtr());
240 dumpBareType(T
, false);
241 OS
<< " " << T
.split().Quals
.getAsString();
244 void TextNodeDumper::Visit(TypeLoc TL
) {
246 ColorScope
Color(OS
, ShowColors
, NullColor
);
252 ColorScope
Color(OS
, ShowColors
, TypeColor
);
253 OS
<< (TL
.getTypeLocClass() == TypeLoc::Qualified
255 : TL
.getType()->getTypeClassName())
258 dumpSourceRange(TL
.getSourceRange());
260 dumpBareType(TL
.getType(), /*Desugar=*/false);
262 TypeLocVisitor
<TextNodeDumper
>::Visit(TL
);
265 void TextNodeDumper::Visit(const Decl
*D
) {
267 ColorScope
Color(OS
, ShowColors
, NullColor
);
273 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
274 OS
<< D
->getDeclKindName() << "Decl";
277 if (D
->getLexicalDeclContext() != D
->getDeclContext())
278 OS
<< " parent " << cast
<Decl
>(D
->getDeclContext());
279 dumpPreviousDecl(OS
, D
);
280 dumpSourceRange(D
->getSourceRange());
282 dumpLocation(D
->getLocation());
283 if (D
->isFromASTFile())
285 if (Module
*M
= D
->getOwningModule())
286 OS
<< " in " << M
->getFullModuleName();
287 if (auto *ND
= dyn_cast
<NamedDecl
>(D
))
288 for (Module
*M
: D
->getASTContext().getModulesWithMergedDefinition(
289 const_cast<NamedDecl
*>(ND
)))
290 AddChild([=] { OS
<< "also in " << M
->getFullModuleName(); });
291 if (const NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
))
292 if (!ND
->isUnconditionallyVisible())
299 else if (D
->isThisDeclarationReferenced())
302 if (D
->isInvalidDecl())
304 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
305 if (FD
->isConstexprSpecified())
307 if (FD
->isConsteval())
309 else if (FD
->isImmediateFunction())
311 if (FD
->isMultiVersion())
312 OS
<< " multiversion";
315 if (!isa
<FunctionDecl
>(*D
)) {
316 const auto *MD
= dyn_cast
<ObjCMethodDecl
>(D
);
317 if (!MD
|| !MD
->isThisDeclarationADefinition()) {
318 const auto *DC
= dyn_cast
<DeclContext
>(D
);
319 if (DC
&& DC
->hasExternalLexicalStorage()) {
320 ColorScope
Color(OS
, ShowColors
, UndeserializedColor
);
321 OS
<< " <undeserialized declarations>";
326 switch (D
->getFriendObjectKind()) {
329 case Decl::FOK_Declared
:
332 case Decl::FOK_Undeclared
:
333 OS
<< " friend_undeclared";
337 ConstDeclVisitor
<TextNodeDumper
>::Visit(D
);
340 void TextNodeDumper::Visit(const CXXCtorInitializer
*Init
) {
341 OS
<< "CXXCtorInitializer";
342 if (Init
->isAnyMemberInitializer()) {
344 dumpBareDeclRef(Init
->getAnyMember());
345 } else if (Init
->isBaseInitializer()) {
346 dumpType(QualType(Init
->getBaseClass(), 0));
347 } else if (Init
->isDelegatingInitializer()) {
348 dumpType(Init
->getTypeSourceInfo()->getType());
350 llvm_unreachable("Unknown initializer type");
354 void TextNodeDumper::Visit(const BlockDecl::Capture
&C
) {
360 if (C
.getVariable()) {
362 dumpBareDeclRef(C
.getVariable());
366 void TextNodeDumper::Visit(const OMPClause
*C
) {
368 ColorScope
Color(OS
, ShowColors
, NullColor
);
369 OS
<< "<<<NULL>>> OMPClause";
373 ColorScope
Color(OS
, ShowColors
, AttrColor
);
374 StringRef
ClauseName(llvm::omp::getOpenMPClauseName(C
->getClauseKind()));
375 OS
<< "OMP" << ClauseName
.substr(/*Start=*/0, /*N=*/1).upper()
376 << ClauseName
.drop_front() << "Clause";
379 dumpSourceRange(SourceRange(C
->getBeginLoc(), C
->getEndLoc()));
384 void TextNodeDumper::VisitOpenACCAsteriskSizeExpr(
385 const OpenACCAsteriskSizeExpr
*E
) {
386 // Nothing to do here, only location exists, and that is printed elsewhere.
389 void TextNodeDumper::Visit(const OpenACCClause
*C
) {
391 ColorScope
Color(OS
, ShowColors
, NullColor
);
392 OS
<< "<<<NULL>>> OpenACCClause";
396 ColorScope
Color(OS
, ShowColors
, AttrColor
);
397 OS
<< C
->getClauseKind();
399 // Handle clauses with parens for types that have no children, likely
400 // because there is no sub expression.
401 switch (C
->getClauseKind()) {
402 case OpenACCClauseKind::Default
:
403 OS
<< '(' << cast
<OpenACCDefaultClause
>(C
)->getDefaultClauseKind() << ')';
405 case OpenACCClauseKind::Async
:
406 case OpenACCClauseKind::Auto
:
407 case OpenACCClauseKind::Attach
:
408 case OpenACCClauseKind::Copy
:
409 case OpenACCClauseKind::PCopy
:
410 case OpenACCClauseKind::PresentOrCopy
:
411 case OpenACCClauseKind::If
:
412 case OpenACCClauseKind::Independent
:
413 case OpenACCClauseKind::DevicePtr
:
414 case OpenACCClauseKind::FirstPrivate
:
415 case OpenACCClauseKind::NoCreate
:
416 case OpenACCClauseKind::NumGangs
:
417 case OpenACCClauseKind::NumWorkers
:
418 case OpenACCClauseKind::Present
:
419 case OpenACCClauseKind::Private
:
420 case OpenACCClauseKind::Self
:
421 case OpenACCClauseKind::Seq
:
422 case OpenACCClauseKind::Tile
:
423 case OpenACCClauseKind::Worker
:
424 case OpenACCClauseKind::Vector
:
425 case OpenACCClauseKind::VectorLength
:
426 // The condition expression will be printed as a part of the 'children',
427 // but print 'clause' here so it is clear what is happening from the dump.
430 case OpenACCClauseKind::Gang
: {
432 // print the list of all GangKinds, so that there is some sort of
433 // relationship to the expressions listed afterwards.
434 auto *GC
= cast
<OpenACCGangClause
>(C
);
436 for (unsigned I
= 0; I
< GC
->getNumExprs(); ++I
) {
437 OS
<< " " << GC
->getExpr(I
).first
;
441 case OpenACCClauseKind::Collapse
:
443 if (cast
<OpenACCCollapseClause
>(C
)->hasForce())
447 case OpenACCClauseKind::CopyIn
:
448 case OpenACCClauseKind::PCopyIn
:
449 case OpenACCClauseKind::PresentOrCopyIn
:
451 if (cast
<OpenACCCopyInClause
>(C
)->isReadOnly())
454 case OpenACCClauseKind::CopyOut
:
455 case OpenACCClauseKind::PCopyOut
:
456 case OpenACCClauseKind::PresentOrCopyOut
:
458 if (cast
<OpenACCCopyOutClause
>(C
)->isZero())
461 case OpenACCClauseKind::Create
:
462 case OpenACCClauseKind::PCreate
:
463 case OpenACCClauseKind::PresentOrCreate
:
465 if (cast
<OpenACCCreateClause
>(C
)->isZero())
468 case OpenACCClauseKind::Wait
:
470 if (cast
<OpenACCWaitClause
>(C
)->hasDevNumExpr())
472 if (cast
<OpenACCWaitClause
>(C
)->hasQueuesTag())
473 OS
<< " has queues tag";
475 case OpenACCClauseKind::DeviceType
:
476 case OpenACCClauseKind::DType
:
478 llvm::interleaveComma(
479 cast
<OpenACCDeviceTypeClause
>(C
)->getArchitectures(), OS
,
480 [&](const DeviceTypeArgument
&Arch
) {
481 if (Arch
.first
== nullptr)
484 OS
<< Arch
.first
->getName();
488 case OpenACCClauseKind::Reduction
:
489 OS
<< " clause Operator: "
490 << cast
<OpenACCReductionClause
>(C
)->getReductionOp();
493 // Nothing to do here.
498 dumpSourceRange(SourceRange(C
->getBeginLoc(), C
->getEndLoc()));
501 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation
&A
) {
502 const TypeSourceInfo
*TSI
= A
.getTypeSourceInfo();
505 dumpType(TSI
->getType());
514 void TextNodeDumper::Visit(const ConceptReference
*R
) {
516 ColorScope
Color(OS
, ShowColors
, NullColor
);
517 OS
<< "<<<NULL>>> ConceptReference";
521 OS
<< "ConceptReference";
523 dumpSourceRange(R
->getSourceRange());
525 dumpBareDeclRef(R
->getNamedConcept());
528 void TextNodeDumper::Visit(const concepts::Requirement
*R
) {
530 ColorScope
Color(OS
, ShowColors
, NullColor
);
531 OS
<< "<<<NULL>>> Requirement";
536 ColorScope
Color(OS
, ShowColors
, StmtColor
);
537 switch (R
->getKind()) {
538 case concepts::Requirement::RK_Type
:
539 OS
<< "TypeRequirement";
541 case concepts::Requirement::RK_Simple
:
542 OS
<< "SimpleRequirement";
544 case concepts::Requirement::RK_Compound
:
545 OS
<< "CompoundRequirement";
547 case concepts::Requirement::RK_Nested
:
548 OS
<< "NestedRequirement";
555 if (auto *ER
= dyn_cast
<concepts::ExprRequirement
>(R
)) {
556 if (ER
->hasNoexceptRequirement())
560 if (R
->isDependent())
563 OS
<< (R
->isSatisfied() ? " satisfied" : " unsatisfied");
564 if (R
->containsUnexpandedParameterPack())
565 OS
<< " contains_unexpanded_pack";
568 static double GetApproxValue(const llvm::APFloat
&F
) {
571 V
.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven
,
573 return V
.convertToDouble();
576 /// True if the \p APValue \p Value can be folded onto the current line.
577 static bool isSimpleAPValue(const APValue
&Value
) {
578 switch (Value
.getKind()) {
580 case APValue::Indeterminate
:
583 case APValue::FixedPoint
:
584 case APValue::ComplexInt
:
585 case APValue::ComplexFloat
:
586 case APValue::LValue
:
587 case APValue::MemberPointer
:
588 case APValue::AddrLabelDiff
:
590 case APValue::Vector
:
592 case APValue::Struct
:
595 return isSimpleAPValue(Value
.getUnionValue());
597 llvm_unreachable("unexpected APValue kind!");
600 /// Dump the children of the \p APValue \p Value.
602 /// \param[in] Value The \p APValue to visit
603 /// \param[in] Ty The \p QualType passed to \p Visit
605 /// \param[in] IdxToChildFun A function mapping an \p APValue and an index
606 /// to one of the child of the \p APValue
608 /// \param[in] NumChildren \p IdxToChildFun will be called on \p Value with
609 /// the indices in the range \p [0,NumChildren(
611 /// \param[in] LabelSingular The label to use on a line with a single child
612 /// \param[in] LabelPlurial The label to use on a line with multiple children
613 void TextNodeDumper::dumpAPValueChildren(
614 const APValue
&Value
, QualType Ty
,
615 const APValue
&(*IdxToChildFun
)(const APValue
&, unsigned),
616 unsigned NumChildren
, StringRef LabelSingular
, StringRef LabelPlurial
) {
617 // To save some vertical space we print up to MaxChildrenPerLine APValues
618 // considered to be simple (by isSimpleAPValue) on a single line.
619 constexpr unsigned MaxChildrenPerLine
= 4;
621 while (I
< NumChildren
) {
623 while (J
< NumChildren
) {
624 if (isSimpleAPValue(IdxToChildFun(Value
, J
)) &&
625 (J
- I
< MaxChildrenPerLine
)) {
632 J
= std::max(I
+ 1, J
);
634 // Print [I,J) on a single line.
635 AddChild(J
- I
> 1 ? LabelPlurial
: LabelSingular
, [=]() {
636 for (unsigned X
= I
; X
< J
; ++X
) {
637 Visit(IdxToChildFun(Value
, X
), Ty
);
646 void TextNodeDumper::Visit(const APValue
&Value
, QualType Ty
) {
647 ColorScope
Color(OS
, ShowColors
, ValueKindColor
);
648 switch (Value
.getKind()) {
652 case APValue::Indeterminate
:
653 OS
<< "Indeterminate";
658 ColorScope
Color(OS
, ShowColors
, ValueColor
);
659 OS
<< Value
.getInt();
665 ColorScope
Color(OS
, ShowColors
, ValueColor
);
666 OS
<< GetApproxValue(Value
.getFloat());
669 case APValue::FixedPoint
:
672 ColorScope
Color(OS
, ShowColors
, ValueColor
);
673 OS
<< Value
.getFixedPoint();
676 case APValue::Vector
: {
677 unsigned VectorLength
= Value
.getVectorLength();
678 OS
<< "Vector length=" << VectorLength
;
682 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
683 return Value
.getVectorElt(Index
);
685 VectorLength
, "element", "elements");
688 case APValue::ComplexInt
:
691 ColorScope
Color(OS
, ShowColors
, ValueColor
);
692 OS
<< Value
.getComplexIntReal() << " + " << Value
.getComplexIntImag()
696 case APValue::ComplexFloat
:
697 OS
<< "ComplexFloat ";
699 ColorScope
Color(OS
, ShowColors
, ValueColor
);
700 OS
<< GetApproxValue(Value
.getComplexFloatReal()) << " + "
701 << GetApproxValue(Value
.getComplexFloatImag()) << 'i';
704 case APValue::LValue
:
706 OS
<< "LValue <todo>";
708 case APValue::Array
: {
709 unsigned ArraySize
= Value
.getArraySize();
710 unsigned NumInitializedElements
= Value
.getArrayInitializedElts();
711 OS
<< "Array size=" << ArraySize
;
715 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
716 return Value
.getArrayInitializedElt(Index
);
718 NumInitializedElements
, "element", "elements");
720 if (Value
.hasArrayFiller()) {
721 AddChild("filler", [=] {
723 ColorScope
Color(OS
, ShowColors
, ValueColor
);
724 OS
<< ArraySize
- NumInitializedElements
<< " x ";
726 Visit(Value
.getArrayFiller(), Ty
);
732 case APValue::Struct
: {
737 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
738 return Value
.getStructBase(Index
);
740 Value
.getStructNumBases(), "base", "bases");
744 [](const APValue
&Value
, unsigned Index
) -> const APValue
& {
745 return Value
.getStructField(Index
);
747 Value
.getStructNumFields(), "field", "fields");
751 case APValue::Union
: {
754 ColorScope
Color(OS
, ShowColors
, ValueColor
);
755 if (const FieldDecl
*FD
= Value
.getUnionField())
756 OS
<< " ." << *cast
<NamedDecl
>(FD
);
758 // If the union value is considered to be simple, fold it into the
759 // current line to save some vertical space.
760 const APValue
&UnionValue
= Value
.getUnionValue();
761 if (isSimpleAPValue(UnionValue
)) {
763 Visit(UnionValue
, Ty
);
765 AddChild([=] { Visit(UnionValue
, Ty
); });
770 case APValue::MemberPointer
:
771 OS
<< "MemberPointer <todo>";
773 case APValue::AddrLabelDiff
:
774 OS
<< "AddrLabelDiff <todo>";
777 llvm_unreachable("Unknown APValue kind!");
780 void TextNodeDumper::dumpPointer(const void *Ptr
) {
781 ColorScope
Color(OS
, ShowColors
, AddressColor
);
785 void TextNodeDumper::dumpLocation(SourceLocation Loc
) {
789 ColorScope
Color(OS
, ShowColors
, LocationColor
);
790 SourceLocation SpellingLoc
= SM
->getSpellingLoc(Loc
);
792 // The general format we print out is filename:line:col, but we drop pieces
793 // that haven't changed since the last loc printed.
794 PresumedLoc PLoc
= SM
->getPresumedLoc(SpellingLoc
);
796 if (PLoc
.isInvalid()) {
797 OS
<< "<invalid sloc>";
801 if (strcmp(PLoc
.getFilename(), LastLocFilename
) != 0) {
802 OS
<< PLoc
.getFilename() << ':' << PLoc
.getLine() << ':'
804 LastLocFilename
= PLoc
.getFilename();
805 LastLocLine
= PLoc
.getLine();
806 } else if (PLoc
.getLine() != LastLocLine
) {
807 OS
<< "line" << ':' << PLoc
.getLine() << ':' << PLoc
.getColumn();
808 LastLocLine
= PLoc
.getLine();
810 OS
<< "col" << ':' << PLoc
.getColumn();
814 void TextNodeDumper::dumpSourceRange(SourceRange R
) {
815 // Can't translate locations if a SourceManager isn't available.
820 dumpLocation(R
.getBegin());
821 if (R
.getBegin() != R
.getEnd()) {
823 dumpLocation(R
.getEnd());
827 // <t2.c:123:421[blah], t2.c:412:321>
830 void TextNodeDumper::dumpBareType(QualType T
, bool Desugar
) {
831 ColorScope
Color(OS
, ShowColors
, TypeColor
);
833 SplitQualType T_split
= T
.split();
834 std::string T_str
= QualType::getAsString(T_split
, PrintPolicy
);
835 OS
<< "'" << T_str
<< "'";
837 if (Desugar
&& !T
.isNull()) {
838 // If the type is sugared, also dump a (shallow) desugared type when
839 // it is visibly different.
840 SplitQualType D_split
= T
.getSplitDesugaredType();
841 if (T_split
!= D_split
) {
842 std::string D_str
= QualType::getAsString(D_split
, PrintPolicy
);
844 OS
<< ":'" << QualType::getAsString(D_split
, PrintPolicy
) << "'";
849 void TextNodeDumper::dumpType(QualType T
) {
854 void TextNodeDumper::dumpBareDeclRef(const Decl
*D
) {
856 ColorScope
Color(OS
, ShowColors
, NullColor
);
862 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
863 OS
<< D
->getDeclKindName();
867 if (const NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
)) {
868 ColorScope
Color(OS
, ShowColors
, DeclNameColor
);
869 OS
<< " '" << ND
->getDeclName() << '\'';
872 if (const ValueDecl
*VD
= dyn_cast
<ValueDecl
>(D
))
873 dumpType(VD
->getType());
876 void TextNodeDumper::dumpName(const NamedDecl
*ND
) {
877 if (ND
->getDeclName()) {
878 ColorScope
Color(OS
, ShowColors
, DeclNameColor
);
879 OS
<< ' ' << ND
->getDeclName();
883 void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS
) {
884 const auto AccessSpelling
= getAccessSpelling(AS
);
885 if (AccessSpelling
.empty())
887 OS
<< AccessSpelling
;
890 void TextNodeDumper::dumpCleanupObject(
891 const ExprWithCleanups::CleanupObject
&C
) {
892 if (auto *BD
= C
.dyn_cast
<BlockDecl
*>())
893 dumpDeclRef(BD
, "cleanup");
894 else if (auto *CLE
= C
.dyn_cast
<CompoundLiteralExpr
*>())
898 ColorScope
Color(OS
, ShowColors
, StmtColor
);
899 OS
<< CLE
->getStmtClassName();
904 llvm_unreachable("unexpected cleanup type");
907 void clang::TextNodeDumper::dumpTemplateSpecializationKind(
908 TemplateSpecializationKind TSK
) {
912 case TSK_ImplicitInstantiation
:
913 OS
<< " implicit_instantiation";
915 case TSK_ExplicitSpecialization
:
916 OS
<< " explicit_specialization";
918 case TSK_ExplicitInstantiationDeclaration
:
919 OS
<< " explicit_instantiation_declaration";
921 case TSK_ExplicitInstantiationDefinition
:
922 OS
<< " explicit_instantiation_definition";
927 void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier
*NNS
) {
932 OS
<< "NestedNameSpecifier";
934 switch (NNS
->getKind()) {
935 case NestedNameSpecifier::Identifier
:
937 OS
<< " '" << NNS
->getAsIdentifier()->getName() << "'";
939 case NestedNameSpecifier::Namespace
:
940 OS
<< " "; // "Namespace" is printed as the decl kind.
941 dumpBareDeclRef(NNS
->getAsNamespace());
943 case NestedNameSpecifier::NamespaceAlias
:
944 OS
<< " "; // "NamespaceAlias" is printed as the decl kind.
945 dumpBareDeclRef(NNS
->getAsNamespaceAlias());
947 case NestedNameSpecifier::TypeSpec
:
949 dumpType(QualType(NNS
->getAsType(), 0));
951 case NestedNameSpecifier::TypeSpecWithTemplate
:
952 OS
<< " TypeSpecWithTemplate";
953 dumpType(QualType(NNS
->getAsType(), 0));
955 case NestedNameSpecifier::Global
:
958 case NestedNameSpecifier::Super
:
963 dumpNestedNameSpecifier(NNS
->getPrefix());
967 void TextNodeDumper::dumpDeclRef(const Decl
*D
, StringRef Label
) {
978 void TextNodeDumper::dumpTemplateArgument(const TemplateArgument
&TA
) {
979 llvm::SmallString
<128> Str
;
981 llvm::raw_svector_ostream
SS(Str
);
982 TA
.print(PrintPolicy
, SS
, /*IncludeType=*/true);
984 OS
<< " '" << Str
<< "'";
989 if (TemplateArgument CanonTA
= Context
->getCanonicalTemplateArgument(TA
);
990 !CanonTA
.structurallyEquals(TA
)) {
991 llvm::SmallString
<128> CanonStr
;
993 llvm::raw_svector_ostream
SS(CanonStr
);
994 CanonTA
.print(PrintPolicy
, SS
, /*IncludeType=*/true);
997 OS
<< ":'" << CanonStr
<< "'";
1001 const char *TextNodeDumper::getCommandName(unsigned CommandID
) {
1003 return Traits
->getCommandInfo(CommandID
)->Name
;
1004 const comments::CommandInfo
*Info
=
1005 comments::CommandTraits::getBuiltinCommandInfo(CommandID
);
1008 return "<not a builtin command>";
1011 void TextNodeDumper::printFPOptions(FPOptionsOverride FPO
) {
1012 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
1013 if (FPO.has##NAME##Override()) \
1014 OS << " " #NAME "=" << FPO.get##NAME##Override();
1015 #include "clang/Basic/FPOptions.def"
1018 void TextNodeDumper::visitTextComment(const comments::TextComment
*C
,
1019 const comments::FullComment
*) {
1020 OS
<< " Text=\"" << C
->getText() << "\"";
1023 void TextNodeDumper::visitInlineCommandComment(
1024 const comments::InlineCommandComment
*C
, const comments::FullComment
*) {
1025 OS
<< " Name=\"" << getCommandName(C
->getCommandID()) << "\"";
1026 switch (C
->getRenderKind()) {
1027 case comments::InlineCommandRenderKind::Normal
:
1028 OS
<< " RenderNormal";
1030 case comments::InlineCommandRenderKind::Bold
:
1031 OS
<< " RenderBold";
1033 case comments::InlineCommandRenderKind::Monospaced
:
1034 OS
<< " RenderMonospaced";
1036 case comments::InlineCommandRenderKind::Emphasized
:
1037 OS
<< " RenderEmphasized";
1039 case comments::InlineCommandRenderKind::Anchor
:
1040 OS
<< " RenderAnchor";
1044 for (unsigned i
= 0, e
= C
->getNumArgs(); i
!= e
; ++i
)
1045 OS
<< " Arg[" << i
<< "]=\"" << C
->getArgText(i
) << "\"";
1048 void TextNodeDumper::visitHTMLStartTagComment(
1049 const comments::HTMLStartTagComment
*C
, const comments::FullComment
*) {
1050 OS
<< " Name=\"" << C
->getTagName() << "\"";
1051 if (C
->getNumAttrs() != 0) {
1053 for (unsigned i
= 0, e
= C
->getNumAttrs(); i
!= e
; ++i
) {
1054 const comments::HTMLStartTagComment::Attribute
&Attr
= C
->getAttr(i
);
1055 OS
<< " \"" << Attr
.Name
<< "=\"" << Attr
.Value
<< "\"";
1058 if (C
->isSelfClosing())
1059 OS
<< " SelfClosing";
1062 void TextNodeDumper::visitHTMLEndTagComment(
1063 const comments::HTMLEndTagComment
*C
, const comments::FullComment
*) {
1064 OS
<< " Name=\"" << C
->getTagName() << "\"";
1067 void TextNodeDumper::visitBlockCommandComment(
1068 const comments::BlockCommandComment
*C
, const comments::FullComment
*) {
1069 OS
<< " Name=\"" << getCommandName(C
->getCommandID()) << "\"";
1070 for (unsigned i
= 0, e
= C
->getNumArgs(); i
!= e
; ++i
)
1071 OS
<< " Arg[" << i
<< "]=\"" << C
->getArgText(i
) << "\"";
1074 void TextNodeDumper::visitParamCommandComment(
1075 const comments::ParamCommandComment
*C
, const comments::FullComment
*FC
) {
1077 << comments::ParamCommandComment::getDirectionAsString(C
->getDirection());
1079 if (C
->isDirectionExplicit())
1080 OS
<< " explicitly";
1082 OS
<< " implicitly";
1084 if (C
->hasParamName()) {
1085 if (C
->isParamIndexValid())
1086 OS
<< " Param=\"" << C
->getParamName(FC
) << "\"";
1088 OS
<< " Param=\"" << C
->getParamNameAsWritten() << "\"";
1091 if (C
->isParamIndexValid() && !C
->isVarArgParam())
1092 OS
<< " ParamIndex=" << C
->getParamIndex();
1095 void TextNodeDumper::visitTParamCommandComment(
1096 const comments::TParamCommandComment
*C
, const comments::FullComment
*FC
) {
1097 if (C
->hasParamName()) {
1098 if (C
->isPositionValid())
1099 OS
<< " Param=\"" << C
->getParamName(FC
) << "\"";
1101 OS
<< " Param=\"" << C
->getParamNameAsWritten() << "\"";
1104 if (C
->isPositionValid()) {
1105 OS
<< " Position=<";
1106 for (unsigned i
= 0, e
= C
->getDepth(); i
!= e
; ++i
) {
1107 OS
<< C
->getIndex(i
);
1115 void TextNodeDumper::visitVerbatimBlockComment(
1116 const comments::VerbatimBlockComment
*C
, const comments::FullComment
*) {
1117 OS
<< " Name=\"" << getCommandName(C
->getCommandID())
1120 << C
->getCloseName() << "\"";
1123 void TextNodeDumper::visitVerbatimBlockLineComment(
1124 const comments::VerbatimBlockLineComment
*C
,
1125 const comments::FullComment
*) {
1126 OS
<< " Text=\"" << C
->getText() << "\"";
1129 void TextNodeDumper::visitVerbatimLineComment(
1130 const comments::VerbatimLineComment
*C
, const comments::FullComment
*) {
1131 OS
<< " Text=\"" << C
->getText() << "\"";
1134 void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument
&) {
1138 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument
&TA
) {
1140 dumpTemplateArgument(TA
);
1143 void TextNodeDumper::VisitDeclarationTemplateArgument(
1144 const TemplateArgument
&TA
) {
1146 dumpTemplateArgument(TA
);
1147 dumpDeclRef(TA
.getAsDecl());
1150 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument
&TA
) {
1152 dumpTemplateArgument(TA
);
1155 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument
&TA
) {
1157 dumpTemplateArgument(TA
);
1160 void TextNodeDumper::dumpTemplateName(TemplateName TN
, StringRef Label
) {
1161 AddChild(Label
, [=] {
1163 llvm::SmallString
<128> Str
;
1165 llvm::raw_svector_ostream
SS(Str
);
1166 TN
.print(SS
, PrintPolicy
);
1168 OS
<< "'" << Str
<< "'";
1171 if (TemplateName CanonTN
= Context
->getCanonicalTemplateName(TN
);
1173 llvm::SmallString
<128> CanonStr
;
1175 llvm::raw_svector_ostream
SS(CanonStr
);
1176 CanonTN
.print(SS
, PrintPolicy
);
1178 if (CanonStr
!= Str
)
1179 OS
<< ":'" << CanonStr
<< "'";
1183 dumpBareTemplateName(TN
);
1187 void TextNodeDumper::dumpBareTemplateName(TemplateName TN
) {
1188 switch (TN
.getKind()) {
1189 case TemplateName::Template
:
1190 AddChild([=] { Visit(TN
.getAsTemplateDecl()); });
1192 case TemplateName::UsingTemplate
: {
1193 const UsingShadowDecl
*USD
= TN
.getAsUsingShadowDecl();
1194 AddChild([=] { Visit(USD
); });
1195 AddChild("target", [=] { Visit(USD
->getTargetDecl()); });
1198 case TemplateName::QualifiedTemplate
: {
1200 const QualifiedTemplateName
*QTN
= TN
.getAsQualifiedTemplateName();
1201 if (QTN
->hasTemplateKeyword())
1203 dumpNestedNameSpecifier(QTN
->getQualifier());
1204 dumpBareTemplateName(QTN
->getUnderlyingTemplate());
1207 case TemplateName::DependentTemplate
: {
1209 const DependentTemplateName
*DTN
= TN
.getAsDependentTemplateName();
1210 dumpNestedNameSpecifier(DTN
->getQualifier());
1213 case TemplateName::SubstTemplateTemplateParm
: {
1215 const SubstTemplateTemplateParmStorage
*STS
=
1216 TN
.getAsSubstTemplateTemplateParm();
1217 OS
<< " index " << STS
->getIndex();
1218 if (std::optional
<unsigned int> PackIndex
= STS
->getPackIndex())
1219 OS
<< " pack_index " << *PackIndex
;
1220 if (const TemplateTemplateParmDecl
*P
= STS
->getParameter())
1221 AddChild("parameter", [=] { Visit(P
); });
1222 dumpDeclRef(STS
->getAssociatedDecl(), "associated");
1223 dumpTemplateName(STS
->getReplacement(), "replacement");
1226 case TemplateName::DeducedTemplate
: {
1228 const DeducedTemplateStorage
*DTS
= TN
.getAsDeducedTemplateName();
1229 dumpTemplateName(DTS
->getUnderlying(), "underlying");
1230 AddChild("defaults", [=] {
1231 auto [StartPos
, Args
] = DTS
->getDefaultArguments();
1232 OS
<< " start " << StartPos
;
1233 for (const TemplateArgument
&Arg
: Args
)
1234 AddChild([=] { Visit(Arg
, SourceRange()); });
1238 // FIXME: Implement these.
1239 case TemplateName::OverloadedTemplate
:
1240 OS
<< " overloaded";
1242 case TemplateName::AssumedTemplate
:
1245 case TemplateName::SubstTemplateTemplateParmPack
:
1246 OS
<< " subst_pack";
1249 llvm_unreachable("Unexpected TemplateName Kind");
1252 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument
&TA
) {
1254 dumpTemplateArgument(TA
);
1255 dumpBareTemplateName(TA
.getAsTemplate());
1258 void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
1259 const TemplateArgument
&TA
) {
1260 OS
<< " template expansion";
1261 dumpTemplateArgument(TA
);
1262 dumpBareTemplateName(TA
.getAsTemplateOrTemplatePattern());
1265 void TextNodeDumper::VisitExpressionTemplateArgument(
1266 const TemplateArgument
&TA
) {
1268 dumpTemplateArgument(TA
);
1271 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument
&TA
) {
1273 dumpTemplateArgument(TA
);
1276 static void dumpBasePath(raw_ostream
&OS
, const CastExpr
*Node
) {
1277 if (Node
->path_empty())
1282 for (CastExpr::path_const_iterator I
= Node
->path_begin(),
1283 E
= Node
->path_end();
1285 const CXXBaseSpecifier
*Base
= *I
;
1290 cast
<CXXRecordDecl
>(Base
->getType()->castAs
<RecordType
>()->getDecl());
1292 if (Base
->isVirtual())
1294 OS
<< RD
->getName();
1301 void TextNodeDumper::VisitIfStmt(const IfStmt
*Node
) {
1302 if (Node
->hasInitStorage())
1304 if (Node
->hasVarStorage())
1306 if (Node
->hasElseStorage())
1308 if (Node
->isConstexpr())
1310 if (Node
->isConsteval()) {
1312 if (Node
->isNegatedConsteval())
1318 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt
*Node
) {
1319 if (Node
->hasInitStorage())
1321 if (Node
->hasVarStorage())
1325 void TextNodeDumper::VisitWhileStmt(const WhileStmt
*Node
) {
1326 if (Node
->hasVarStorage())
1330 void TextNodeDumper::VisitLabelStmt(const LabelStmt
*Node
) {
1331 OS
<< " '" << Node
->getName() << "'";
1332 if (Node
->isSideEntry())
1333 OS
<< " side_entry";
1336 void TextNodeDumper::VisitGotoStmt(const GotoStmt
*Node
) {
1337 OS
<< " '" << Node
->getLabel()->getName() << "'";
1338 dumpPointer(Node
->getLabel());
1341 void TextNodeDumper::VisitCaseStmt(const CaseStmt
*Node
) {
1342 if (Node
->caseStmtIsGNURange())
1346 void clang::TextNodeDumper::VisitReturnStmt(const ReturnStmt
*Node
) {
1347 if (const VarDecl
*Cand
= Node
->getNRVOCandidate()) {
1348 OS
<< " nrvo_candidate(";
1349 dumpBareDeclRef(Cand
);
1354 void clang::TextNodeDumper::VisitCoawaitExpr(const CoawaitExpr
*Node
) {
1355 if (Node
->isImplicit())
1359 void clang::TextNodeDumper::VisitCoreturnStmt(const CoreturnStmt
*Node
) {
1360 if (Node
->isImplicit())
1364 void TextNodeDumper::VisitConstantExpr(const ConstantExpr
*Node
) {
1365 if (Node
->hasAPValueResult())
1367 [=] { Visit(Node
->getAPValueResult(), Node
->getType()); });
1370 void TextNodeDumper::VisitCallExpr(const CallExpr
*Node
) {
1371 if (Node
->usesADL())
1373 if (Node
->hasStoredFPFeatures())
1374 printFPOptions(Node
->getFPFeatures());
1377 void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr
*Node
) {
1378 const char *OperatorSpelling
= clang::getOperatorSpelling(Node
->getOperator());
1379 if (OperatorSpelling
)
1380 OS
<< " '" << OperatorSpelling
<< "'";
1382 VisitCallExpr(Node
);
1385 void TextNodeDumper::VisitCastExpr(const CastExpr
*Node
) {
1388 ColorScope
Color(OS
, ShowColors
, CastColor
);
1389 OS
<< Node
->getCastKindName();
1391 dumpBasePath(OS
, Node
);
1393 if (Node
->hasStoredFPFeatures())
1394 printFPOptions(Node
->getFPFeatures());
1397 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr
*Node
) {
1398 VisitCastExpr(Node
);
1399 if (Node
->isPartOfExplicitCast())
1400 OS
<< " part_of_explicit_cast";
1403 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr
*Node
) {
1405 dumpBareDeclRef(Node
->getDecl());
1406 dumpNestedNameSpecifier(Node
->getQualifier());
1407 if (Node
->getDecl() != Node
->getFoundDecl()) {
1409 dumpBareDeclRef(Node
->getFoundDecl());
1412 switch (Node
->isNonOdrUse()) {
1413 case NOUR_None
: break;
1414 case NOUR_Unevaluated
: OS
<< " non_odr_use_unevaluated"; break;
1415 case NOUR_Constant
: OS
<< " non_odr_use_constant"; break;
1416 case NOUR_Discarded
: OS
<< " non_odr_use_discarded"; break;
1418 if (Node
->isCapturedByCopyInLambdaWithExplicitObjectParameter())
1419 OS
<< " dependent_capture";
1420 else if (Node
->refersToEnclosingVariableOrCapture())
1421 OS
<< " refers_to_enclosing_variable_or_capture";
1423 if (Node
->isImmediateEscalating())
1424 OS
<< " immediate-escalating";
1427 void clang::TextNodeDumper::VisitDependentScopeDeclRefExpr(
1428 const DependentScopeDeclRefExpr
*Node
) {
1430 dumpNestedNameSpecifier(Node
->getQualifier());
1433 void TextNodeDumper::VisitUnresolvedLookupExpr(
1434 const UnresolvedLookupExpr
*Node
) {
1436 if (!Node
->requiresADL())
1438 OS
<< "ADL) = '" << Node
->getName() << '\'';
1440 UnresolvedLookupExpr::decls_iterator I
= Node
->decls_begin(),
1441 E
= Node
->decls_end();
1448 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr
*Node
) {
1450 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
1451 OS
<< " " << Node
->getDecl()->getDeclKindName() << "Decl";
1453 OS
<< "='" << *Node
->getDecl() << "'";
1454 dumpPointer(Node
->getDecl());
1455 if (Node
->isFreeIvar())
1456 OS
<< " isFreeIvar";
1459 void TextNodeDumper::VisitSYCLUniqueStableNameExpr(
1460 const SYCLUniqueStableNameExpr
*Node
) {
1461 dumpType(Node
->getTypeSourceInfo()->getType());
1464 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr
*Node
) {
1465 OS
<< " " << PredefinedExpr::getIdentKindName(Node
->getIdentKind());
1468 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral
*Node
) {
1469 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1470 OS
<< " " << Node
->getValue();
1473 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral
*Node
) {
1474 bool isSigned
= Node
->getType()->isSignedIntegerType();
1475 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1476 OS
<< " " << toString(Node
->getValue(), 10, isSigned
);
1479 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral
*Node
) {
1480 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1481 OS
<< " " << Node
->getValueAsString(/*Radix=*/10);
1484 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral
*Node
) {
1485 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1486 OS
<< " " << Node
->getValueAsApproximateDouble();
1489 void TextNodeDumper::VisitStringLiteral(const StringLiteral
*Str
) {
1490 ColorScope
Color(OS
, ShowColors
, ValueColor
);
1492 Str
->outputString(OS
);
1495 void TextNodeDumper::VisitInitListExpr(const InitListExpr
*ILE
) {
1496 if (auto *Field
= ILE
->getInitializedFieldInUnion()) {
1498 dumpBareDeclRef(Field
);
1502 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr
*E
) {
1503 if (E
->isResultDependent())
1504 OS
<< " result_dependent";
1507 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator
*Node
) {
1508 OS
<< " " << (Node
->isPostfix() ? "postfix" : "prefix") << " '"
1509 << UnaryOperator::getOpcodeStr(Node
->getOpcode()) << "'";
1510 if (!Node
->canOverflow())
1511 OS
<< " cannot overflow";
1512 if (Node
->hasStoredFPFeatures())
1513 printFPOptions(Node
->getStoredFPFeatures());
1516 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1517 const UnaryExprOrTypeTraitExpr
*Node
) {
1518 OS
<< " " << getTraitSpelling(Node
->getKind());
1520 if (Node
->isArgumentType())
1521 dumpType(Node
->getArgumentType());
1524 void TextNodeDumper::VisitMemberExpr(const MemberExpr
*Node
) {
1525 OS
<< " " << (Node
->isArrow() ? "->" : ".") << *Node
->getMemberDecl();
1526 dumpPointer(Node
->getMemberDecl());
1527 dumpNestedNameSpecifier(Node
->getQualifier());
1528 switch (Node
->isNonOdrUse()) {
1529 case NOUR_None
: break;
1530 case NOUR_Unevaluated
: OS
<< " non_odr_use_unevaluated"; break;
1531 case NOUR_Constant
: OS
<< " non_odr_use_constant"; break;
1532 case NOUR_Discarded
: OS
<< " non_odr_use_discarded"; break;
1536 void TextNodeDumper::VisitExtVectorElementExpr(
1537 const ExtVectorElementExpr
*Node
) {
1538 OS
<< " " << Node
->getAccessor().getNameStart();
1541 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator
*Node
) {
1542 OS
<< " '" << BinaryOperator::getOpcodeStr(Node
->getOpcode()) << "'";
1543 if (Node
->hasStoredFPFeatures())
1544 printFPOptions(Node
->getStoredFPFeatures());
1547 void TextNodeDumper::VisitCompoundAssignOperator(
1548 const CompoundAssignOperator
*Node
) {
1549 OS
<< " '" << BinaryOperator::getOpcodeStr(Node
->getOpcode())
1550 << "' ComputeLHSTy=";
1551 dumpBareType(Node
->getComputationLHSType());
1552 OS
<< " ComputeResultTy=";
1553 dumpBareType(Node
->getComputationResultType());
1554 if (Node
->hasStoredFPFeatures())
1555 printFPOptions(Node
->getStoredFPFeatures());
1558 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr
*Node
) {
1559 OS
<< " " << Node
->getLabel()->getName();
1560 dumpPointer(Node
->getLabel());
1563 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr
*Node
) {
1564 OS
<< " " << Node
->getCastName() << "<"
1565 << Node
->getTypeAsWritten().getAsString() << ">"
1566 << " <" << Node
->getCastKindName();
1567 dumpBasePath(OS
, Node
);
1571 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr
*Node
) {
1572 OS
<< " " << (Node
->getValue() ? "true" : "false");
1575 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr
*Node
) {
1576 if (Node
->isImplicit())
1578 if (Node
->isCapturedByCopyInLambdaWithExplicitObjectParameter())
1579 OS
<< " dependent_capture";
1583 void TextNodeDumper::VisitCXXFunctionalCastExpr(
1584 const CXXFunctionalCastExpr
*Node
) {
1585 OS
<< " functional cast to " << Node
->getTypeAsWritten().getAsString() << " <"
1586 << Node
->getCastKindName() << ">";
1587 if (Node
->hasStoredFPFeatures())
1588 printFPOptions(Node
->getFPFeatures());
1591 void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr
*Node
) {
1592 VisitCXXNamedCastExpr(Node
);
1593 if (Node
->hasStoredFPFeatures())
1594 printFPOptions(Node
->getFPFeatures());
1597 void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
1598 const CXXUnresolvedConstructExpr
*Node
) {
1599 dumpType(Node
->getTypeAsWritten());
1600 if (Node
->isListInitialization())
1604 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr
*Node
) {
1605 CXXConstructorDecl
*Ctor
= Node
->getConstructor();
1606 dumpType(Ctor
->getType());
1607 if (Node
->isElidable())
1609 if (Node
->isListInitialization())
1611 if (Node
->isStdInitListInitialization())
1612 OS
<< " std::initializer_list";
1613 if (Node
->requiresZeroInitialization())
1615 if (Node
->isImmediateEscalating())
1616 OS
<< " immediate-escalating";
1619 void TextNodeDumper::VisitCXXBindTemporaryExpr(
1620 const CXXBindTemporaryExpr
*Node
) {
1621 OS
<< " (CXXTemporary";
1626 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr
*Node
) {
1627 if (Node
->isGlobalNew())
1629 if (Node
->isArray())
1631 if (Node
->getOperatorNew()) {
1633 dumpBareDeclRef(Node
->getOperatorNew());
1635 // We could dump the deallocation function used in case of error, but it's
1636 // usually not that interesting.
1639 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr
*Node
) {
1640 if (Node
->isGlobalDelete())
1642 if (Node
->isArrayForm())
1644 if (Node
->getOperatorDelete()) {
1646 dumpBareDeclRef(Node
->getOperatorDelete());
1650 void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr
*Node
) {
1651 OS
<< " " << getTraitSpelling(Node
->getTrait());
1654 void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr
*Node
) {
1655 OS
<< " " << getTraitSpelling(Node
->getTrait());
1658 void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr
*Node
) {
1659 OS
<< " " << getTraitSpelling(Node
->getTrait());
1662 void TextNodeDumper::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr
*Node
) {
1663 if (Node
->hasRewrittenInit())
1664 OS
<< " has rewritten init";
1667 void TextNodeDumper::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr
*Node
) {
1668 if (Node
->hasRewrittenInit())
1669 OS
<< " has rewritten init";
1672 void TextNodeDumper::VisitMaterializeTemporaryExpr(
1673 const MaterializeTemporaryExpr
*Node
) {
1674 if (const ValueDecl
*VD
= Node
->getExtendingDecl()) {
1675 OS
<< " extended by ";
1676 dumpBareDeclRef(VD
);
1680 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups
*Node
) {
1681 for (unsigned i
= 0, e
= Node
->getNumObjects(); i
!= e
; ++i
)
1682 dumpCleanupObject(Node
->getObject(i
));
1685 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr
*Node
) {
1686 dumpPointer(Node
->getPack());
1687 dumpName(Node
->getPack());
1690 void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
1691 const CXXDependentScopeMemberExpr
*Node
) {
1692 OS
<< " " << (Node
->isArrow() ? "->" : ".") << Node
->getMember();
1695 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr
*Node
) {
1697 Node
->getSelector().print(OS
);
1698 switch (Node
->getReceiverKind()) {
1699 case ObjCMessageExpr::Instance
:
1702 case ObjCMessageExpr::Class
:
1704 dumpBareType(Node
->getClassReceiver());
1707 case ObjCMessageExpr::SuperInstance
:
1708 OS
<< " super (instance)";
1711 case ObjCMessageExpr::SuperClass
:
1712 OS
<< " super (class)";
1717 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr
*Node
) {
1718 if (auto *BoxingMethod
= Node
->getBoxingMethod()) {
1720 BoxingMethod
->getSelector().print(OS
);
1724 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt
*Node
) {
1725 if (!Node
->getCatchParamDecl())
1729 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr
*Node
) {
1730 dumpType(Node
->getEncodedType());
1733 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr
*Node
) {
1735 Node
->getSelector().print(OS
);
1738 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr
*Node
) {
1739 OS
<< ' ' << *Node
->getProtocol();
1742 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr
*Node
) {
1743 if (Node
->isImplicitProperty()) {
1744 OS
<< " Kind=MethodRef Getter=\"";
1745 if (Node
->getImplicitPropertyGetter())
1746 Node
->getImplicitPropertyGetter()->getSelector().print(OS
);
1750 OS
<< "\" Setter=\"";
1751 if (ObjCMethodDecl
*Setter
= Node
->getImplicitPropertySetter())
1752 Setter
->getSelector().print(OS
);
1757 OS
<< " Kind=PropertyRef Property=\"" << *Node
->getExplicitProperty()
1761 if (Node
->isSuperReceiver())
1764 OS
<< " Messaging=";
1765 if (Node
->isMessagingGetter() && Node
->isMessagingSetter())
1766 OS
<< "Getter&Setter";
1767 else if (Node
->isMessagingGetter())
1769 else if (Node
->isMessagingSetter())
1773 void TextNodeDumper::VisitObjCSubscriptRefExpr(
1774 const ObjCSubscriptRefExpr
*Node
) {
1775 if (Node
->isArraySubscriptRefExpr())
1776 OS
<< " Kind=ArraySubscript GetterForArray=\"";
1778 OS
<< " Kind=DictionarySubscript GetterForDictionary=\"";
1779 if (Node
->getAtIndexMethodDecl())
1780 Node
->getAtIndexMethodDecl()->getSelector().print(OS
);
1784 if (Node
->isArraySubscriptRefExpr())
1785 OS
<< "\" SetterForArray=\"";
1787 OS
<< "\" SetterForDictionary=\"";
1788 if (Node
->setAtIndexMethodDecl())
1789 Node
->setAtIndexMethodDecl()->getSelector().print(OS
);
1794 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr
*Node
) {
1795 OS
<< " " << (Node
->getValue() ? "__objc_yes" : "__objc_no");
1798 void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr
*Node
) {
1800 for (unsigned I
= 0, E
= Node
->numOfIterators(); I
< E
; ++I
) {
1801 Visit(Node
->getIteratorDecl(I
));
1803 const OMPIteratorExpr::IteratorRange Range
= Node
->getIteratorRange(I
);
1815 void TextNodeDumper::VisitConceptSpecializationExpr(
1816 const ConceptSpecializationExpr
*Node
) {
1818 dumpBareDeclRef(Node
->getFoundDecl());
1821 void TextNodeDumper::VisitRequiresExpr(
1822 const RequiresExpr
*Node
) {
1823 if (!Node
->isValueDependent())
1824 OS
<< (Node
->isSatisfied() ? " satisfied" : " unsatisfied");
1827 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType
*T
) {
1828 if (T
->isSpelledAsLValue())
1829 OS
<< " written as lvalue reference";
1832 void TextNodeDumper::VisitArrayType(const ArrayType
*T
) {
1833 switch (T
->getSizeModifier()) {
1834 case ArraySizeModifier::Normal
:
1836 case ArraySizeModifier::Static
:
1839 case ArraySizeModifier::Star
:
1843 OS
<< " " << T
->getIndexTypeQualifiers().getAsString();
1846 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType
*T
) {
1847 OS
<< " " << T
->getSize();
1851 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType
*T
) {
1853 dumpSourceRange(T
->getBracketsRange());
1857 void TextNodeDumper::VisitDependentSizedArrayType(
1858 const DependentSizedArrayType
*T
) {
1861 dumpSourceRange(T
->getBracketsRange());
1864 void TextNodeDumper::VisitDependentSizedExtVectorType(
1865 const DependentSizedExtVectorType
*T
) {
1867 dumpLocation(T
->getAttributeLoc());
1870 void TextNodeDumper::VisitVectorType(const VectorType
*T
) {
1871 switch (T
->getVectorKind()) {
1872 case VectorKind::Generic
:
1874 case VectorKind::AltiVecVector
:
1877 case VectorKind::AltiVecPixel
:
1878 OS
<< " altivec pixel";
1880 case VectorKind::AltiVecBool
:
1881 OS
<< " altivec bool";
1883 case VectorKind::Neon
:
1886 case VectorKind::NeonPoly
:
1889 case VectorKind::SveFixedLengthData
:
1890 OS
<< " fixed-length sve data vector";
1892 case VectorKind::SveFixedLengthPredicate
:
1893 OS
<< " fixed-length sve predicate vector";
1895 case VectorKind::RVVFixedLengthData
:
1896 OS
<< " fixed-length rvv data vector";
1898 case VectorKind::RVVFixedLengthMask
:
1899 case VectorKind::RVVFixedLengthMask_1
:
1900 case VectorKind::RVVFixedLengthMask_2
:
1901 case VectorKind::RVVFixedLengthMask_4
:
1902 OS
<< " fixed-length rvv mask vector";
1905 OS
<< " " << T
->getNumElements();
1908 void TextNodeDumper::VisitFunctionType(const FunctionType
*T
) {
1909 auto EI
= T
->getExtInfo();
1910 if (EI
.getNoReturn())
1912 if (EI
.getProducesResult())
1913 OS
<< " produces_result";
1914 if (EI
.getHasRegParm())
1915 OS
<< " regparm " << EI
.getRegParm();
1916 OS
<< " " << FunctionType::getNameForCallConv(EI
.getCC());
1919 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType
*T
) {
1920 auto EPI
= T
->getExtProtoInfo();
1921 if (EPI
.HasTrailingReturn
)
1922 OS
<< " trailing_return";
1925 if (T
->isVolatile())
1927 if (T
->isRestrict())
1929 if (T
->getExtProtoInfo().Variadic
)
1931 switch (EPI
.RefQualifier
) {
1942 switch (EPI
.ExceptionSpec
.Type
) {
1945 case EST_DynamicNone
:
1946 OS
<< " exceptionspec_dynamic_none";
1949 OS
<< " exceptionspec_dynamic";
1952 OS
<< " exceptionspec_ms_any";
1955 OS
<< " exceptionspec_nothrow";
1957 case EST_BasicNoexcept
:
1958 OS
<< " exceptionspec_basic_noexcept";
1960 case EST_DependentNoexcept
:
1961 OS
<< " exceptionspec_dependent_noexcept";
1963 case EST_NoexceptFalse
:
1964 OS
<< " exceptionspec_noexcept_false";
1966 case EST_NoexceptTrue
:
1967 OS
<< " exceptionspec_noexcept_true";
1969 case EST_Unevaluated
:
1970 OS
<< " exceptionspec_unevaluated";
1972 case EST_Uninstantiated
:
1973 OS
<< " exceptionspec_uninstantiated";
1976 OS
<< " exceptionspec_unparsed";
1979 if (!EPI
.ExceptionSpec
.Exceptions
.empty()) {
1981 OS
<< "Exceptions:";
1982 for (unsigned I
= 0, N
= EPI
.ExceptionSpec
.Exceptions
.size(); I
!= N
;
1986 dumpType(EPI
.ExceptionSpec
.Exceptions
[I
]);
1990 if (EPI
.ExceptionSpec
.NoexceptExpr
) {
1992 OS
<< "NoexceptExpr: ";
1993 Visit(EPI
.ExceptionSpec
.NoexceptExpr
);
1996 dumpDeclRef(EPI
.ExceptionSpec
.SourceDecl
, "ExceptionSourceDecl");
1997 dumpDeclRef(EPI
.ExceptionSpec
.SourceTemplate
, "ExceptionSourceTemplate");
1999 // FIXME: Consumed parameters.
2000 VisitFunctionType(T
);
2003 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType
*T
) {
2004 dumpDeclRef(T
->getDecl());
2007 void TextNodeDumper::VisitUsingType(const UsingType
*T
) {
2008 dumpDeclRef(T
->getFoundDecl());
2009 if (!T
->typeMatchesDecl())
2013 void TextNodeDumper::VisitTypedefType(const TypedefType
*T
) {
2014 dumpDeclRef(T
->getDecl());
2015 if (!T
->typeMatchesDecl())
2019 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType
*T
) {
2020 switch (T
->getUTTKind()) {
2021 #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
2022 case UnaryTransformType::Enum: \
2025 #include "clang/Basic/TransformTypeTraits.def"
2029 void TextNodeDumper::VisitTagType(const TagType
*T
) {
2030 dumpDeclRef(T
->getDecl());
2033 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType
*T
) {
2034 OS
<< " depth " << T
->getDepth() << " index " << T
->getIndex();
2035 if (T
->isParameterPack())
2037 dumpDeclRef(T
->getDecl());
2040 void TextNodeDumper::VisitSubstTemplateTypeParmType(
2041 const SubstTemplateTypeParmType
*T
) {
2042 dumpDeclRef(T
->getAssociatedDecl());
2043 VisitTemplateTypeParmDecl(T
->getReplacedParameter());
2044 if (auto PackIndex
= T
->getPackIndex())
2045 OS
<< " pack_index " << *PackIndex
;
2048 void TextNodeDumper::VisitSubstTemplateTypeParmPackType(
2049 const SubstTemplateTypeParmPackType
*T
) {
2050 dumpDeclRef(T
->getAssociatedDecl());
2051 VisitTemplateTypeParmDecl(T
->getReplacedParameter());
2054 void TextNodeDumper::VisitAutoType(const AutoType
*T
) {
2055 if (T
->isDecltypeAuto())
2056 OS
<< " decltype(auto)";
2057 if (!T
->isDeduced())
2059 if (T
->isConstrained())
2060 dumpDeclRef(T
->getTypeConstraintConcept());
2063 void TextNodeDumper::VisitDeducedTemplateSpecializationType(
2064 const DeducedTemplateSpecializationType
*T
) {
2065 dumpTemplateName(T
->getTemplateName(), "name");
2068 void TextNodeDumper::VisitTemplateSpecializationType(
2069 const TemplateSpecializationType
*T
) {
2070 if (T
->isTypeAlias())
2072 dumpTemplateName(T
->getTemplateName(), "name");
2075 void TextNodeDumper::VisitInjectedClassNameType(
2076 const InjectedClassNameType
*T
) {
2077 dumpDeclRef(T
->getDecl());
2080 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType
*T
) {
2081 dumpDeclRef(T
->getDecl());
2084 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType
*T
) {
2085 if (auto N
= T
->getNumExpansions())
2086 OS
<< " expansions " << *N
;
2089 void TextNodeDumper::VisitTypeLoc(TypeLoc TL
) {
2090 // By default, add extra Type details with no extra loc info.
2091 TypeVisitor
<TextNodeDumper
>::Visit(TL
.getTypePtr());
2093 // FIXME: override behavior for TypeLocs that have interesting location
2094 // information, such as the qualifier in ElaboratedTypeLoc.
2096 void TextNodeDumper::VisitLabelDecl(const LabelDecl
*D
) { dumpName(D
); }
2098 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl
*D
) {
2100 dumpType(D
->getUnderlyingType());
2101 if (D
->isModulePrivate())
2102 OS
<< " __module_private__";
2105 void TextNodeDumper::VisitEnumDecl(const EnumDecl
*D
) {
2106 if (D
->isScoped()) {
2107 if (D
->isScopedUsingClassTag())
2113 if (D
->isModulePrivate())
2114 OS
<< " __module_private__";
2116 dumpType(D
->getIntegerType());
2119 void TextNodeDumper::VisitRecordDecl(const RecordDecl
*D
) {
2120 OS
<< ' ' << D
->getKindName();
2122 if (D
->isModulePrivate())
2123 OS
<< " __module_private__";
2124 if (D
->isCompleteDefinition())
2125 OS
<< " definition";
2128 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl
*D
) {
2130 dumpType(D
->getType());
2133 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl
*D
) {
2135 dumpType(D
->getType());
2137 for (const auto *Child
: D
->chain())
2141 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl
*D
) {
2143 dumpType(D
->getType());
2144 dumpTemplateSpecializationKind(D
->getTemplateSpecializationKind());
2146 StorageClass SC
= D
->getStorageClass();
2148 OS
<< ' ' << VarDecl::getStorageClassSpecifierString(SC
);
2149 if (D
->isInlineSpecified())
2151 if (D
->isVirtualAsWritten())
2153 if (D
->isModulePrivate())
2154 OS
<< " __module_private__";
2156 if (D
->isPureVirtual())
2158 if (D
->isDefaulted()) {
2163 if (D
->isDeletedAsWritten())
2168 if (const StringLiteral
*M
= D
->getDeletedMessage())
2169 AddChild("delete message", [=] { Visit(M
); });
2171 if (D
->isIneligibleOrNotSelected())
2172 OS
<< (isa
<CXXDestructorDecl
>(D
) ? " not_selected" : " ineligible");
2174 if (const auto *FPT
= D
->getType()->getAs
<FunctionProtoType
>()) {
2175 FunctionProtoType::ExtProtoInfo EPI
= FPT
->getExtProtoInfo();
2176 switch (EPI
.ExceptionSpec
.Type
) {
2179 case EST_Unevaluated
:
2180 OS
<< " noexcept-unevaluated " << EPI
.ExceptionSpec
.SourceDecl
;
2182 case EST_Uninstantiated
:
2183 OS
<< " noexcept-uninstantiated " << EPI
.ExceptionSpec
.SourceTemplate
;
2188 if (const auto *MD
= dyn_cast
<CXXMethodDecl
>(D
)) {
2189 if (MD
->size_overridden_methods() != 0) {
2190 auto dumpOverride
= [=](const CXXMethodDecl
*D
) {
2191 SplitQualType T_split
= D
->getType().split();
2192 OS
<< D
<< " " << D
->getParent()->getName() << "::" << D
->getDeclName()
2193 << " '" << QualType::getAsString(T_split
, PrintPolicy
) << "'";
2197 auto Overrides
= MD
->overridden_methods();
2198 OS
<< "Overrides: [ ";
2199 dumpOverride(*Overrides
.begin());
2200 for (const auto *Override
: llvm::drop_begin(Overrides
)) {
2202 dumpOverride(Override
);
2209 if (!D
->isInlineSpecified() && D
->isInlined()) {
2210 OS
<< " implicit-inline";
2212 // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
2213 // the Params are set later, it is possible for a dump during debugging to
2214 // encounter a FunctionDecl that has been created but hasn't been assigned
2215 // ParmVarDecls yet.
2216 if (!D
->param_empty() && !D
->param_begin())
2217 OS
<< " <<<NULL params x " << D
->getNumParams() << ">>>";
2219 if (const auto *Instance
= D
->getInstantiatedFromMemberFunction()) {
2220 OS
<< " instantiated_from";
2221 dumpPointer(Instance
);
2225 void TextNodeDumper::VisitCXXDeductionGuideDecl(
2226 const CXXDeductionGuideDecl
*D
) {
2227 VisitFunctionDecl(D
);
2228 switch (D
->getDeductionCandidateKind()) {
2229 case DeductionCandidate::Normal
:
2230 case DeductionCandidate::Copy
:
2232 case DeductionCandidate::Aggregate
:
2233 OS
<< " aggregate ";
2238 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
2239 const LifetimeExtendedTemporaryDecl
*D
) {
2240 OS
<< " extended by ";
2241 dumpBareDeclRef(D
->getExtendingDecl());
2244 ColorScope
Color(OS
, ShowColors
, ValueColor
);
2245 OS
<< D
->getManglingNumber();
2249 void TextNodeDumper::VisitFieldDecl(const FieldDecl
*D
) {
2251 dumpType(D
->getType());
2254 if (D
->isModulePrivate())
2255 OS
<< " __module_private__";
2258 void TextNodeDumper::VisitVarDecl(const VarDecl
*D
) {
2259 dumpNestedNameSpecifier(D
->getQualifier());
2261 if (const auto *P
= dyn_cast
<ParmVarDecl
>(D
);
2262 P
&& P
->isExplicitObjectParameter())
2265 dumpType(D
->getType());
2266 dumpTemplateSpecializationKind(D
->getTemplateSpecializationKind());
2267 StorageClass SC
= D
->getStorageClass();
2269 OS
<< ' ' << VarDecl::getStorageClassSpecifierString(SC
);
2270 switch (D
->getTLSKind()) {
2271 case VarDecl::TLS_None
:
2273 case VarDecl::TLS_Static
:
2276 case VarDecl::TLS_Dynamic
:
2277 OS
<< " tls_dynamic";
2280 if (D
->isModulePrivate())
2281 OS
<< " __module_private__";
2282 if (D
->isNRVOVariable())
2286 if (D
->isConstexpr())
2289 switch (D
->getInitStyle()) {
2290 case VarDecl::CInit
:
2293 case VarDecl::CallInit
:
2296 case VarDecl::ListInit
:
2299 case VarDecl::ParenListInit
:
2300 OS
<< " parenlistinit";
2303 if (D
->needsDestruction(D
->getASTContext()))
2305 if (D
->isParameterPack())
2309 const Expr
*E
= D
->getInit();
2310 // Only dump the value of constexpr VarDecls for now.
2311 if (E
&& !E
->isValueDependent() && D
->isConstexpr() &&
2312 !D
->getType()->isDependentType()) {
2313 const APValue
*Value
= D
->evaluateValue();
2315 AddChild("value", [=] { Visit(*Value
, E
->getType()); });
2320 void TextNodeDumper::VisitBindingDecl(const BindingDecl
*D
) {
2322 dumpType(D
->getType());
2325 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl
*D
) {
2330 void TextNodeDumper::VisitImportDecl(const ImportDecl
*D
) {
2331 OS
<< ' ' << D
->getImportedModule()->getFullModuleName();
2334 D
->getASTContext().getModuleInitializers(D
->getImportedModule()))
2335 dumpDeclRef(InitD
, "initializer");
2338 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl
*D
) {
2340 switch (D
->getCommentKind()) {
2342 llvm_unreachable("unexpected pragma comment kind");
2359 StringRef Arg
= D
->getArg();
2361 OS
<< " \"" << Arg
<< "\"";
2364 void TextNodeDumper::VisitPragmaDetectMismatchDecl(
2365 const PragmaDetectMismatchDecl
*D
) {
2366 OS
<< " \"" << D
->getName() << "\" \"" << D
->getValue() << "\"";
2369 void TextNodeDumper::VisitOMPExecutableDirective(
2370 const OMPExecutableDirective
*D
) {
2371 if (D
->isStandaloneDirective())
2372 OS
<< " openmp_standalone_directive";
2375 void TextNodeDumper::VisitOMPDeclareReductionDecl(
2376 const OMPDeclareReductionDecl
*D
) {
2378 dumpType(D
->getType());
2380 dumpPointer(D
->getCombiner());
2381 if (const auto *Initializer
= D
->getInitializer()) {
2382 OS
<< " initializer";
2383 dumpPointer(Initializer
);
2384 switch (D
->getInitializerKind()) {
2385 case OMPDeclareReductionInitKind::Direct
:
2386 OS
<< " omp_priv = ";
2388 case OMPDeclareReductionInitKind::Copy
:
2389 OS
<< " omp_priv ()";
2391 case OMPDeclareReductionInitKind::Call
:
2397 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl
*D
) {
2398 for (const auto *C
: D
->clauselists()) {
2401 ColorScope
Color(OS
, ShowColors
, NullColor
);
2402 OS
<< "<<<NULL>>> OMPClause";
2406 ColorScope
Color(OS
, ShowColors
, AttrColor
);
2407 StringRef
ClauseName(
2408 llvm::omp::getOpenMPClauseName(C
->getClauseKind()));
2409 OS
<< "OMP" << ClauseName
.substr(/*Start=*/0, /*N=*/1).upper()
2410 << ClauseName
.drop_front() << "Clause";
2413 dumpSourceRange(SourceRange(C
->getBeginLoc(), C
->getEndLoc()));
2418 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl
*D
) {
2420 dumpType(D
->getType());
2423 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl
*D
) {
2429 if (!D
->isFirstDecl())
2430 dumpDeclRef(D
->getFirstDecl(), "original");
2433 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl
*D
) {
2435 dumpBareDeclRef(D
->getNominatedNamespace());
2438 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl
*D
) {
2440 dumpDeclRef(D
->getAliasedNamespace());
2443 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl
*D
) {
2445 dumpType(D
->getUnderlyingType());
2448 void TextNodeDumper::VisitTypeAliasTemplateDecl(
2449 const TypeAliasTemplateDecl
*D
) {
2453 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl
*D
) {
2455 if (const auto *Instance
= D
->getInstantiatedFromMemberClass()) {
2456 OS
<< " instantiated_from";
2457 dumpPointer(Instance
);
2459 if (const auto *CTSD
= dyn_cast
<ClassTemplateSpecializationDecl
>(D
))
2460 dumpTemplateSpecializationKind(CTSD
->getSpecializationKind());
2462 dumpNestedNameSpecifier(D
->getQualifier());
2464 if (!D
->isCompleteDefinition())
2469 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2470 OS
<< "DefinitionData";
2472 #define FLAG(fn, name) \
2475 FLAG(isParsingBaseSpecifiers
, parsing_base_specifiers
);
2477 FLAG(isGenericLambda
, generic
);
2478 FLAG(isLambda
, lambda
);
2480 FLAG(isAnonymousStructOrUnion
, is_anonymous
);
2481 FLAG(canPassInRegisters
, pass_in_registers
);
2482 FLAG(isEmpty
, empty
);
2483 FLAG(isAggregate
, aggregate
);
2484 FLAG(isStandardLayout
, standard_layout
);
2485 FLAG(isTriviallyCopyable
, trivially_copyable
);
2487 FLAG(isTrivial
, trivial
);
2488 FLAG(isPolymorphic
, polymorphic
);
2489 FLAG(isAbstract
, abstract
);
2490 FLAG(isLiteral
, literal
);
2492 FLAG(hasUserDeclaredConstructor
, has_user_declared_ctor
);
2493 FLAG(hasConstexprNonCopyMoveConstructor
, has_constexpr_non_copy_move_ctor
);
2494 FLAG(hasMutableFields
, has_mutable_fields
);
2495 FLAG(hasVariantMembers
, has_variant_members
);
2496 FLAG(allowConstDefaultInit
, can_const_default_init
);
2500 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2501 OS
<< "DefaultConstructor";
2503 FLAG(hasDefaultConstructor
, exists
);
2504 FLAG(hasTrivialDefaultConstructor
, trivial
);
2505 FLAG(hasNonTrivialDefaultConstructor
, non_trivial
);
2506 FLAG(hasUserProvidedDefaultConstructor
, user_provided
);
2507 FLAG(hasConstexprDefaultConstructor
, constexpr);
2508 FLAG(needsImplicitDefaultConstructor
, needs_implicit
);
2509 FLAG(defaultedDefaultConstructorIsConstexpr
, defaulted_is_constexpr
);
2514 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2515 OS
<< "CopyConstructor";
2517 FLAG(hasSimpleCopyConstructor
, simple
);
2518 FLAG(hasTrivialCopyConstructor
, trivial
);
2519 FLAG(hasNonTrivialCopyConstructor
, non_trivial
);
2520 FLAG(hasUserDeclaredCopyConstructor
, user_declared
);
2521 FLAG(hasCopyConstructorWithConstParam
, has_const_param
);
2522 FLAG(needsImplicitCopyConstructor
, needs_implicit
);
2523 FLAG(needsOverloadResolutionForCopyConstructor
,
2524 needs_overload_resolution
);
2525 if (!D
->needsOverloadResolutionForCopyConstructor())
2526 FLAG(defaultedCopyConstructorIsDeleted
, defaulted_is_deleted
);
2527 FLAG(implicitCopyConstructorHasConstParam
, implicit_has_const_param
);
2532 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2533 OS
<< "MoveConstructor";
2535 FLAG(hasMoveConstructor
, exists
);
2536 FLAG(hasSimpleMoveConstructor
, simple
);
2537 FLAG(hasTrivialMoveConstructor
, trivial
);
2538 FLAG(hasNonTrivialMoveConstructor
, non_trivial
);
2539 FLAG(hasUserDeclaredMoveConstructor
, user_declared
);
2540 FLAG(needsImplicitMoveConstructor
, needs_implicit
);
2541 FLAG(needsOverloadResolutionForMoveConstructor
,
2542 needs_overload_resolution
);
2543 if (!D
->needsOverloadResolutionForMoveConstructor())
2544 FLAG(defaultedMoveConstructorIsDeleted
, defaulted_is_deleted
);
2549 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2550 OS
<< "CopyAssignment";
2552 FLAG(hasSimpleCopyAssignment
, simple
);
2553 FLAG(hasTrivialCopyAssignment
, trivial
);
2554 FLAG(hasNonTrivialCopyAssignment
, non_trivial
);
2555 FLAG(hasCopyAssignmentWithConstParam
, has_const_param
);
2556 FLAG(hasUserDeclaredCopyAssignment
, user_declared
);
2557 FLAG(needsImplicitCopyAssignment
, needs_implicit
);
2558 FLAG(needsOverloadResolutionForCopyAssignment
, needs_overload_resolution
);
2559 FLAG(implicitCopyAssignmentHasConstParam
, implicit_has_const_param
);
2564 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2565 OS
<< "MoveAssignment";
2567 FLAG(hasMoveAssignment
, exists
);
2568 FLAG(hasSimpleMoveAssignment
, simple
);
2569 FLAG(hasTrivialMoveAssignment
, trivial
);
2570 FLAG(hasNonTrivialMoveAssignment
, non_trivial
);
2571 FLAG(hasUserDeclaredMoveAssignment
, user_declared
);
2572 FLAG(needsImplicitMoveAssignment
, needs_implicit
);
2573 FLAG(needsOverloadResolutionForMoveAssignment
, needs_overload_resolution
);
2578 ColorScope
Color(OS
, ShowColors
, DeclKindNameColor
);
2581 FLAG(hasSimpleDestructor
, simple
);
2582 FLAG(hasIrrelevantDestructor
, irrelevant
);
2583 FLAG(hasTrivialDestructor
, trivial
);
2584 FLAG(hasNonTrivialDestructor
, non_trivial
);
2585 FLAG(hasUserDeclaredDestructor
, user_declared
);
2586 FLAG(hasConstexprDestructor
, constexpr);
2587 FLAG(needsImplicitDestructor
, needs_implicit
);
2588 FLAG(needsOverloadResolutionForDestructor
, needs_overload_resolution
);
2589 if (!D
->needsOverloadResolutionForDestructor())
2590 FLAG(defaultedDestructorIsDeleted
, defaulted_is_deleted
);
2594 for (const auto &I
: D
->bases()) {
2598 dumpAccessSpecifier(I
.getAccessSpecifier());
2599 dumpType(I
.getType());
2600 if (I
.isPackExpansion())
2606 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl
*D
) {
2610 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl
*D
) {
2614 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl
*D
) {
2618 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl
*D
) {
2622 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl
*D
) {
2623 if (const auto *TC
= D
->getTypeConstraint()) {
2625 dumpBareDeclRef(TC
->getNamedConcept());
2626 if (TC
->getNamedConcept() != TC
->getFoundDecl()) {
2628 dumpBareDeclRef(TC
->getFoundDecl());
2631 } else if (D
->wasDeclaredWithTypename())
2635 OS
<< " depth " << D
->getDepth() << " index " << D
->getIndex();
2636 if (D
->isParameterPack())
2641 void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2642 const NonTypeTemplateParmDecl
*D
) {
2643 dumpType(D
->getType());
2644 OS
<< " depth " << D
->getDepth() << " index " << D
->getIndex();
2645 if (D
->isParameterPack())
2650 void TextNodeDumper::VisitTemplateTemplateParmDecl(
2651 const TemplateTemplateParmDecl
*D
) {
2652 OS
<< " depth " << D
->getDepth() << " index " << D
->getIndex();
2653 if (D
->isParameterPack())
2658 void TextNodeDumper::VisitUsingDecl(const UsingDecl
*D
) {
2660 if (D
->getQualifier())
2661 D
->getQualifier()->print(OS
, D
->getASTContext().getPrintingPolicy());
2662 OS
<< D
->getDeclName();
2663 dumpNestedNameSpecifier(D
->getQualifier());
2666 void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl
*D
) {
2668 dumpBareDeclRef(D
->getEnumDecl());
2671 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2672 const UnresolvedUsingTypenameDecl
*D
) {
2674 if (D
->getQualifier())
2675 D
->getQualifier()->print(OS
, D
->getASTContext().getPrintingPolicy());
2676 OS
<< D
->getDeclName();
2679 void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2680 const UnresolvedUsingValueDecl
*D
) {
2682 if (D
->getQualifier())
2683 D
->getQualifier()->print(OS
, D
->getASTContext().getPrintingPolicy());
2684 OS
<< D
->getDeclName();
2685 dumpType(D
->getType());
2688 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl
*D
) {
2690 dumpBareDeclRef(D
->getTargetDecl());
2693 void TextNodeDumper::VisitConstructorUsingShadowDecl(
2694 const ConstructorUsingShadowDecl
*D
) {
2695 if (D
->constructsVirtualBase())
2700 dumpBareDeclRef(D
->getTargetDecl());
2705 dumpBareDeclRef(D
->getNominatedBaseClass());
2707 dumpBareDeclRef(D
->getNominatedBaseClassShadowDecl());
2711 OS
<< "constructed ";
2712 dumpBareDeclRef(D
->getConstructedBaseClass());
2714 dumpBareDeclRef(D
->getConstructedBaseClassShadowDecl());
2718 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl
*D
) {
2719 switch (D
->getLanguage()) {
2720 case LinkageSpecLanguageIDs::C
:
2723 case LinkageSpecLanguageIDs::CXX
:
2729 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl
*D
) {
2731 dumpAccessSpecifier(D
->getAccess());
2734 void TextNodeDumper::VisitFriendDecl(const FriendDecl
*D
) {
2735 if (TypeSourceInfo
*T
= D
->getFriendType())
2736 dumpType(T
->getType());
2737 if (D
->isPackExpansion())
2741 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl
*D
) {
2743 dumpType(D
->getType());
2744 if (D
->getSynthesize())
2745 OS
<< " synthesize";
2747 switch (D
->getAccessControl()) {
2748 case ObjCIvarDecl::None
:
2751 case ObjCIvarDecl::Private
:
2754 case ObjCIvarDecl::Protected
:
2757 case ObjCIvarDecl::Public
:
2760 case ObjCIvarDecl::Package
:
2766 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl
*D
) {
2767 if (D
->isInstanceMethod())
2772 dumpType(D
->getReturnType());
2774 if (D
->isVariadic())
2778 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl
*D
) {
2780 switch (D
->getVariance()) {
2781 case ObjCTypeParamVariance::Invariant
:
2784 case ObjCTypeParamVariance::Covariant
:
2788 case ObjCTypeParamVariance::Contravariant
:
2789 OS
<< " contravariant";
2793 if (D
->hasExplicitBound())
2795 dumpType(D
->getUnderlyingType());
2798 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl
*D
) {
2800 dumpDeclRef(D
->getClassInterface());
2801 dumpDeclRef(D
->getImplementation());
2802 for (const auto *P
: D
->protocols())
2806 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl
*D
) {
2808 dumpDeclRef(D
->getClassInterface());
2809 dumpDeclRef(D
->getCategoryDecl());
2812 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl
*D
) {
2815 for (const auto *Child
: D
->protocols())
2819 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl
*D
) {
2821 dumpDeclRef(D
->getSuperClass(), "super");
2823 dumpDeclRef(D
->getImplementation());
2824 for (const auto *Child
: D
->protocols())
2828 void TextNodeDumper::VisitObjCImplementationDecl(
2829 const ObjCImplementationDecl
*D
) {
2831 dumpDeclRef(D
->getSuperClass(), "super");
2832 dumpDeclRef(D
->getClassInterface());
2835 void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2836 const ObjCCompatibleAliasDecl
*D
) {
2838 dumpDeclRef(D
->getClassInterface());
2841 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl
*D
) {
2843 dumpType(D
->getType());
2845 if (D
->getPropertyImplementation() == ObjCPropertyDecl::Required
)
2847 else if (D
->getPropertyImplementation() == ObjCPropertyDecl::Optional
)
2850 ObjCPropertyAttribute::Kind Attrs
= D
->getPropertyAttributes();
2851 if (Attrs
!= ObjCPropertyAttribute::kind_noattr
) {
2852 if (Attrs
& ObjCPropertyAttribute::kind_readonly
)
2854 if (Attrs
& ObjCPropertyAttribute::kind_assign
)
2856 if (Attrs
& ObjCPropertyAttribute::kind_readwrite
)
2858 if (Attrs
& ObjCPropertyAttribute::kind_retain
)
2860 if (Attrs
& ObjCPropertyAttribute::kind_copy
)
2862 if (Attrs
& ObjCPropertyAttribute::kind_nonatomic
)
2864 if (Attrs
& ObjCPropertyAttribute::kind_atomic
)
2866 if (Attrs
& ObjCPropertyAttribute::kind_weak
)
2868 if (Attrs
& ObjCPropertyAttribute::kind_strong
)
2870 if (Attrs
& ObjCPropertyAttribute::kind_unsafe_unretained
)
2871 OS
<< " unsafe_unretained";
2872 if (Attrs
& ObjCPropertyAttribute::kind_class
)
2874 if (Attrs
& ObjCPropertyAttribute::kind_direct
)
2876 if (Attrs
& ObjCPropertyAttribute::kind_getter
)
2877 dumpDeclRef(D
->getGetterMethodDecl(), "getter");
2878 if (Attrs
& ObjCPropertyAttribute::kind_setter
)
2879 dumpDeclRef(D
->getSetterMethodDecl(), "setter");
2883 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl
*D
) {
2884 dumpName(D
->getPropertyDecl());
2885 if (D
->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize
)
2886 OS
<< " synthesize";
2889 dumpDeclRef(D
->getPropertyDecl());
2890 dumpDeclRef(D
->getPropertyIvarDecl());
2893 void TextNodeDumper::VisitBlockDecl(const BlockDecl
*D
) {
2894 if (D
->isVariadic())
2897 if (D
->capturesCXXThis())
2898 OS
<< " captures_this";
2901 void TextNodeDumper::VisitConceptDecl(const ConceptDecl
*D
) {
2905 void TextNodeDumper::VisitCompoundStmt(const CompoundStmt
*S
) {
2907 if (S
->hasStoredFPFeatures())
2908 printFPOptions(S
->getStoredFPFeatures());
2911 void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl
*D
) {
2919 void TextNodeDumper::VisitHLSLOutArgExpr(const HLSLOutArgExpr
*E
) {
2920 OS
<< (E
->isInOut() ? " inout" : " out");
2923 void TextNodeDumper::VisitOpenACCConstructStmt(const OpenACCConstructStmt
*S
) {
2924 OS
<< " " << S
->getDirectiveKind();
2926 void TextNodeDumper::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct
*S
) {
2928 if (S
->isOrphanedLoopConstruct())
2931 OS
<< " parent: " << S
->getParentComputeConstructKind();
2934 void TextNodeDumper::VisitOpenACCCombinedConstruct(
2935 const OpenACCCombinedConstruct
*S
) {
2936 OS
<< " " << S
->getDirectiveKind();
2939 void TextNodeDumper::VisitEmbedExpr(const EmbedExpr
*S
) {
2940 AddChild("begin", [=] { OS
<< S
->getStartingElementPos(); });
2941 AddChild("number of elements", [=] { OS
<< S
->getDataElementCount(); });
2944 void TextNodeDumper::VisitAtomicExpr(const AtomicExpr
*AE
) {
2945 OS
<< ' ' << AE
->getOpAsString();