[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / lib / AST / TextNodeDumper.cpp
blob8d0f421e3a7dbc9cd1f3f33046331ec0089fb7cb
1 //===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements AST dumping of components of individual AST nodes.
11 //===----------------------------------------------------------------------===//
13 #include "clang/AST/TextNodeDumper.h"
14 #include "clang/AST/APValue.h"
15 #include "clang/AST/DeclFriend.h"
16 #include "clang/AST/DeclOpenMP.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/LocInfoType.h"
19 #include "clang/AST/NestedNameSpecifier.h"
20 #include "clang/AST/Type.h"
21 #include "clang/Basic/Module.h"
22 #include "clang/Basic/SourceManager.h"
23 #include "clang/Basic/Specifiers.h"
24 #include "clang/Basic/TypeTraits.h"
25 #include "llvm/ADT/StringExtras.h"
27 #include <algorithm>
28 #include <utility>
30 using namespace clang;
32 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
34 template <typename T>
35 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
36 const T *First = D->getFirstDecl();
37 if (First != D)
38 OS << " first " << First;
41 template <typename T>
42 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
43 const T *Prev = D->getPreviousDecl();
44 if (Prev)
45 OS << " prev " << Prev;
48 /// Dump the previous declaration in the redeclaration chain for a declaration,
49 /// if any.
50 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
51 switch (D->getKind()) {
52 #define DECL(DERIVED, BASE) \
53 case Decl::DERIVED: \
54 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
55 #define ABSTRACT_DECL(DECL)
56 #include "clang/AST/DeclNodes.inc"
58 llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
61 TextNodeDumper::TextNodeDumper(raw_ostream &OS, const ASTContext &Context,
62 bool ShowColors)
63 : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors),
64 Context(&Context), SM(&Context.getSourceManager()),
65 PrintPolicy(Context.getPrintingPolicy()),
66 Traits(&Context.getCommentCommandTraits()) {}
68 TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors)
69 : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors) {}
71 void TextNodeDumper::Visit(const comments::Comment *C,
72 const comments::FullComment *FC) {
73 if (!C) {
74 ColorScope Color(OS, ShowColors, NullColor);
75 OS << "<<<NULL>>>";
76 return;
80 ColorScope Color(OS, ShowColors, CommentColor);
81 OS << C->getCommentKindName();
83 dumpPointer(C);
84 dumpSourceRange(C->getSourceRange());
86 ConstCommentVisitor<TextNodeDumper, void,
87 const comments::FullComment *>::visit(C, FC);
90 void TextNodeDumper::Visit(const Attr *A) {
92 ColorScope Color(OS, ShowColors, AttrColor);
94 switch (A->getKind()) {
95 #define ATTR(X) \
96 case attr::X: \
97 OS << #X; \
98 break;
99 #include "clang/Basic/AttrList.inc"
101 OS << "Attr";
103 dumpPointer(A);
104 dumpSourceRange(A->getRange());
105 if (A->isInherited())
106 OS << " Inherited";
107 if (A->isImplicit())
108 OS << " Implicit";
110 ConstAttrVisitor<TextNodeDumper>::Visit(A);
113 void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
114 const Decl *From, StringRef Label) {
115 OS << "TemplateArgument";
116 if (R.isValid())
117 dumpSourceRange(R);
119 if (From)
120 dumpDeclRef(From, Label);
122 ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
125 void TextNodeDumper::Visit(const Stmt *Node) {
126 if (!Node) {
127 ColorScope Color(OS, ShowColors, NullColor);
128 OS << "<<<NULL>>>";
129 return;
132 ColorScope Color(OS, ShowColors, StmtColor);
133 OS << Node->getStmtClassName();
135 dumpPointer(Node);
136 dumpSourceRange(Node->getSourceRange());
138 if (const auto *E = dyn_cast<Expr>(Node)) {
139 dumpType(E->getType());
141 if (E->containsErrors()) {
142 ColorScope Color(OS, ShowColors, ErrorsColor);
143 OS << " contains-errors";
147 ColorScope Color(OS, ShowColors, ValueKindColor);
148 switch (E->getValueKind()) {
149 case VK_PRValue:
150 break;
151 case VK_LValue:
152 OS << " lvalue";
153 break;
154 case VK_XValue:
155 OS << " xvalue";
156 break;
161 ColorScope Color(OS, ShowColors, ObjectKindColor);
162 switch (E->getObjectKind()) {
163 case OK_Ordinary:
164 break;
165 case OK_BitField:
166 OS << " bitfield";
167 break;
168 case OK_ObjCProperty:
169 OS << " objcproperty";
170 break;
171 case OK_ObjCSubscript:
172 OS << " objcsubscript";
173 break;
174 case OK_VectorComponent:
175 OS << " vectorcomponent";
176 break;
177 case OK_MatrixComponent:
178 OS << " matrixcomponent";
179 break;
184 ConstStmtVisitor<TextNodeDumper>::Visit(Node);
187 void TextNodeDumper::Visit(const Type *T) {
188 if (!T) {
189 ColorScope Color(OS, ShowColors, NullColor);
190 OS << "<<<NULL>>>";
191 return;
193 if (isa<LocInfoType>(T)) {
195 ColorScope Color(OS, ShowColors, TypeColor);
196 OS << "LocInfo Type";
198 dumpPointer(T);
199 return;
203 ColorScope Color(OS, ShowColors, TypeColor);
204 OS << T->getTypeClassName() << "Type";
206 dumpPointer(T);
207 OS << " ";
208 dumpBareType(QualType(T, 0), false);
210 QualType SingleStepDesugar =
211 T->getLocallyUnqualifiedSingleStepDesugaredType();
212 if (SingleStepDesugar != QualType(T, 0))
213 OS << " sugar";
215 if (T->containsErrors()) {
216 ColorScope Color(OS, ShowColors, ErrorsColor);
217 OS << " contains-errors";
220 if (T->isDependentType())
221 OS << " dependent";
222 else if (T->isInstantiationDependentType())
223 OS << " instantiation_dependent";
225 if (T->isVariablyModifiedType())
226 OS << " variably_modified";
227 if (T->containsUnexpandedParameterPack())
228 OS << " contains_unexpanded_pack";
229 if (T->isFromAST())
230 OS << " imported";
232 TypeVisitor<TextNodeDumper>::Visit(T);
235 void TextNodeDumper::Visit(QualType T) {
236 OS << "QualType";
237 dumpPointer(T.getAsOpaquePtr());
238 OS << " ";
239 dumpBareType(T, false);
240 OS << " " << T.split().Quals.getAsString();
243 void TextNodeDumper::Visit(const Decl *D) {
244 if (!D) {
245 ColorScope Color(OS, ShowColors, NullColor);
246 OS << "<<<NULL>>>";
247 return;
251 ColorScope Color(OS, ShowColors, DeclKindNameColor);
252 OS << D->getDeclKindName() << "Decl";
254 dumpPointer(D);
255 if (D->getLexicalDeclContext() != D->getDeclContext())
256 OS << " parent " << cast<Decl>(D->getDeclContext());
257 dumpPreviousDecl(OS, D);
258 dumpSourceRange(D->getSourceRange());
259 OS << ' ';
260 dumpLocation(D->getLocation());
261 if (D->isFromASTFile())
262 OS << " imported";
263 if (Module *M = D->getOwningModule())
264 OS << " in " << M->getFullModuleName();
265 if (auto *ND = dyn_cast<NamedDecl>(D))
266 for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
267 const_cast<NamedDecl *>(ND)))
268 AddChild([=] { OS << "also in " << M->getFullModuleName(); });
269 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
270 if (!ND->isUnconditionallyVisible())
271 OS << " hidden";
272 if (D->isImplicit())
273 OS << " implicit";
275 if (D->isUsed())
276 OS << " used";
277 else if (D->isThisDeclarationReferenced())
278 OS << " referenced";
280 if (D->isInvalidDecl())
281 OS << " invalid";
282 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
283 if (FD->isConstexprSpecified())
284 OS << " constexpr";
285 if (FD->isConsteval())
286 OS << " consteval";
287 else if (FD->isImmediateFunction())
288 OS << " immediate";
289 if (FD->isMultiVersion())
290 OS << " multiversion";
293 if (!isa<FunctionDecl>(*D)) {
294 const auto *MD = dyn_cast<ObjCMethodDecl>(D);
295 if (!MD || !MD->isThisDeclarationADefinition()) {
296 const auto *DC = dyn_cast<DeclContext>(D);
297 if (DC && DC->hasExternalLexicalStorage()) {
298 ColorScope Color(OS, ShowColors, UndeserializedColor);
299 OS << " <undeserialized declarations>";
304 switch (D->getFriendObjectKind()) {
305 case Decl::FOK_None:
306 break;
307 case Decl::FOK_Declared:
308 OS << " friend";
309 break;
310 case Decl::FOK_Undeclared:
311 OS << " friend_undeclared";
312 break;
315 ConstDeclVisitor<TextNodeDumper>::Visit(D);
318 void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
319 OS << "CXXCtorInitializer";
320 if (Init->isAnyMemberInitializer()) {
321 OS << ' ';
322 dumpBareDeclRef(Init->getAnyMember());
323 } else if (Init->isBaseInitializer()) {
324 dumpType(QualType(Init->getBaseClass(), 0));
325 } else if (Init->isDelegatingInitializer()) {
326 dumpType(Init->getTypeSourceInfo()->getType());
327 } else {
328 llvm_unreachable("Unknown initializer type");
332 void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
333 OS << "capture";
334 if (C.isByRef())
335 OS << " byref";
336 if (C.isNested())
337 OS << " nested";
338 if (C.getVariable()) {
339 OS << ' ';
340 dumpBareDeclRef(C.getVariable());
344 void TextNodeDumper::Visit(const OMPClause *C) {
345 if (!C) {
346 ColorScope Color(OS, ShowColors, NullColor);
347 OS << "<<<NULL>>> OMPClause";
348 return;
351 ColorScope Color(OS, ShowColors, AttrColor);
352 StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind()));
353 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
354 << ClauseName.drop_front() << "Clause";
356 dumpPointer(C);
357 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
358 if (C->isImplicit())
359 OS << " <implicit>";
362 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
363 const TypeSourceInfo *TSI = A.getTypeSourceInfo();
364 if (TSI) {
365 OS << "case ";
366 dumpType(TSI->getType());
367 } else {
368 OS << "default";
371 if (A.isSelected())
372 OS << " selected";
375 void TextNodeDumper::Visit(const ConceptReference *R) {
376 if (!R) {
377 ColorScope Color(OS, ShowColors, NullColor);
378 OS << "<<<NULL>>> ConceptReference";
379 return;
382 OS << "ConceptReference";
383 dumpPointer(R);
384 dumpSourceRange(R->getSourceRange());
385 OS << ' ';
386 dumpBareDeclRef(R->getNamedConcept());
389 void TextNodeDumper::Visit(const concepts::Requirement *R) {
390 if (!R) {
391 ColorScope Color(OS, ShowColors, NullColor);
392 OS << "<<<NULL>>> Requirement";
393 return;
397 ColorScope Color(OS, ShowColors, StmtColor);
398 switch (R->getKind()) {
399 case concepts::Requirement::RK_Type:
400 OS << "TypeRequirement";
401 break;
402 case concepts::Requirement::RK_Simple:
403 OS << "SimpleRequirement";
404 break;
405 case concepts::Requirement::RK_Compound:
406 OS << "CompoundRequirement";
407 break;
408 case concepts::Requirement::RK_Nested:
409 OS << "NestedRequirement";
410 break;
414 dumpPointer(R);
416 if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) {
417 if (ER->hasNoexceptRequirement())
418 OS << " noexcept";
421 if (R->isDependent())
422 OS << " dependent";
423 else
424 OS << (R->isSatisfied() ? " satisfied" : " unsatisfied");
425 if (R->containsUnexpandedParameterPack())
426 OS << " contains_unexpanded_pack";
429 static double GetApproxValue(const llvm::APFloat &F) {
430 llvm::APFloat V = F;
431 bool ignored;
432 V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
433 &ignored);
434 return V.convertToDouble();
437 /// True if the \p APValue \p Value can be folded onto the current line.
438 static bool isSimpleAPValue(const APValue &Value) {
439 switch (Value.getKind()) {
440 case APValue::None:
441 case APValue::Indeterminate:
442 case APValue::Int:
443 case APValue::Float:
444 case APValue::FixedPoint:
445 case APValue::ComplexInt:
446 case APValue::ComplexFloat:
447 case APValue::LValue:
448 case APValue::MemberPointer:
449 case APValue::AddrLabelDiff:
450 return true;
451 case APValue::Vector:
452 case APValue::Array:
453 case APValue::Struct:
454 return false;
455 case APValue::Union:
456 return isSimpleAPValue(Value.getUnionValue());
458 llvm_unreachable("unexpected APValue kind!");
461 /// Dump the children of the \p APValue \p Value.
463 /// \param[in] Value The \p APValue to visit
464 /// \param[in] Ty The \p QualType passed to \p Visit
466 /// \param[in] IdxToChildFun A function mapping an \p APValue and an index
467 /// to one of the child of the \p APValue
469 /// \param[in] NumChildren \p IdxToChildFun will be called on \p Value with
470 /// the indices in the range \p [0,NumChildren(
472 /// \param[in] LabelSingular The label to use on a line with a single child
473 /// \param[in] LabelPlurial The label to use on a line with multiple children
474 void TextNodeDumper::dumpAPValueChildren(
475 const APValue &Value, QualType Ty,
476 const APValue &(*IdxToChildFun)(const APValue &, unsigned),
477 unsigned NumChildren, StringRef LabelSingular, StringRef LabelPlurial) {
478 // To save some vertical space we print up to MaxChildrenPerLine APValues
479 // considered to be simple (by isSimpleAPValue) on a single line.
480 constexpr unsigned MaxChildrenPerLine = 4;
481 unsigned I = 0;
482 while (I < NumChildren) {
483 unsigned J = I;
484 while (J < NumChildren) {
485 if (isSimpleAPValue(IdxToChildFun(Value, J)) &&
486 (J - I < MaxChildrenPerLine)) {
487 ++J;
488 continue;
490 break;
493 J = std::max(I + 1, J);
495 // Print [I,J) on a single line.
496 AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() {
497 for (unsigned X = I; X < J; ++X) {
498 Visit(IdxToChildFun(Value, X), Ty);
499 if (X + 1 != J)
500 OS << ", ";
503 I = J;
507 void TextNodeDumper::Visit(const APValue &Value, QualType Ty) {
508 ColorScope Color(OS, ShowColors, ValueKindColor);
509 switch (Value.getKind()) {
510 case APValue::None:
511 OS << "None";
512 return;
513 case APValue::Indeterminate:
514 OS << "Indeterminate";
515 return;
516 case APValue::Int:
517 OS << "Int ";
519 ColorScope Color(OS, ShowColors, ValueColor);
520 OS << Value.getInt();
522 return;
523 case APValue::Float:
524 OS << "Float ";
526 ColorScope Color(OS, ShowColors, ValueColor);
527 OS << GetApproxValue(Value.getFloat());
529 return;
530 case APValue::FixedPoint:
531 OS << "FixedPoint ";
533 ColorScope Color(OS, ShowColors, ValueColor);
534 OS << Value.getFixedPoint();
536 return;
537 case APValue::Vector: {
538 unsigned VectorLength = Value.getVectorLength();
539 OS << "Vector length=" << VectorLength;
541 dumpAPValueChildren(
542 Value, Ty,
543 [](const APValue &Value, unsigned Index) -> const APValue & {
544 return Value.getVectorElt(Index);
546 VectorLength, "element", "elements");
547 return;
549 case APValue::ComplexInt:
550 OS << "ComplexInt ";
552 ColorScope Color(OS, ShowColors, ValueColor);
553 OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag()
554 << 'i';
556 return;
557 case APValue::ComplexFloat:
558 OS << "ComplexFloat ";
560 ColorScope Color(OS, ShowColors, ValueColor);
561 OS << GetApproxValue(Value.getComplexFloatReal()) << " + "
562 << GetApproxValue(Value.getComplexFloatImag()) << 'i';
564 return;
565 case APValue::LValue:
566 (void)Context;
567 OS << "LValue <todo>";
568 return;
569 case APValue::Array: {
570 unsigned ArraySize = Value.getArraySize();
571 unsigned NumInitializedElements = Value.getArrayInitializedElts();
572 OS << "Array size=" << ArraySize;
574 dumpAPValueChildren(
575 Value, Ty,
576 [](const APValue &Value, unsigned Index) -> const APValue & {
577 return Value.getArrayInitializedElt(Index);
579 NumInitializedElements, "element", "elements");
581 if (Value.hasArrayFiller()) {
582 AddChild("filler", [=] {
584 ColorScope Color(OS, ShowColors, ValueColor);
585 OS << ArraySize - NumInitializedElements << " x ";
587 Visit(Value.getArrayFiller(), Ty);
591 return;
593 case APValue::Struct: {
594 OS << "Struct";
596 dumpAPValueChildren(
597 Value, Ty,
598 [](const APValue &Value, unsigned Index) -> const APValue & {
599 return Value.getStructBase(Index);
601 Value.getStructNumBases(), "base", "bases");
603 dumpAPValueChildren(
604 Value, Ty,
605 [](const APValue &Value, unsigned Index) -> const APValue & {
606 return Value.getStructField(Index);
608 Value.getStructNumFields(), "field", "fields");
610 return;
612 case APValue::Union: {
613 OS << "Union";
615 ColorScope Color(OS, ShowColors, ValueColor);
616 if (const FieldDecl *FD = Value.getUnionField())
617 OS << " ." << *cast<NamedDecl>(FD);
619 // If the union value is considered to be simple, fold it into the
620 // current line to save some vertical space.
621 const APValue &UnionValue = Value.getUnionValue();
622 if (isSimpleAPValue(UnionValue)) {
623 OS << ' ';
624 Visit(UnionValue, Ty);
625 } else {
626 AddChild([=] { Visit(UnionValue, Ty); });
629 return;
631 case APValue::MemberPointer:
632 OS << "MemberPointer <todo>";
633 return;
634 case APValue::AddrLabelDiff:
635 OS << "AddrLabelDiff <todo>";
636 return;
638 llvm_unreachable("Unknown APValue kind!");
641 void TextNodeDumper::dumpPointer(const void *Ptr) {
642 ColorScope Color(OS, ShowColors, AddressColor);
643 OS << ' ' << Ptr;
646 void TextNodeDumper::dumpLocation(SourceLocation Loc) {
647 if (!SM)
648 return;
650 ColorScope Color(OS, ShowColors, LocationColor);
651 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
653 // The general format we print out is filename:line:col, but we drop pieces
654 // that haven't changed since the last loc printed.
655 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
657 if (PLoc.isInvalid()) {
658 OS << "<invalid sloc>";
659 return;
662 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
663 OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
664 << PLoc.getColumn();
665 LastLocFilename = PLoc.getFilename();
666 LastLocLine = PLoc.getLine();
667 } else if (PLoc.getLine() != LastLocLine) {
668 OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
669 LastLocLine = PLoc.getLine();
670 } else {
671 OS << "col" << ':' << PLoc.getColumn();
675 void TextNodeDumper::dumpSourceRange(SourceRange R) {
676 // Can't translate locations if a SourceManager isn't available.
677 if (!SM)
678 return;
680 OS << " <";
681 dumpLocation(R.getBegin());
682 if (R.getBegin() != R.getEnd()) {
683 OS << ", ";
684 dumpLocation(R.getEnd());
686 OS << ">";
688 // <t2.c:123:421[blah], t2.c:412:321>
691 void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
692 ColorScope Color(OS, ShowColors, TypeColor);
694 SplitQualType T_split = T.split();
695 std::string T_str = QualType::getAsString(T_split, PrintPolicy);
696 OS << "'" << T_str << "'";
698 if (Desugar && !T.isNull()) {
699 // If the type is sugared, also dump a (shallow) desugared type when
700 // it is visibly different.
701 SplitQualType D_split = T.getSplitDesugaredType();
702 if (T_split != D_split) {
703 std::string D_str = QualType::getAsString(D_split, PrintPolicy);
704 if (T_str != D_str)
705 OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
710 void TextNodeDumper::dumpType(QualType T) {
711 OS << ' ';
712 dumpBareType(T);
715 void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
716 if (!D) {
717 ColorScope Color(OS, ShowColors, NullColor);
718 OS << "<<<NULL>>>";
719 return;
723 ColorScope Color(OS, ShowColors, DeclKindNameColor);
724 OS << D->getDeclKindName();
726 dumpPointer(D);
728 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
729 ColorScope Color(OS, ShowColors, DeclNameColor);
730 OS << " '" << ND->getDeclName() << '\'';
733 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
734 dumpType(VD->getType());
737 void TextNodeDumper::dumpName(const NamedDecl *ND) {
738 if (ND->getDeclName()) {
739 ColorScope Color(OS, ShowColors, DeclNameColor);
740 OS << ' ' << ND->getDeclName();
744 void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
745 const auto AccessSpelling = getAccessSpelling(AS);
746 if (AccessSpelling.empty())
747 return;
748 OS << AccessSpelling;
751 void TextNodeDumper::dumpCleanupObject(
752 const ExprWithCleanups::CleanupObject &C) {
753 if (auto *BD = C.dyn_cast<BlockDecl *>())
754 dumpDeclRef(BD, "cleanup");
755 else if (auto *CLE = C.dyn_cast<CompoundLiteralExpr *>())
756 AddChild([=] {
757 OS << "cleanup ";
759 ColorScope Color(OS, ShowColors, StmtColor);
760 OS << CLE->getStmtClassName();
762 dumpPointer(CLE);
764 else
765 llvm_unreachable("unexpected cleanup type");
768 void clang::TextNodeDumper::dumpTemplateSpecializationKind(
769 TemplateSpecializationKind TSK) {
770 switch (TSK) {
771 case TSK_Undeclared:
772 break;
773 case TSK_ImplicitInstantiation:
774 OS << " implicit_instantiation";
775 break;
776 case TSK_ExplicitSpecialization:
777 OS << " explicit_specialization";
778 break;
779 case TSK_ExplicitInstantiationDeclaration:
780 OS << " explicit_instantiation_declaration";
781 break;
782 case TSK_ExplicitInstantiationDefinition:
783 OS << " explicit_instantiation_definition";
784 break;
788 void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier *NNS) {
789 if (!NNS)
790 return;
792 AddChild([=] {
793 OS << "NestedNameSpecifier";
795 switch (NNS->getKind()) {
796 case NestedNameSpecifier::Identifier:
797 OS << " Identifier";
798 OS << " '" << NNS->getAsIdentifier()->getName() << "'";
799 break;
800 case NestedNameSpecifier::Namespace:
801 OS << " "; // "Namespace" is printed as the decl kind.
802 dumpBareDeclRef(NNS->getAsNamespace());
803 break;
804 case NestedNameSpecifier::NamespaceAlias:
805 OS << " "; // "NamespaceAlias" is printed as the decl kind.
806 dumpBareDeclRef(NNS->getAsNamespaceAlias());
807 break;
808 case NestedNameSpecifier::TypeSpec:
809 OS << " TypeSpec";
810 dumpType(QualType(NNS->getAsType(), 0));
811 break;
812 case NestedNameSpecifier::TypeSpecWithTemplate:
813 OS << " TypeSpecWithTemplate";
814 dumpType(QualType(NNS->getAsType(), 0));
815 break;
816 case NestedNameSpecifier::Global:
817 OS << " Global";
818 break;
819 case NestedNameSpecifier::Super:
820 OS << " Super";
821 break;
824 dumpNestedNameSpecifier(NNS->getPrefix());
828 void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
829 if (!D)
830 return;
832 AddChild([=] {
833 if (!Label.empty())
834 OS << Label << ' ';
835 dumpBareDeclRef(D);
839 const char *TextNodeDumper::getCommandName(unsigned CommandID) {
840 if (Traits)
841 return Traits->getCommandInfo(CommandID)->Name;
842 const comments::CommandInfo *Info =
843 comments::CommandTraits::getBuiltinCommandInfo(CommandID);
844 if (Info)
845 return Info->Name;
846 return "<not a builtin command>";
849 void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) {
850 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
851 if (FPO.has##NAME##Override()) \
852 OS << " " #NAME "=" << FPO.get##NAME##Override();
853 #include "clang/Basic/FPOptions.def"
856 void TextNodeDumper::visitTextComment(const comments::TextComment *C,
857 const comments::FullComment *) {
858 OS << " Text=\"" << C->getText() << "\"";
861 void TextNodeDumper::visitInlineCommandComment(
862 const comments::InlineCommandComment *C, const comments::FullComment *) {
863 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
864 switch (C->getRenderKind()) {
865 case comments::InlineCommandComment::RenderNormal:
866 OS << " RenderNormal";
867 break;
868 case comments::InlineCommandComment::RenderBold:
869 OS << " RenderBold";
870 break;
871 case comments::InlineCommandComment::RenderMonospaced:
872 OS << " RenderMonospaced";
873 break;
874 case comments::InlineCommandComment::RenderEmphasized:
875 OS << " RenderEmphasized";
876 break;
877 case comments::InlineCommandComment::RenderAnchor:
878 OS << " RenderAnchor";
879 break;
882 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
883 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
886 void TextNodeDumper::visitHTMLStartTagComment(
887 const comments::HTMLStartTagComment *C, const comments::FullComment *) {
888 OS << " Name=\"" << C->getTagName() << "\"";
889 if (C->getNumAttrs() != 0) {
890 OS << " Attrs: ";
891 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
892 const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
893 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
896 if (C->isSelfClosing())
897 OS << " SelfClosing";
900 void TextNodeDumper::visitHTMLEndTagComment(
901 const comments::HTMLEndTagComment *C, const comments::FullComment *) {
902 OS << " Name=\"" << C->getTagName() << "\"";
905 void TextNodeDumper::visitBlockCommandComment(
906 const comments::BlockCommandComment *C, const comments::FullComment *) {
907 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
908 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
909 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
912 void TextNodeDumper::visitParamCommandComment(
913 const comments::ParamCommandComment *C, const comments::FullComment *FC) {
914 OS << " "
915 << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
917 if (C->isDirectionExplicit())
918 OS << " explicitly";
919 else
920 OS << " implicitly";
922 if (C->hasParamName()) {
923 if (C->isParamIndexValid())
924 OS << " Param=\"" << C->getParamName(FC) << "\"";
925 else
926 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
929 if (C->isParamIndexValid() && !C->isVarArgParam())
930 OS << " ParamIndex=" << C->getParamIndex();
933 void TextNodeDumper::visitTParamCommandComment(
934 const comments::TParamCommandComment *C, const comments::FullComment *FC) {
935 if (C->hasParamName()) {
936 if (C->isPositionValid())
937 OS << " Param=\"" << C->getParamName(FC) << "\"";
938 else
939 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
942 if (C->isPositionValid()) {
943 OS << " Position=<";
944 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
945 OS << C->getIndex(i);
946 if (i != e - 1)
947 OS << ", ";
949 OS << ">";
953 void TextNodeDumper::visitVerbatimBlockComment(
954 const comments::VerbatimBlockComment *C, const comments::FullComment *) {
955 OS << " Name=\"" << getCommandName(C->getCommandID())
956 << "\""
957 " CloseName=\""
958 << C->getCloseName() << "\"";
961 void TextNodeDumper::visitVerbatimBlockLineComment(
962 const comments::VerbatimBlockLineComment *C,
963 const comments::FullComment *) {
964 OS << " Text=\"" << C->getText() << "\"";
967 void TextNodeDumper::visitVerbatimLineComment(
968 const comments::VerbatimLineComment *C, const comments::FullComment *) {
969 OS << " Text=\"" << C->getText() << "\"";
972 void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
973 OS << " null";
976 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
977 OS << " type";
978 dumpType(TA.getAsType());
981 void TextNodeDumper::VisitDeclarationTemplateArgument(
982 const TemplateArgument &TA) {
983 OS << " decl";
984 dumpDeclRef(TA.getAsDecl());
987 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
988 OS << " nullptr";
991 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
992 OS << " integral " << TA.getAsIntegral();
995 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
996 if (TA.getAsTemplate().getKind() == TemplateName::UsingTemplate)
997 OS << " using";
998 OS << " template ";
999 TA.getAsTemplate().dump(OS);
1002 void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
1003 const TemplateArgument &TA) {
1004 if (TA.getAsTemplateOrTemplatePattern().getKind() ==
1005 TemplateName::UsingTemplate)
1006 OS << " using";
1007 OS << " template expansion ";
1008 TA.getAsTemplateOrTemplatePattern().dump(OS);
1011 void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
1012 OS << " expr";
1015 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
1016 OS << " pack";
1019 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
1020 if (Node->path_empty())
1021 return;
1023 OS << " (";
1024 bool First = true;
1025 for (CastExpr::path_const_iterator I = Node->path_begin(),
1026 E = Node->path_end();
1027 I != E; ++I) {
1028 const CXXBaseSpecifier *Base = *I;
1029 if (!First)
1030 OS << " -> ";
1032 const auto *RD =
1033 cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
1035 if (Base->isVirtual())
1036 OS << "virtual ";
1037 OS << RD->getName();
1038 First = false;
1041 OS << ')';
1044 void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
1045 if (Node->hasInitStorage())
1046 OS << " has_init";
1047 if (Node->hasVarStorage())
1048 OS << " has_var";
1049 if (Node->hasElseStorage())
1050 OS << " has_else";
1051 if (Node->isConstexpr())
1052 OS << " constexpr";
1053 if (Node->isConsteval()) {
1054 OS << " ";
1055 if (Node->isNegatedConsteval())
1056 OS << "!";
1057 OS << "consteval";
1061 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
1062 if (Node->hasInitStorage())
1063 OS << " has_init";
1064 if (Node->hasVarStorage())
1065 OS << " has_var";
1068 void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
1069 if (Node->hasVarStorage())
1070 OS << " has_var";
1073 void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
1074 OS << " '" << Node->getName() << "'";
1075 if (Node->isSideEntry())
1076 OS << " side_entry";
1079 void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
1080 OS << " '" << Node->getLabel()->getName() << "'";
1081 dumpPointer(Node->getLabel());
1084 void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
1085 if (Node->caseStmtIsGNURange())
1086 OS << " gnu_range";
1089 void clang::TextNodeDumper::VisitReturnStmt(const ReturnStmt *Node) {
1090 if (const VarDecl *Cand = Node->getNRVOCandidate()) {
1091 OS << " nrvo_candidate(";
1092 dumpBareDeclRef(Cand);
1093 OS << ")";
1097 void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
1098 if (Node->hasAPValueResult())
1099 AddChild("value",
1100 [=] { Visit(Node->getAPValueResult(), Node->getType()); });
1103 void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
1104 if (Node->usesADL())
1105 OS << " adl";
1106 if (Node->hasStoredFPFeatures())
1107 printFPOptions(Node->getFPFeatures());
1110 void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) {
1111 const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator());
1112 if (OperatorSpelling)
1113 OS << " '" << OperatorSpelling << "'";
1115 VisitCallExpr(Node);
1118 void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
1119 OS << " <";
1121 ColorScope Color(OS, ShowColors, CastColor);
1122 OS << Node->getCastKindName();
1124 dumpBasePath(OS, Node);
1125 OS << ">";
1126 if (Node->hasStoredFPFeatures())
1127 printFPOptions(Node->getFPFeatures());
1130 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
1131 VisitCastExpr(Node);
1132 if (Node->isPartOfExplicitCast())
1133 OS << " part_of_explicit_cast";
1136 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1137 OS << " ";
1138 dumpBareDeclRef(Node->getDecl());
1139 dumpNestedNameSpecifier(Node->getQualifier());
1140 if (Node->getDecl() != Node->getFoundDecl()) {
1141 OS << " (";
1142 dumpBareDeclRef(Node->getFoundDecl());
1143 OS << ")";
1145 switch (Node->isNonOdrUse()) {
1146 case NOUR_None: break;
1147 case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1148 case NOUR_Constant: OS << " non_odr_use_constant"; break;
1149 case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1151 if (Node->refersToEnclosingVariableOrCapture())
1152 OS << " refers_to_enclosing_variable_or_capture";
1153 if (Node->isImmediateEscalating())
1154 OS << " immediate-escalating";
1157 void clang::TextNodeDumper::VisitDependentScopeDeclRefExpr(
1158 const DependentScopeDeclRefExpr *Node) {
1160 dumpNestedNameSpecifier(Node->getQualifier());
1163 void TextNodeDumper::VisitUnresolvedLookupExpr(
1164 const UnresolvedLookupExpr *Node) {
1165 OS << " (";
1166 if (!Node->requiresADL())
1167 OS << "no ";
1168 OS << "ADL) = '" << Node->getName() << '\'';
1170 UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
1171 E = Node->decls_end();
1172 if (I == E)
1173 OS << " empty";
1174 for (; I != E; ++I)
1175 dumpPointer(*I);
1178 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
1180 ColorScope Color(OS, ShowColors, DeclKindNameColor);
1181 OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
1183 OS << "='" << *Node->getDecl() << "'";
1184 dumpPointer(Node->getDecl());
1185 if (Node->isFreeIvar())
1186 OS << " isFreeIvar";
1189 void TextNodeDumper::VisitSYCLUniqueStableNameExpr(
1190 const SYCLUniqueStableNameExpr *Node) {
1191 dumpType(Node->getTypeSourceInfo()->getType());
1194 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
1195 OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1198 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1199 ColorScope Color(OS, ShowColors, ValueColor);
1200 OS << " " << Node->getValue();
1203 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1204 bool isSigned = Node->getType()->isSignedIntegerType();
1205 ColorScope Color(OS, ShowColors, ValueColor);
1206 OS << " " << toString(Node->getValue(), 10, isSigned);
1209 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
1210 ColorScope Color(OS, ShowColors, ValueColor);
1211 OS << " " << Node->getValueAsString(/*Radix=*/10);
1214 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1215 ColorScope Color(OS, ShowColors, ValueColor);
1216 OS << " " << Node->getValueAsApproximateDouble();
1219 void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
1220 ColorScope Color(OS, ShowColors, ValueColor);
1221 OS << " ";
1222 Str->outputString(OS);
1225 void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
1226 if (auto *Field = ILE->getInitializedFieldInUnion()) {
1227 OS << " field ";
1228 dumpBareDeclRef(Field);
1232 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
1233 if (E->isResultDependent())
1234 OS << " result_dependent";
1237 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1238 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
1239 << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1240 if (!Node->canOverflow())
1241 OS << " cannot overflow";
1242 if (Node->hasStoredFPFeatures())
1243 printFPOptions(Node->getStoredFPFeatures());
1246 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1247 const UnaryExprOrTypeTraitExpr *Node) {
1248 OS << " " << getTraitSpelling(Node->getKind());
1250 if (Node->isArgumentType())
1251 dumpType(Node->getArgumentType());
1254 void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
1255 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
1256 dumpPointer(Node->getMemberDecl());
1257 dumpNestedNameSpecifier(Node->getQualifier());
1258 switch (Node->isNonOdrUse()) {
1259 case NOUR_None: break;
1260 case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1261 case NOUR_Constant: OS << " non_odr_use_constant"; break;
1262 case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1266 void TextNodeDumper::VisitExtVectorElementExpr(
1267 const ExtVectorElementExpr *Node) {
1268 OS << " " << Node->getAccessor().getNameStart();
1271 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1272 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1273 if (Node->hasStoredFPFeatures())
1274 printFPOptions(Node->getStoredFPFeatures());
1277 void TextNodeDumper::VisitCompoundAssignOperator(
1278 const CompoundAssignOperator *Node) {
1279 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1280 << "' ComputeLHSTy=";
1281 dumpBareType(Node->getComputationLHSType());
1282 OS << " ComputeResultTy=";
1283 dumpBareType(Node->getComputationResultType());
1284 if (Node->hasStoredFPFeatures())
1285 printFPOptions(Node->getStoredFPFeatures());
1288 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
1289 OS << " " << Node->getLabel()->getName();
1290 dumpPointer(Node->getLabel());
1293 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
1294 OS << " " << Node->getCastName() << "<"
1295 << Node->getTypeAsWritten().getAsString() << ">"
1296 << " <" << Node->getCastKindName();
1297 dumpBasePath(OS, Node);
1298 OS << ">";
1301 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1302 OS << " " << (Node->getValue() ? "true" : "false");
1305 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1306 if (Node->isImplicit())
1307 OS << " implicit";
1308 OS << " this";
1311 void TextNodeDumper::VisitCXXFunctionalCastExpr(
1312 const CXXFunctionalCastExpr *Node) {
1313 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
1314 << Node->getCastKindName() << ">";
1315 if (Node->hasStoredFPFeatures())
1316 printFPOptions(Node->getFPFeatures());
1319 void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) {
1320 VisitCXXNamedCastExpr(Node);
1321 if (Node->hasStoredFPFeatures())
1322 printFPOptions(Node->getFPFeatures());
1325 void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
1326 const CXXUnresolvedConstructExpr *Node) {
1327 dumpType(Node->getTypeAsWritten());
1328 if (Node->isListInitialization())
1329 OS << " list";
1332 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1333 CXXConstructorDecl *Ctor = Node->getConstructor();
1334 dumpType(Ctor->getType());
1335 if (Node->isElidable())
1336 OS << " elidable";
1337 if (Node->isListInitialization())
1338 OS << " list";
1339 if (Node->isStdInitListInitialization())
1340 OS << " std::initializer_list";
1341 if (Node->requiresZeroInitialization())
1342 OS << " zeroing";
1343 if (Node->isImmediateEscalating())
1344 OS << " immediate-escalating";
1347 void TextNodeDumper::VisitCXXBindTemporaryExpr(
1348 const CXXBindTemporaryExpr *Node) {
1349 OS << " (CXXTemporary";
1350 dumpPointer(Node);
1351 OS << ")";
1354 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
1355 if (Node->isGlobalNew())
1356 OS << " global";
1357 if (Node->isArray())
1358 OS << " array";
1359 if (Node->getOperatorNew()) {
1360 OS << ' ';
1361 dumpBareDeclRef(Node->getOperatorNew());
1363 // We could dump the deallocation function used in case of error, but it's
1364 // usually not that interesting.
1367 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
1368 if (Node->isGlobalDelete())
1369 OS << " global";
1370 if (Node->isArrayForm())
1371 OS << " array";
1372 if (Node->getOperatorDelete()) {
1373 OS << ' ';
1374 dumpBareDeclRef(Node->getOperatorDelete());
1378 void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) {
1379 OS << " " << getTraitSpelling(Node->getTrait());
1382 void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) {
1383 OS << " " << getTraitSpelling(Node->getTrait());
1386 void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) {
1387 OS << " " << getTraitSpelling(Node->getTrait());
1390 void TextNodeDumper::VisitMaterializeTemporaryExpr(
1391 const MaterializeTemporaryExpr *Node) {
1392 if (const ValueDecl *VD = Node->getExtendingDecl()) {
1393 OS << " extended by ";
1394 dumpBareDeclRef(VD);
1398 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
1399 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
1400 dumpCleanupObject(Node->getObject(i));
1403 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
1404 dumpPointer(Node->getPack());
1405 dumpName(Node->getPack());
1408 void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
1409 const CXXDependentScopeMemberExpr *Node) {
1410 OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
1413 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
1414 OS << " selector=";
1415 Node->getSelector().print(OS);
1416 switch (Node->getReceiverKind()) {
1417 case ObjCMessageExpr::Instance:
1418 break;
1420 case ObjCMessageExpr::Class:
1421 OS << " class=";
1422 dumpBareType(Node->getClassReceiver());
1423 break;
1425 case ObjCMessageExpr::SuperInstance:
1426 OS << " super (instance)";
1427 break;
1429 case ObjCMessageExpr::SuperClass:
1430 OS << " super (class)";
1431 break;
1435 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
1436 if (auto *BoxingMethod = Node->getBoxingMethod()) {
1437 OS << " selector=";
1438 BoxingMethod->getSelector().print(OS);
1442 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
1443 if (!Node->getCatchParamDecl())
1444 OS << " catch all";
1447 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
1448 dumpType(Node->getEncodedType());
1451 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1452 OS << " ";
1453 Node->getSelector().print(OS);
1456 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
1457 OS << ' ' << *Node->getProtocol();
1460 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
1461 if (Node->isImplicitProperty()) {
1462 OS << " Kind=MethodRef Getter=\"";
1463 if (Node->getImplicitPropertyGetter())
1464 Node->getImplicitPropertyGetter()->getSelector().print(OS);
1465 else
1466 OS << "(null)";
1468 OS << "\" Setter=\"";
1469 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
1470 Setter->getSelector().print(OS);
1471 else
1472 OS << "(null)";
1473 OS << "\"";
1474 } else {
1475 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
1476 << '"';
1479 if (Node->isSuperReceiver())
1480 OS << " super";
1482 OS << " Messaging=";
1483 if (Node->isMessagingGetter() && Node->isMessagingSetter())
1484 OS << "Getter&Setter";
1485 else if (Node->isMessagingGetter())
1486 OS << "Getter";
1487 else if (Node->isMessagingSetter())
1488 OS << "Setter";
1491 void TextNodeDumper::VisitObjCSubscriptRefExpr(
1492 const ObjCSubscriptRefExpr *Node) {
1493 if (Node->isArraySubscriptRefExpr())
1494 OS << " Kind=ArraySubscript GetterForArray=\"";
1495 else
1496 OS << " Kind=DictionarySubscript GetterForDictionary=\"";
1497 if (Node->getAtIndexMethodDecl())
1498 Node->getAtIndexMethodDecl()->getSelector().print(OS);
1499 else
1500 OS << "(null)";
1502 if (Node->isArraySubscriptRefExpr())
1503 OS << "\" SetterForArray=\"";
1504 else
1505 OS << "\" SetterForDictionary=\"";
1506 if (Node->setAtIndexMethodDecl())
1507 Node->setAtIndexMethodDecl()->getSelector().print(OS);
1508 else
1509 OS << "(null)";
1512 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
1513 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
1516 void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) {
1517 OS << " ";
1518 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1519 Visit(Node->getIteratorDecl(I));
1520 OS << " = ";
1521 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1522 OS << " begin ";
1523 Visit(Range.Begin);
1524 OS << " end ";
1525 Visit(Range.End);
1526 if (Range.Step) {
1527 OS << " step ";
1528 Visit(Range.Step);
1533 void TextNodeDumper::VisitConceptSpecializationExpr(
1534 const ConceptSpecializationExpr *Node) {
1535 OS << " ";
1536 dumpBareDeclRef(Node->getFoundDecl());
1539 void TextNodeDumper::VisitRequiresExpr(
1540 const RequiresExpr *Node) {
1541 if (!Node->isValueDependent())
1542 OS << (Node->isSatisfied() ? " satisfied" : " unsatisfied");
1545 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
1546 if (T->isSpelledAsLValue())
1547 OS << " written as lvalue reference";
1550 void TextNodeDumper::VisitArrayType(const ArrayType *T) {
1551 switch (T->getSizeModifier()) {
1552 case ArraySizeModifier::Normal:
1553 break;
1554 case ArraySizeModifier::Static:
1555 OS << " static";
1556 break;
1557 case ArraySizeModifier::Star:
1558 OS << " *";
1559 break;
1561 OS << " " << T->getIndexTypeQualifiers().getAsString();
1564 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
1565 OS << " " << T->getSize();
1566 VisitArrayType(T);
1569 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
1570 OS << " ";
1571 dumpSourceRange(T->getBracketsRange());
1572 VisitArrayType(T);
1575 void TextNodeDumper::VisitDependentSizedArrayType(
1576 const DependentSizedArrayType *T) {
1577 VisitArrayType(T);
1578 OS << " ";
1579 dumpSourceRange(T->getBracketsRange());
1582 void TextNodeDumper::VisitDependentSizedExtVectorType(
1583 const DependentSizedExtVectorType *T) {
1584 OS << " ";
1585 dumpLocation(T->getAttributeLoc());
1588 void TextNodeDumper::VisitVectorType(const VectorType *T) {
1589 switch (T->getVectorKind()) {
1590 case VectorKind::Generic:
1591 break;
1592 case VectorKind::AltiVecVector:
1593 OS << " altivec";
1594 break;
1595 case VectorKind::AltiVecPixel:
1596 OS << " altivec pixel";
1597 break;
1598 case VectorKind::AltiVecBool:
1599 OS << " altivec bool";
1600 break;
1601 case VectorKind::Neon:
1602 OS << " neon";
1603 break;
1604 case VectorKind::NeonPoly:
1605 OS << " neon poly";
1606 break;
1607 case VectorKind::SveFixedLengthData:
1608 OS << " fixed-length sve data vector";
1609 break;
1610 case VectorKind::SveFixedLengthPredicate:
1611 OS << " fixed-length sve predicate vector";
1612 break;
1613 case VectorKind::RVVFixedLengthData:
1614 OS << " fixed-length rvv data vector";
1615 break;
1617 OS << " " << T->getNumElements();
1620 void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
1621 auto EI = T->getExtInfo();
1622 if (EI.getNoReturn())
1623 OS << " noreturn";
1624 if (EI.getProducesResult())
1625 OS << " produces_result";
1626 if (EI.getHasRegParm())
1627 OS << " regparm " << EI.getRegParm();
1628 OS << " " << FunctionType::getNameForCallConv(EI.getCC());
1631 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
1632 auto EPI = T->getExtProtoInfo();
1633 if (EPI.HasTrailingReturn)
1634 OS << " trailing_return";
1635 if (T->isConst())
1636 OS << " const";
1637 if (T->isVolatile())
1638 OS << " volatile";
1639 if (T->isRestrict())
1640 OS << " restrict";
1641 if (T->getExtProtoInfo().Variadic)
1642 OS << " variadic";
1643 switch (EPI.RefQualifier) {
1644 case RQ_None:
1645 break;
1646 case RQ_LValue:
1647 OS << " &";
1648 break;
1649 case RQ_RValue:
1650 OS << " &&";
1651 break;
1654 switch (EPI.ExceptionSpec.Type) {
1655 case EST_None:
1656 break;
1657 case EST_DynamicNone:
1658 OS << " exceptionspec_dynamic_none";
1659 break;
1660 case EST_Dynamic:
1661 OS << " exceptionspec_dynamic";
1662 break;
1663 case EST_MSAny:
1664 OS << " exceptionspec_ms_any";
1665 break;
1666 case EST_NoThrow:
1667 OS << " exceptionspec_nothrow";
1668 break;
1669 case EST_BasicNoexcept:
1670 OS << " exceptionspec_basic_noexcept";
1671 break;
1672 case EST_DependentNoexcept:
1673 OS << " exceptionspec_dependent_noexcept";
1674 break;
1675 case EST_NoexceptFalse:
1676 OS << " exceptionspec_noexcept_false";
1677 break;
1678 case EST_NoexceptTrue:
1679 OS << " exceptionspec_noexcept_true";
1680 break;
1681 case EST_Unevaluated:
1682 OS << " exceptionspec_unevaluated";
1683 break;
1684 case EST_Uninstantiated:
1685 OS << " exceptionspec_uninstantiated";
1686 break;
1687 case EST_Unparsed:
1688 OS << " exceptionspec_unparsed";
1689 break;
1691 if (!EPI.ExceptionSpec.Exceptions.empty()) {
1692 AddChild([=] {
1693 OS << "Exceptions:";
1694 for (unsigned I = 0, N = EPI.ExceptionSpec.Exceptions.size(); I != N;
1695 ++I) {
1696 if (I)
1697 OS << ",";
1698 dumpType(EPI.ExceptionSpec.Exceptions[I]);
1702 if (EPI.ExceptionSpec.NoexceptExpr) {
1703 AddChild([=] {
1704 OS << "NoexceptExpr: ";
1705 Visit(EPI.ExceptionSpec.NoexceptExpr);
1708 dumpDeclRef(EPI.ExceptionSpec.SourceDecl, "ExceptionSourceDecl");
1709 dumpDeclRef(EPI.ExceptionSpec.SourceTemplate, "ExceptionSourceTemplate");
1711 // FIXME: Consumed parameters.
1712 VisitFunctionType(T);
1715 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1716 dumpDeclRef(T->getDecl());
1719 void TextNodeDumper::VisitUsingType(const UsingType *T) {
1720 dumpDeclRef(T->getFoundDecl());
1721 if (!T->typeMatchesDecl())
1722 OS << " divergent";
1725 void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
1726 dumpDeclRef(T->getDecl());
1727 if (!T->typeMatchesDecl())
1728 OS << " divergent";
1731 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
1732 switch (T->getUTTKind()) {
1733 #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
1734 case UnaryTransformType::Enum: \
1735 OS << " " #Trait; \
1736 break;
1737 #include "clang/Basic/TransformTypeTraits.def"
1741 void TextNodeDumper::VisitTagType(const TagType *T) {
1742 dumpDeclRef(T->getDecl());
1745 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1746 OS << " depth " << T->getDepth() << " index " << T->getIndex();
1747 if (T->isParameterPack())
1748 OS << " pack";
1749 dumpDeclRef(T->getDecl());
1752 void TextNodeDumper::VisitSubstTemplateTypeParmType(
1753 const SubstTemplateTypeParmType *T) {
1754 dumpDeclRef(T->getAssociatedDecl());
1755 VisitTemplateTypeParmDecl(T->getReplacedParameter());
1756 if (auto PackIndex = T->getPackIndex())
1757 OS << " pack_index " << *PackIndex;
1760 void TextNodeDumper::VisitSubstTemplateTypeParmPackType(
1761 const SubstTemplateTypeParmPackType *T) {
1762 dumpDeclRef(T->getAssociatedDecl());
1763 VisitTemplateTypeParmDecl(T->getReplacedParameter());
1766 void TextNodeDumper::VisitAutoType(const AutoType *T) {
1767 if (T->isDecltypeAuto())
1768 OS << " decltype(auto)";
1769 if (!T->isDeduced())
1770 OS << " undeduced";
1771 if (T->isConstrained()) {
1772 dumpDeclRef(T->getTypeConstraintConcept());
1773 for (const auto &Arg : T->getTypeConstraintArguments())
1774 VisitTemplateArgument(Arg);
1778 void TextNodeDumper::VisitDeducedTemplateSpecializationType(
1779 const DeducedTemplateSpecializationType *T) {
1780 if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
1781 OS << " using";
1784 void TextNodeDumper::VisitTemplateSpecializationType(
1785 const TemplateSpecializationType *T) {
1786 if (T->isTypeAlias())
1787 OS << " alias";
1788 if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
1789 OS << " using";
1790 OS << " ";
1791 T->getTemplateName().dump(OS);
1794 void TextNodeDumper::VisitInjectedClassNameType(
1795 const InjectedClassNameType *T) {
1796 dumpDeclRef(T->getDecl());
1799 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1800 dumpDeclRef(T->getDecl());
1803 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
1804 if (auto N = T->getNumExpansions())
1805 OS << " expansions " << *N;
1808 void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
1810 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
1811 dumpName(D);
1812 dumpType(D->getUnderlyingType());
1813 if (D->isModulePrivate())
1814 OS << " __module_private__";
1817 void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
1818 if (D->isScoped()) {
1819 if (D->isScopedUsingClassTag())
1820 OS << " class";
1821 else
1822 OS << " struct";
1824 dumpName(D);
1825 if (D->isModulePrivate())
1826 OS << " __module_private__";
1827 if (D->isFixed())
1828 dumpType(D->getIntegerType());
1831 void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
1832 OS << ' ' << D->getKindName();
1833 dumpName(D);
1834 if (D->isModulePrivate())
1835 OS << " __module_private__";
1836 if (D->isCompleteDefinition())
1837 OS << " definition";
1840 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
1841 dumpName(D);
1842 dumpType(D->getType());
1845 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
1846 dumpName(D);
1847 dumpType(D->getType());
1849 for (const auto *Child : D->chain())
1850 dumpDeclRef(Child);
1853 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
1854 dumpName(D);
1855 dumpType(D->getType());
1856 dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
1858 StorageClass SC = D->getStorageClass();
1859 if (SC != SC_None)
1860 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1861 if (D->isInlineSpecified())
1862 OS << " inline";
1863 if (D->isVirtualAsWritten())
1864 OS << " virtual";
1865 if (D->isModulePrivate())
1866 OS << " __module_private__";
1868 if (D->isPure())
1869 OS << " pure";
1870 if (D->isDefaulted()) {
1871 OS << " default";
1872 if (D->isDeleted())
1873 OS << "_delete";
1875 if (D->isDeletedAsWritten())
1876 OS << " delete";
1877 if (D->isTrivial())
1878 OS << " trivial";
1880 if (D->isIneligibleOrNotSelected())
1881 OS << (isa<CXXDestructorDecl>(D) ? " not_selected" : " ineligible");
1883 if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
1884 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
1885 switch (EPI.ExceptionSpec.Type) {
1886 default:
1887 break;
1888 case EST_Unevaluated:
1889 OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
1890 break;
1891 case EST_Uninstantiated:
1892 OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
1893 break;
1897 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
1898 if (MD->size_overridden_methods() != 0) {
1899 auto dumpOverride = [=](const CXXMethodDecl *D) {
1900 SplitQualType T_split = D->getType().split();
1901 OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName()
1902 << " '" << QualType::getAsString(T_split, PrintPolicy) << "'";
1905 AddChild([=] {
1906 auto Overrides = MD->overridden_methods();
1907 OS << "Overrides: [ ";
1908 dumpOverride(*Overrides.begin());
1909 for (const auto *Override : llvm::drop_begin(Overrides)) {
1910 OS << ", ";
1911 dumpOverride(Override);
1913 OS << " ]";
1918 if (!D->isInlineSpecified() && D->isInlined()) {
1919 OS << " implicit-inline";
1921 // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
1922 // the Params are set later, it is possible for a dump during debugging to
1923 // encounter a FunctionDecl that has been created but hasn't been assigned
1924 // ParmVarDecls yet.
1925 if (!D->param_empty() && !D->param_begin())
1926 OS << " <<<NULL params x " << D->getNumParams() << ">>>";
1928 if (const auto *Instance = D->getInstantiatedFromMemberFunction()) {
1929 OS << " instantiated_from";
1930 dumpPointer(Instance);
1934 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
1935 const LifetimeExtendedTemporaryDecl *D) {
1936 OS << " extended by ";
1937 dumpBareDeclRef(D->getExtendingDecl());
1938 OS << " mangling ";
1940 ColorScope Color(OS, ShowColors, ValueColor);
1941 OS << D->getManglingNumber();
1945 void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
1946 dumpName(D);
1947 dumpType(D->getType());
1948 if (D->isMutable())
1949 OS << " mutable";
1950 if (D->isModulePrivate())
1951 OS << " __module_private__";
1954 void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
1955 dumpNestedNameSpecifier(D->getQualifier());
1956 dumpName(D);
1957 if (const auto *P = dyn_cast<ParmVarDecl>(D);
1958 P && P->isExplicitObjectParameter())
1959 OS << " this";
1961 dumpType(D->getType());
1962 dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
1963 StorageClass SC = D->getStorageClass();
1964 if (SC != SC_None)
1965 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1966 switch (D->getTLSKind()) {
1967 case VarDecl::TLS_None:
1968 break;
1969 case VarDecl::TLS_Static:
1970 OS << " tls";
1971 break;
1972 case VarDecl::TLS_Dynamic:
1973 OS << " tls_dynamic";
1974 break;
1976 if (D->isModulePrivate())
1977 OS << " __module_private__";
1978 if (D->isNRVOVariable())
1979 OS << " nrvo";
1980 if (D->isInline())
1981 OS << " inline";
1982 if (D->isConstexpr())
1983 OS << " constexpr";
1984 if (D->hasInit()) {
1985 switch (D->getInitStyle()) {
1986 case VarDecl::CInit:
1987 OS << " cinit";
1988 break;
1989 case VarDecl::CallInit:
1990 OS << " callinit";
1991 break;
1992 case VarDecl::ListInit:
1993 OS << " listinit";
1994 break;
1995 case VarDecl::ParenListInit:
1996 OS << " parenlistinit";
1999 if (D->needsDestruction(D->getASTContext()))
2000 OS << " destroyed";
2001 if (D->isParameterPack())
2002 OS << " pack";
2004 if (D->hasInit()) {
2005 const Expr *E = D->getInit();
2006 // Only dump the value of constexpr VarDecls for now.
2007 if (E && !E->isValueDependent() && D->isConstexpr() &&
2008 !D->getType()->isDependentType()) {
2009 const APValue *Value = D->evaluateValue();
2010 if (Value)
2011 AddChild("value", [=] { Visit(*Value, E->getType()); });
2016 void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
2017 dumpName(D);
2018 dumpType(D->getType());
2021 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
2022 if (D->isNothrow())
2023 OS << " nothrow";
2026 void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
2027 OS << ' ' << D->getImportedModule()->getFullModuleName();
2029 for (Decl *InitD :
2030 D->getASTContext().getModuleInitializers(D->getImportedModule()))
2031 dumpDeclRef(InitD, "initializer");
2034 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
2035 OS << ' ';
2036 switch (D->getCommentKind()) {
2037 case PCK_Unknown:
2038 llvm_unreachable("unexpected pragma comment kind");
2039 case PCK_Compiler:
2040 OS << "compiler";
2041 break;
2042 case PCK_ExeStr:
2043 OS << "exestr";
2044 break;
2045 case PCK_Lib:
2046 OS << "lib";
2047 break;
2048 case PCK_Linker:
2049 OS << "linker";
2050 break;
2051 case PCK_User:
2052 OS << "user";
2053 break;
2055 StringRef Arg = D->getArg();
2056 if (!Arg.empty())
2057 OS << " \"" << Arg << "\"";
2060 void TextNodeDumper::VisitPragmaDetectMismatchDecl(
2061 const PragmaDetectMismatchDecl *D) {
2062 OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
2065 void TextNodeDumper::VisitOMPExecutableDirective(
2066 const OMPExecutableDirective *D) {
2067 if (D->isStandaloneDirective())
2068 OS << " openmp_standalone_directive";
2071 void TextNodeDumper::VisitOMPDeclareReductionDecl(
2072 const OMPDeclareReductionDecl *D) {
2073 dumpName(D);
2074 dumpType(D->getType());
2075 OS << " combiner";
2076 dumpPointer(D->getCombiner());
2077 if (const auto *Initializer = D->getInitializer()) {
2078 OS << " initializer";
2079 dumpPointer(Initializer);
2080 switch (D->getInitializerKind()) {
2081 case OMPDeclareReductionInitKind::Direct:
2082 OS << " omp_priv = ";
2083 break;
2084 case OMPDeclareReductionInitKind::Copy:
2085 OS << " omp_priv ()";
2086 break;
2087 case OMPDeclareReductionInitKind::Call:
2088 break;
2093 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
2094 for (const auto *C : D->clauselists()) {
2095 AddChild([=] {
2096 if (!C) {
2097 ColorScope Color(OS, ShowColors, NullColor);
2098 OS << "<<<NULL>>> OMPClause";
2099 return;
2102 ColorScope Color(OS, ShowColors, AttrColor);
2103 StringRef ClauseName(
2104 llvm::omp::getOpenMPClauseName(C->getClauseKind()));
2105 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
2106 << ClauseName.drop_front() << "Clause";
2108 dumpPointer(C);
2109 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
2114 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
2115 dumpName(D);
2116 dumpType(D->getType());
2119 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
2120 dumpName(D);
2121 if (D->isInline())
2122 OS << " inline";
2123 if (D->isNested())
2124 OS << " nested";
2125 if (!D->isOriginalNamespace())
2126 dumpDeclRef(D->getOriginalNamespace(), "original");
2129 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
2130 OS << ' ';
2131 dumpBareDeclRef(D->getNominatedNamespace());
2134 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
2135 dumpName(D);
2136 dumpDeclRef(D->getAliasedNamespace());
2139 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
2140 dumpName(D);
2141 dumpType(D->getUnderlyingType());
2144 void TextNodeDumper::VisitTypeAliasTemplateDecl(
2145 const TypeAliasTemplateDecl *D) {
2146 dumpName(D);
2149 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
2150 VisitRecordDecl(D);
2151 if (const auto *Instance = D->getInstantiatedFromMemberClass()) {
2152 OS << " instantiated_from";
2153 dumpPointer(Instance);
2155 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
2156 dumpTemplateSpecializationKind(CTSD->getSpecializationKind());
2158 dumpNestedNameSpecifier(D->getQualifier());
2160 if (!D->isCompleteDefinition())
2161 return;
2163 AddChild([=] {
2165 ColorScope Color(OS, ShowColors, DeclKindNameColor);
2166 OS << "DefinitionData";
2168 #define FLAG(fn, name) \
2169 if (D->fn()) \
2170 OS << " " #name;
2171 FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
2173 FLAG(isGenericLambda, generic);
2174 FLAG(isLambda, lambda);
2176 FLAG(isAnonymousStructOrUnion, is_anonymous);
2177 FLAG(canPassInRegisters, pass_in_registers);
2178 FLAG(isEmpty, empty);
2179 FLAG(isAggregate, aggregate);
2180 FLAG(isStandardLayout, standard_layout);
2181 FLAG(isTriviallyCopyable, trivially_copyable);
2182 FLAG(isPOD, pod);
2183 FLAG(isTrivial, trivial);
2184 FLAG(isPolymorphic, polymorphic);
2185 FLAG(isAbstract, abstract);
2186 FLAG(isLiteral, literal);
2188 FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
2189 FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
2190 FLAG(hasMutableFields, has_mutable_fields);
2191 FLAG(hasVariantMembers, has_variant_members);
2192 FLAG(allowConstDefaultInit, can_const_default_init);
2194 AddChild([=] {
2196 ColorScope Color(OS, ShowColors, DeclKindNameColor);
2197 OS << "DefaultConstructor";
2199 FLAG(hasDefaultConstructor, exists);
2200 FLAG(hasTrivialDefaultConstructor, trivial);
2201 FLAG(hasNonTrivialDefaultConstructor, non_trivial);
2202 FLAG(hasUserProvidedDefaultConstructor, user_provided);
2203 FLAG(hasConstexprDefaultConstructor, constexpr);
2204 FLAG(needsImplicitDefaultConstructor, needs_implicit);
2205 FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
2208 AddChild([=] {
2210 ColorScope Color(OS, ShowColors, DeclKindNameColor);
2211 OS << "CopyConstructor";
2213 FLAG(hasSimpleCopyConstructor, simple);
2214 FLAG(hasTrivialCopyConstructor, trivial);
2215 FLAG(hasNonTrivialCopyConstructor, non_trivial);
2216 FLAG(hasUserDeclaredCopyConstructor, user_declared);
2217 FLAG(hasCopyConstructorWithConstParam, has_const_param);
2218 FLAG(needsImplicitCopyConstructor, needs_implicit);
2219 FLAG(needsOverloadResolutionForCopyConstructor,
2220 needs_overload_resolution);
2221 if (!D->needsOverloadResolutionForCopyConstructor())
2222 FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
2223 FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
2226 AddChild([=] {
2228 ColorScope Color(OS, ShowColors, DeclKindNameColor);
2229 OS << "MoveConstructor";
2231 FLAG(hasMoveConstructor, exists);
2232 FLAG(hasSimpleMoveConstructor, simple);
2233 FLAG(hasTrivialMoveConstructor, trivial);
2234 FLAG(hasNonTrivialMoveConstructor, non_trivial);
2235 FLAG(hasUserDeclaredMoveConstructor, user_declared);
2236 FLAG(needsImplicitMoveConstructor, needs_implicit);
2237 FLAG(needsOverloadResolutionForMoveConstructor,
2238 needs_overload_resolution);
2239 if (!D->needsOverloadResolutionForMoveConstructor())
2240 FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
2243 AddChild([=] {
2245 ColorScope Color(OS, ShowColors, DeclKindNameColor);
2246 OS << "CopyAssignment";
2248 FLAG(hasSimpleCopyAssignment, simple);
2249 FLAG(hasTrivialCopyAssignment, trivial);
2250 FLAG(hasNonTrivialCopyAssignment, non_trivial);
2251 FLAG(hasCopyAssignmentWithConstParam, has_const_param);
2252 FLAG(hasUserDeclaredCopyAssignment, user_declared);
2253 FLAG(needsImplicitCopyAssignment, needs_implicit);
2254 FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
2255 FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
2258 AddChild([=] {
2260 ColorScope Color(OS, ShowColors, DeclKindNameColor);
2261 OS << "MoveAssignment";
2263 FLAG(hasMoveAssignment, exists);
2264 FLAG(hasSimpleMoveAssignment, simple);
2265 FLAG(hasTrivialMoveAssignment, trivial);
2266 FLAG(hasNonTrivialMoveAssignment, non_trivial);
2267 FLAG(hasUserDeclaredMoveAssignment, user_declared);
2268 FLAG(needsImplicitMoveAssignment, needs_implicit);
2269 FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
2272 AddChild([=] {
2274 ColorScope Color(OS, ShowColors, DeclKindNameColor);
2275 OS << "Destructor";
2277 FLAG(hasSimpleDestructor, simple);
2278 FLAG(hasIrrelevantDestructor, irrelevant);
2279 FLAG(hasTrivialDestructor, trivial);
2280 FLAG(hasNonTrivialDestructor, non_trivial);
2281 FLAG(hasUserDeclaredDestructor, user_declared);
2282 FLAG(hasConstexprDestructor, constexpr);
2283 FLAG(needsImplicitDestructor, needs_implicit);
2284 FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
2285 if (!D->needsOverloadResolutionForDestructor())
2286 FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
2290 for (const auto &I : D->bases()) {
2291 AddChild([=] {
2292 if (I.isVirtual())
2293 OS << "virtual ";
2294 dumpAccessSpecifier(I.getAccessSpecifier());
2295 dumpType(I.getType());
2296 if (I.isPackExpansion())
2297 OS << "...";
2302 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
2303 dumpName(D);
2306 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
2307 dumpName(D);
2310 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
2311 dumpName(D);
2314 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
2315 dumpName(D);
2318 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2319 if (const auto *TC = D->getTypeConstraint()) {
2320 OS << " ";
2321 dumpBareDeclRef(TC->getNamedConcept());
2322 if (TC->getNamedConcept() != TC->getFoundDecl()) {
2323 OS << " (";
2324 dumpBareDeclRef(TC->getFoundDecl());
2325 OS << ")";
2327 } else if (D->wasDeclaredWithTypename())
2328 OS << " typename";
2329 else
2330 OS << " class";
2331 OS << " depth " << D->getDepth() << " index " << D->getIndex();
2332 if (D->isParameterPack())
2333 OS << " ...";
2334 dumpName(D);
2337 void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2338 const NonTypeTemplateParmDecl *D) {
2339 dumpType(D->getType());
2340 OS << " depth " << D->getDepth() << " index " << D->getIndex();
2341 if (D->isParameterPack())
2342 OS << " ...";
2343 dumpName(D);
2346 void TextNodeDumper::VisitTemplateTemplateParmDecl(
2347 const TemplateTemplateParmDecl *D) {
2348 OS << " depth " << D->getDepth() << " index " << D->getIndex();
2349 if (D->isParameterPack())
2350 OS << " ...";
2351 dumpName(D);
2354 void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
2355 OS << ' ';
2356 if (D->getQualifier())
2357 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2358 OS << D->getDeclName();
2359 dumpNestedNameSpecifier(D->getQualifier());
2362 void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) {
2363 OS << ' ';
2364 dumpBareDeclRef(D->getEnumDecl());
2367 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2368 const UnresolvedUsingTypenameDecl *D) {
2369 OS << ' ';
2370 if (D->getQualifier())
2371 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2372 OS << D->getDeclName();
2375 void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2376 const UnresolvedUsingValueDecl *D) {
2377 OS << ' ';
2378 if (D->getQualifier())
2379 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2380 OS << D->getDeclName();
2381 dumpType(D->getType());
2384 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
2385 OS << ' ';
2386 dumpBareDeclRef(D->getTargetDecl());
2389 void TextNodeDumper::VisitConstructorUsingShadowDecl(
2390 const ConstructorUsingShadowDecl *D) {
2391 if (D->constructsVirtualBase())
2392 OS << " virtual";
2394 AddChild([=] {
2395 OS << "target ";
2396 dumpBareDeclRef(D->getTargetDecl());
2399 AddChild([=] {
2400 OS << "nominated ";
2401 dumpBareDeclRef(D->getNominatedBaseClass());
2402 OS << ' ';
2403 dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
2406 AddChild([=] {
2407 OS << "constructed ";
2408 dumpBareDeclRef(D->getConstructedBaseClass());
2409 OS << ' ';
2410 dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
2414 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
2415 switch (D->getLanguage()) {
2416 case LinkageSpecLanguageIDs::C:
2417 OS << " C";
2418 break;
2419 case LinkageSpecLanguageIDs::CXX:
2420 OS << " C++";
2421 break;
2425 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
2426 OS << ' ';
2427 dumpAccessSpecifier(D->getAccess());
2430 void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
2431 if (TypeSourceInfo *T = D->getFriendType())
2432 dumpType(T->getType());
2435 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
2436 dumpName(D);
2437 dumpType(D->getType());
2438 if (D->getSynthesize())
2439 OS << " synthesize";
2441 switch (D->getAccessControl()) {
2442 case ObjCIvarDecl::None:
2443 OS << " none";
2444 break;
2445 case ObjCIvarDecl::Private:
2446 OS << " private";
2447 break;
2448 case ObjCIvarDecl::Protected:
2449 OS << " protected";
2450 break;
2451 case ObjCIvarDecl::Public:
2452 OS << " public";
2453 break;
2454 case ObjCIvarDecl::Package:
2455 OS << " package";
2456 break;
2460 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
2461 if (D->isInstanceMethod())
2462 OS << " -";
2463 else
2464 OS << " +";
2465 dumpName(D);
2466 dumpType(D->getReturnType());
2468 if (D->isVariadic())
2469 OS << " variadic";
2472 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
2473 dumpName(D);
2474 switch (D->getVariance()) {
2475 case ObjCTypeParamVariance::Invariant:
2476 break;
2478 case ObjCTypeParamVariance::Covariant:
2479 OS << " covariant";
2480 break;
2482 case ObjCTypeParamVariance::Contravariant:
2483 OS << " contravariant";
2484 break;
2487 if (D->hasExplicitBound())
2488 OS << " bounded";
2489 dumpType(D->getUnderlyingType());
2492 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
2493 dumpName(D);
2494 dumpDeclRef(D->getClassInterface());
2495 dumpDeclRef(D->getImplementation());
2496 for (const auto *P : D->protocols())
2497 dumpDeclRef(P);
2500 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
2501 dumpName(D);
2502 dumpDeclRef(D->getClassInterface());
2503 dumpDeclRef(D->getCategoryDecl());
2506 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
2507 dumpName(D);
2509 for (const auto *Child : D->protocols())
2510 dumpDeclRef(Child);
2513 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
2514 dumpName(D);
2515 dumpDeclRef(D->getSuperClass(), "super");
2517 dumpDeclRef(D->getImplementation());
2518 for (const auto *Child : D->protocols())
2519 dumpDeclRef(Child);
2522 void TextNodeDumper::VisitObjCImplementationDecl(
2523 const ObjCImplementationDecl *D) {
2524 dumpName(D);
2525 dumpDeclRef(D->getSuperClass(), "super");
2526 dumpDeclRef(D->getClassInterface());
2529 void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2530 const ObjCCompatibleAliasDecl *D) {
2531 dumpName(D);
2532 dumpDeclRef(D->getClassInterface());
2535 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
2536 dumpName(D);
2537 dumpType(D->getType());
2539 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
2540 OS << " required";
2541 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
2542 OS << " optional";
2544 ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
2545 if (Attrs != ObjCPropertyAttribute::kind_noattr) {
2546 if (Attrs & ObjCPropertyAttribute::kind_readonly)
2547 OS << " readonly";
2548 if (Attrs & ObjCPropertyAttribute::kind_assign)
2549 OS << " assign";
2550 if (Attrs & ObjCPropertyAttribute::kind_readwrite)
2551 OS << " readwrite";
2552 if (Attrs & ObjCPropertyAttribute::kind_retain)
2553 OS << " retain";
2554 if (Attrs & ObjCPropertyAttribute::kind_copy)
2555 OS << " copy";
2556 if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
2557 OS << " nonatomic";
2558 if (Attrs & ObjCPropertyAttribute::kind_atomic)
2559 OS << " atomic";
2560 if (Attrs & ObjCPropertyAttribute::kind_weak)
2561 OS << " weak";
2562 if (Attrs & ObjCPropertyAttribute::kind_strong)
2563 OS << " strong";
2564 if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
2565 OS << " unsafe_unretained";
2566 if (Attrs & ObjCPropertyAttribute::kind_class)
2567 OS << " class";
2568 if (Attrs & ObjCPropertyAttribute::kind_direct)
2569 OS << " direct";
2570 if (Attrs & ObjCPropertyAttribute::kind_getter)
2571 dumpDeclRef(D->getGetterMethodDecl(), "getter");
2572 if (Attrs & ObjCPropertyAttribute::kind_setter)
2573 dumpDeclRef(D->getSetterMethodDecl(), "setter");
2577 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
2578 dumpName(D->getPropertyDecl());
2579 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
2580 OS << " synthesize";
2581 else
2582 OS << " dynamic";
2583 dumpDeclRef(D->getPropertyDecl());
2584 dumpDeclRef(D->getPropertyIvarDecl());
2587 void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
2588 if (D->isVariadic())
2589 OS << " variadic";
2591 if (D->capturesCXXThis())
2592 OS << " captures_this";
2595 void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
2596 dumpName(D);
2599 void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
2600 VisitStmt(S);
2601 if (S->hasStoredFPFeatures())
2602 printFPOptions(S->getStoredFPFeatures());
2605 void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) {
2606 if (D->isCBuffer())
2607 OS << " cbuffer";
2608 else
2609 OS << " tbuffer";
2610 dumpName(D);