[RISCV][GISel] Make s16->s32 G_ANYEXT/SEXT/ZEXT legal.
[llvm-project.git] / clang / lib / AST / TextNodeDumper.cpp
blob2552c11a3953205b3d2b6414438249e89a60c988
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/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"
28 #include <algorithm>
29 #include <utility>
31 using namespace clang;
33 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
35 template <typename T>
36 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
37 const T *First = D->getFirstDecl();
38 if (First != D)
39 OS << " first " << First;
42 template <typename T>
43 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
44 const T *Prev = D->getPreviousDecl();
45 if (Prev)
46 OS << " prev " << Prev;
49 /// Dump the previous declaration in the redeclaration chain for a declaration,
50 /// if any.
51 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
52 switch (D->getKind()) {
53 #define DECL(DERIVED, BASE) \
54 case Decl::DERIVED: \
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,
63 bool ShowColors)
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) {
74 if (!C) {
75 ColorScope Color(OS, ShowColors, NullColor);
76 OS << "<<<NULL>>>";
77 return;
81 ColorScope Color(OS, ShowColors, CommentColor);
82 OS << C->getCommentKindName();
84 dumpPointer(C);
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()) {
96 #define ATTR(X) \
97 case attr::X: \
98 OS << #X; \
99 break;
100 #include "clang/Basic/AttrList.inc"
102 OS << "Attr";
104 dumpPointer(A);
105 dumpSourceRange(A->getRange());
106 if (A->isInherited())
107 OS << " Inherited";
108 if (A->isImplicit())
109 OS << " Implicit";
111 ConstAttrVisitor<TextNodeDumper>::Visit(A);
114 void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
115 const Decl *From, StringRef Label) {
116 OS << "TemplateArgument";
117 if (R.isValid())
118 dumpSourceRange(R);
120 if (From)
121 dumpDeclRef(From, Label);
123 ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
126 void TextNodeDumper::Visit(const Stmt *Node) {
127 if (!Node) {
128 ColorScope Color(OS, ShowColors, NullColor);
129 OS << "<<<NULL>>>";
130 return;
133 ColorScope Color(OS, ShowColors, StmtColor);
134 OS << Node->getStmtClassName();
136 dumpPointer(Node);
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()) {
150 case VK_PRValue:
151 break;
152 case VK_LValue:
153 OS << " lvalue";
154 break;
155 case VK_XValue:
156 OS << " xvalue";
157 break;
162 ColorScope Color(OS, ShowColors, ObjectKindColor);
163 switch (E->getObjectKind()) {
164 case OK_Ordinary:
165 break;
166 case OK_BitField:
167 OS << " bitfield";
168 break;
169 case OK_ObjCProperty:
170 OS << " objcproperty";
171 break;
172 case OK_ObjCSubscript:
173 OS << " objcsubscript";
174 break;
175 case OK_VectorComponent:
176 OS << " vectorcomponent";
177 break;
178 case OK_MatrixComponent:
179 OS << " matrixcomponent";
180 break;
185 ConstStmtVisitor<TextNodeDumper>::Visit(Node);
188 void TextNodeDumper::Visit(const Type *T) {
189 if (!T) {
190 ColorScope Color(OS, ShowColors, NullColor);
191 OS << "<<<NULL>>>";
192 return;
194 if (isa<LocInfoType>(T)) {
196 ColorScope Color(OS, ShowColors, TypeColor);
197 OS << "LocInfo Type";
199 dumpPointer(T);
200 return;
204 ColorScope Color(OS, ShowColors, TypeColor);
205 OS << T->getTypeClassName() << "Type";
207 dumpPointer(T);
208 OS << " ";
209 dumpBareType(QualType(T, 0), false);
211 QualType SingleStepDesugar =
212 T->getLocallyUnqualifiedSingleStepDesugaredType();
213 if (SingleStepDesugar != QualType(T, 0))
214 OS << " sugar";
216 if (T->containsErrors()) {
217 ColorScope Color(OS, ShowColors, ErrorsColor);
218 OS << " contains-errors";
221 if (T->isDependentType())
222 OS << " dependent";
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";
230 if (T->isFromAST())
231 OS << " imported";
233 TypeVisitor<TextNodeDumper>::Visit(T);
236 void TextNodeDumper::Visit(QualType T) {
237 OS << "QualType";
238 dumpPointer(T.getAsOpaquePtr());
239 OS << " ";
240 dumpBareType(T, false);
241 OS << " " << T.split().Quals.getAsString();
244 void TextNodeDumper::Visit(TypeLoc TL) {
245 if (!TL) {
246 ColorScope Color(OS, ShowColors, NullColor);
247 OS << "<<<NULL>>>";
248 return;
252 ColorScope Color(OS, ShowColors, TypeColor);
253 OS << (TL.getTypeLocClass() == TypeLoc::Qualified
254 ? "Qualified"
255 : TL.getType()->getTypeClassName())
256 << "TypeLoc";
258 dumpSourceRange(TL.getSourceRange());
259 OS << ' ';
260 dumpBareType(TL.getType(), /*Desugar=*/false);
262 TypeLocVisitor<TextNodeDumper>::Visit(TL);
265 void TextNodeDumper::Visit(const Decl *D) {
266 if (!D) {
267 ColorScope Color(OS, ShowColors, NullColor);
268 OS << "<<<NULL>>>";
269 return;
273 ColorScope Color(OS, ShowColors, DeclKindNameColor);
274 OS << D->getDeclKindName() << "Decl";
276 dumpPointer(D);
277 if (D->getLexicalDeclContext() != D->getDeclContext())
278 OS << " parent " << cast<Decl>(D->getDeclContext());
279 dumpPreviousDecl(OS, D);
280 dumpSourceRange(D->getSourceRange());
281 OS << ' ';
282 dumpLocation(D->getLocation());
283 if (D->isFromASTFile())
284 OS << " imported";
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())
293 OS << " hidden";
294 if (D->isImplicit())
295 OS << " implicit";
297 if (D->isUsed())
298 OS << " used";
299 else if (D->isThisDeclarationReferenced())
300 OS << " referenced";
302 if (D->isInvalidDecl())
303 OS << " invalid";
304 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
305 if (FD->isConstexprSpecified())
306 OS << " constexpr";
307 if (FD->isConsteval())
308 OS << " consteval";
309 else if (FD->isImmediateFunction())
310 OS << " immediate";
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()) {
327 case Decl::FOK_None:
328 break;
329 case Decl::FOK_Declared:
330 OS << " friend";
331 break;
332 case Decl::FOK_Undeclared:
333 OS << " friend_undeclared";
334 break;
337 ConstDeclVisitor<TextNodeDumper>::Visit(D);
340 void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
341 OS << "CXXCtorInitializer";
342 if (Init->isAnyMemberInitializer()) {
343 OS << ' ';
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());
349 } else {
350 llvm_unreachable("Unknown initializer type");
354 void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
355 OS << "capture";
356 if (C.isByRef())
357 OS << " byref";
358 if (C.isNested())
359 OS << " nested";
360 if (C.getVariable()) {
361 OS << ' ';
362 dumpBareDeclRef(C.getVariable());
366 void TextNodeDumper::Visit(const OMPClause *C) {
367 if (!C) {
368 ColorScope Color(OS, ShowColors, NullColor);
369 OS << "<<<NULL>>> OMPClause";
370 return;
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";
378 dumpPointer(C);
379 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
380 if (C->isImplicit())
381 OS << " <implicit>";
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) {
390 if (!C) {
391 ColorScope Color(OS, ShowColors, NullColor);
392 OS << "<<<NULL>>> OpenACCClause";
393 return;
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() << ')';
404 break;
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.
428 OS << " clause";
429 break;
430 case OpenACCClauseKind::Gang: {
431 OS << " clause";
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;
439 break;
441 case OpenACCClauseKind::Collapse:
442 OS << " clause";
443 if (cast<OpenACCCollapseClause>(C)->hasForce())
444 OS << ": force";
445 break;
447 case OpenACCClauseKind::CopyIn:
448 case OpenACCClauseKind::PCopyIn:
449 case OpenACCClauseKind::PresentOrCopyIn:
450 OS << " clause";
451 if (cast<OpenACCCopyInClause>(C)->isReadOnly())
452 OS << " : readonly";
453 break;
454 case OpenACCClauseKind::CopyOut:
455 case OpenACCClauseKind::PCopyOut:
456 case OpenACCClauseKind::PresentOrCopyOut:
457 OS << " clause";
458 if (cast<OpenACCCopyOutClause>(C)->isZero())
459 OS << " : zero";
460 break;
461 case OpenACCClauseKind::Create:
462 case OpenACCClauseKind::PCreate:
463 case OpenACCClauseKind::PresentOrCreate:
464 OS << " clause";
465 if (cast<OpenACCCreateClause>(C)->isZero())
466 OS << " : zero";
467 break;
468 case OpenACCClauseKind::Wait:
469 OS << " clause";
470 if (cast<OpenACCWaitClause>(C)->hasDevNumExpr())
471 OS << " has devnum";
472 if (cast<OpenACCWaitClause>(C)->hasQueuesTag())
473 OS << " has queues tag";
474 break;
475 case OpenACCClauseKind::DeviceType:
476 case OpenACCClauseKind::DType:
477 OS << "(";
478 llvm::interleaveComma(
479 cast<OpenACCDeviceTypeClause>(C)->getArchitectures(), OS,
480 [&](const DeviceTypeArgument &Arch) {
481 if (Arch.first == nullptr)
482 OS << "*";
483 else
484 OS << Arch.first->getName();
486 OS << ")";
487 break;
488 case OpenACCClauseKind::Reduction:
489 OS << " clause Operator: "
490 << cast<OpenACCReductionClause>(C)->getReductionOp();
491 break;
492 default:
493 // Nothing to do here.
494 break;
497 dumpPointer(C);
498 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
501 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
502 const TypeSourceInfo *TSI = A.getTypeSourceInfo();
503 if (TSI) {
504 OS << "case ";
505 dumpType(TSI->getType());
506 } else {
507 OS << "default";
510 if (A.isSelected())
511 OS << " selected";
514 void TextNodeDumper::Visit(const ConceptReference *R) {
515 if (!R) {
516 ColorScope Color(OS, ShowColors, NullColor);
517 OS << "<<<NULL>>> ConceptReference";
518 return;
521 OS << "ConceptReference";
522 dumpPointer(R);
523 dumpSourceRange(R->getSourceRange());
524 OS << ' ';
525 dumpBareDeclRef(R->getNamedConcept());
528 void TextNodeDumper::Visit(const concepts::Requirement *R) {
529 if (!R) {
530 ColorScope Color(OS, ShowColors, NullColor);
531 OS << "<<<NULL>>> Requirement";
532 return;
536 ColorScope Color(OS, ShowColors, StmtColor);
537 switch (R->getKind()) {
538 case concepts::Requirement::RK_Type:
539 OS << "TypeRequirement";
540 break;
541 case concepts::Requirement::RK_Simple:
542 OS << "SimpleRequirement";
543 break;
544 case concepts::Requirement::RK_Compound:
545 OS << "CompoundRequirement";
546 break;
547 case concepts::Requirement::RK_Nested:
548 OS << "NestedRequirement";
549 break;
553 dumpPointer(R);
555 if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) {
556 if (ER->hasNoexceptRequirement())
557 OS << " noexcept";
560 if (R->isDependent())
561 OS << " dependent";
562 else
563 OS << (R->isSatisfied() ? " satisfied" : " unsatisfied");
564 if (R->containsUnexpandedParameterPack())
565 OS << " contains_unexpanded_pack";
568 static double GetApproxValue(const llvm::APFloat &F) {
569 llvm::APFloat V = F;
570 bool ignored;
571 V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
572 &ignored);
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()) {
579 case APValue::None:
580 case APValue::Indeterminate:
581 case APValue::Int:
582 case APValue::Float:
583 case APValue::FixedPoint:
584 case APValue::ComplexInt:
585 case APValue::ComplexFloat:
586 case APValue::LValue:
587 case APValue::MemberPointer:
588 case APValue::AddrLabelDiff:
589 return true;
590 case APValue::Vector:
591 case APValue::Array:
592 case APValue::Struct:
593 return false;
594 case APValue::Union:
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;
620 unsigned I = 0;
621 while (I < NumChildren) {
622 unsigned J = I;
623 while (J < NumChildren) {
624 if (isSimpleAPValue(IdxToChildFun(Value, J)) &&
625 (J - I < MaxChildrenPerLine)) {
626 ++J;
627 continue;
629 break;
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);
638 if (X + 1 != J)
639 OS << ", ";
642 I = J;
646 void TextNodeDumper::Visit(const APValue &Value, QualType Ty) {
647 ColorScope Color(OS, ShowColors, ValueKindColor);
648 switch (Value.getKind()) {
649 case APValue::None:
650 OS << "None";
651 return;
652 case APValue::Indeterminate:
653 OS << "Indeterminate";
654 return;
655 case APValue::Int:
656 OS << "Int ";
658 ColorScope Color(OS, ShowColors, ValueColor);
659 OS << Value.getInt();
661 return;
662 case APValue::Float:
663 OS << "Float ";
665 ColorScope Color(OS, ShowColors, ValueColor);
666 OS << GetApproxValue(Value.getFloat());
668 return;
669 case APValue::FixedPoint:
670 OS << "FixedPoint ";
672 ColorScope Color(OS, ShowColors, ValueColor);
673 OS << Value.getFixedPoint();
675 return;
676 case APValue::Vector: {
677 unsigned VectorLength = Value.getVectorLength();
678 OS << "Vector length=" << VectorLength;
680 dumpAPValueChildren(
681 Value, Ty,
682 [](const APValue &Value, unsigned Index) -> const APValue & {
683 return Value.getVectorElt(Index);
685 VectorLength, "element", "elements");
686 return;
688 case APValue::ComplexInt:
689 OS << "ComplexInt ";
691 ColorScope Color(OS, ShowColors, ValueColor);
692 OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag()
693 << 'i';
695 return;
696 case APValue::ComplexFloat:
697 OS << "ComplexFloat ";
699 ColorScope Color(OS, ShowColors, ValueColor);
700 OS << GetApproxValue(Value.getComplexFloatReal()) << " + "
701 << GetApproxValue(Value.getComplexFloatImag()) << 'i';
703 return;
704 case APValue::LValue:
705 (void)Context;
706 OS << "LValue <todo>";
707 return;
708 case APValue::Array: {
709 unsigned ArraySize = Value.getArraySize();
710 unsigned NumInitializedElements = Value.getArrayInitializedElts();
711 OS << "Array size=" << ArraySize;
713 dumpAPValueChildren(
714 Value, Ty,
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);
730 return;
732 case APValue::Struct: {
733 OS << "Struct";
735 dumpAPValueChildren(
736 Value, Ty,
737 [](const APValue &Value, unsigned Index) -> const APValue & {
738 return Value.getStructBase(Index);
740 Value.getStructNumBases(), "base", "bases");
742 dumpAPValueChildren(
743 Value, Ty,
744 [](const APValue &Value, unsigned Index) -> const APValue & {
745 return Value.getStructField(Index);
747 Value.getStructNumFields(), "field", "fields");
749 return;
751 case APValue::Union: {
752 OS << "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)) {
762 OS << ' ';
763 Visit(UnionValue, Ty);
764 } else {
765 AddChild([=] { Visit(UnionValue, Ty); });
768 return;
770 case APValue::MemberPointer:
771 OS << "MemberPointer <todo>";
772 return;
773 case APValue::AddrLabelDiff:
774 OS << "AddrLabelDiff <todo>";
775 return;
777 llvm_unreachable("Unknown APValue kind!");
780 void TextNodeDumper::dumpPointer(const void *Ptr) {
781 ColorScope Color(OS, ShowColors, AddressColor);
782 OS << ' ' << Ptr;
785 void TextNodeDumper::dumpLocation(SourceLocation Loc) {
786 if (!SM)
787 return;
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>";
798 return;
801 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
802 OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
803 << PLoc.getColumn();
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();
809 } else {
810 OS << "col" << ':' << PLoc.getColumn();
814 void TextNodeDumper::dumpSourceRange(SourceRange R) {
815 // Can't translate locations if a SourceManager isn't available.
816 if (!SM)
817 return;
819 OS << " <";
820 dumpLocation(R.getBegin());
821 if (R.getBegin() != R.getEnd()) {
822 OS << ", ";
823 dumpLocation(R.getEnd());
825 OS << ">";
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);
843 if (T_str != D_str)
844 OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
849 void TextNodeDumper::dumpType(QualType T) {
850 OS << ' ';
851 dumpBareType(T);
854 void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
855 if (!D) {
856 ColorScope Color(OS, ShowColors, NullColor);
857 OS << "<<<NULL>>>";
858 return;
862 ColorScope Color(OS, ShowColors, DeclKindNameColor);
863 OS << D->getDeclKindName();
865 dumpPointer(D);
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())
886 return;
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 *>())
895 AddChild([=] {
896 OS << "cleanup ";
898 ColorScope Color(OS, ShowColors, StmtColor);
899 OS << CLE->getStmtClassName();
901 dumpPointer(CLE);
903 else
904 llvm_unreachable("unexpected cleanup type");
907 void clang::TextNodeDumper::dumpTemplateSpecializationKind(
908 TemplateSpecializationKind TSK) {
909 switch (TSK) {
910 case TSK_Undeclared:
911 break;
912 case TSK_ImplicitInstantiation:
913 OS << " implicit_instantiation";
914 break;
915 case TSK_ExplicitSpecialization:
916 OS << " explicit_specialization";
917 break;
918 case TSK_ExplicitInstantiationDeclaration:
919 OS << " explicit_instantiation_declaration";
920 break;
921 case TSK_ExplicitInstantiationDefinition:
922 OS << " explicit_instantiation_definition";
923 break;
927 void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier *NNS) {
928 if (!NNS)
929 return;
931 AddChild([=] {
932 OS << "NestedNameSpecifier";
934 switch (NNS->getKind()) {
935 case NestedNameSpecifier::Identifier:
936 OS << " Identifier";
937 OS << " '" << NNS->getAsIdentifier()->getName() << "'";
938 break;
939 case NestedNameSpecifier::Namespace:
940 OS << " "; // "Namespace" is printed as the decl kind.
941 dumpBareDeclRef(NNS->getAsNamespace());
942 break;
943 case NestedNameSpecifier::NamespaceAlias:
944 OS << " "; // "NamespaceAlias" is printed as the decl kind.
945 dumpBareDeclRef(NNS->getAsNamespaceAlias());
946 break;
947 case NestedNameSpecifier::TypeSpec:
948 OS << " TypeSpec";
949 dumpType(QualType(NNS->getAsType(), 0));
950 break;
951 case NestedNameSpecifier::TypeSpecWithTemplate:
952 OS << " TypeSpecWithTemplate";
953 dumpType(QualType(NNS->getAsType(), 0));
954 break;
955 case NestedNameSpecifier::Global:
956 OS << " Global";
957 break;
958 case NestedNameSpecifier::Super:
959 OS << " Super";
960 break;
963 dumpNestedNameSpecifier(NNS->getPrefix());
967 void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
968 if (!D)
969 return;
971 AddChild([=] {
972 if (!Label.empty())
973 OS << Label << ' ';
974 dumpBareDeclRef(D);
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 << "'";
986 if (!Context)
987 return;
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);
996 if (CanonStr != Str)
997 OS << ":'" << CanonStr << "'";
1001 const char *TextNodeDumper::getCommandName(unsigned CommandID) {
1002 if (Traits)
1003 return Traits->getCommandInfo(CommandID)->Name;
1004 const comments::CommandInfo *Info =
1005 comments::CommandTraits::getBuiltinCommandInfo(CommandID);
1006 if (Info)
1007 return Info->Name;
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";
1029 break;
1030 case comments::InlineCommandRenderKind::Bold:
1031 OS << " RenderBold";
1032 break;
1033 case comments::InlineCommandRenderKind::Monospaced:
1034 OS << " RenderMonospaced";
1035 break;
1036 case comments::InlineCommandRenderKind::Emphasized:
1037 OS << " RenderEmphasized";
1038 break;
1039 case comments::InlineCommandRenderKind::Anchor:
1040 OS << " RenderAnchor";
1041 break;
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) {
1052 OS << " Attrs: ";
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) {
1076 OS << " "
1077 << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
1079 if (C->isDirectionExplicit())
1080 OS << " explicitly";
1081 else
1082 OS << " implicitly";
1084 if (C->hasParamName()) {
1085 if (C->isParamIndexValid())
1086 OS << " Param=\"" << C->getParamName(FC) << "\"";
1087 else
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) << "\"";
1100 else
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);
1108 if (i != e - 1)
1109 OS << ", ";
1111 OS << ">";
1115 void TextNodeDumper::visitVerbatimBlockComment(
1116 const comments::VerbatimBlockComment *C, const comments::FullComment *) {
1117 OS << " Name=\"" << getCommandName(C->getCommandID())
1118 << "\""
1119 " CloseName=\""
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 &) {
1135 OS << " null";
1138 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
1139 OS << " type";
1140 dumpTemplateArgument(TA);
1143 void TextNodeDumper::VisitDeclarationTemplateArgument(
1144 const TemplateArgument &TA) {
1145 OS << " decl";
1146 dumpTemplateArgument(TA);
1147 dumpDeclRef(TA.getAsDecl());
1150 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) {
1151 OS << " nullptr";
1152 dumpTemplateArgument(TA);
1155 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
1156 OS << " integral";
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 << "'";
1170 if (Context) {
1171 if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN);
1172 CanonTN != 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()); });
1191 return;
1192 case TemplateName::UsingTemplate: {
1193 const UsingShadowDecl *USD = TN.getAsUsingShadowDecl();
1194 AddChild([=] { Visit(USD); });
1195 AddChild("target", [=] { Visit(USD->getTargetDecl()); });
1196 return;
1198 case TemplateName::QualifiedTemplate: {
1199 OS << " qualified";
1200 const QualifiedTemplateName *QTN = TN.getAsQualifiedTemplateName();
1201 if (QTN->hasTemplateKeyword())
1202 OS << " keyword";
1203 dumpNestedNameSpecifier(QTN->getQualifier());
1204 dumpBareTemplateName(QTN->getUnderlyingTemplate());
1205 return;
1207 case TemplateName::DependentTemplate: {
1208 OS << " dependent";
1209 const DependentTemplateName *DTN = TN.getAsDependentTemplateName();
1210 dumpNestedNameSpecifier(DTN->getQualifier());
1211 return;
1213 case TemplateName::SubstTemplateTemplateParm: {
1214 OS << " subst";
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");
1224 return;
1226 case TemplateName::DeducedTemplate: {
1227 OS << " deduced";
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()); });
1236 return;
1238 // FIXME: Implement these.
1239 case TemplateName::OverloadedTemplate:
1240 OS << " overloaded";
1241 return;
1242 case TemplateName::AssumedTemplate:
1243 OS << " assumed";
1244 return;
1245 case TemplateName::SubstTemplateTemplateParmPack:
1246 OS << " subst_pack";
1247 return;
1249 llvm_unreachable("Unexpected TemplateName Kind");
1252 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
1253 OS << " template";
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) {
1267 OS << " expr";
1268 dumpTemplateArgument(TA);
1271 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) {
1272 OS << " pack";
1273 dumpTemplateArgument(TA);
1276 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
1277 if (Node->path_empty())
1278 return;
1280 OS << " (";
1281 bool First = true;
1282 for (CastExpr::path_const_iterator I = Node->path_begin(),
1283 E = Node->path_end();
1284 I != E; ++I) {
1285 const CXXBaseSpecifier *Base = *I;
1286 if (!First)
1287 OS << " -> ";
1289 const auto *RD =
1290 cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
1292 if (Base->isVirtual())
1293 OS << "virtual ";
1294 OS << RD->getName();
1295 First = false;
1298 OS << ')';
1301 void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
1302 if (Node->hasInitStorage())
1303 OS << " has_init";
1304 if (Node->hasVarStorage())
1305 OS << " has_var";
1306 if (Node->hasElseStorage())
1307 OS << " has_else";
1308 if (Node->isConstexpr())
1309 OS << " constexpr";
1310 if (Node->isConsteval()) {
1311 OS << " ";
1312 if (Node->isNegatedConsteval())
1313 OS << "!";
1314 OS << "consteval";
1318 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
1319 if (Node->hasInitStorage())
1320 OS << " has_init";
1321 if (Node->hasVarStorage())
1322 OS << " has_var";
1325 void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
1326 if (Node->hasVarStorage())
1327 OS << " has_var";
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())
1343 OS << " gnu_range";
1346 void clang::TextNodeDumper::VisitReturnStmt(const ReturnStmt *Node) {
1347 if (const VarDecl *Cand = Node->getNRVOCandidate()) {
1348 OS << " nrvo_candidate(";
1349 dumpBareDeclRef(Cand);
1350 OS << ")";
1354 void clang::TextNodeDumper::VisitCoawaitExpr(const CoawaitExpr *Node) {
1355 if (Node->isImplicit())
1356 OS << " implicit";
1359 void clang::TextNodeDumper::VisitCoreturnStmt(const CoreturnStmt *Node) {
1360 if (Node->isImplicit())
1361 OS << " implicit";
1364 void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
1365 if (Node->hasAPValueResult())
1366 AddChild("value",
1367 [=] { Visit(Node->getAPValueResult(), Node->getType()); });
1370 void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
1371 if (Node->usesADL())
1372 OS << " adl";
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) {
1386 OS << " <";
1388 ColorScope Color(OS, ShowColors, CastColor);
1389 OS << Node->getCastKindName();
1391 dumpBasePath(OS, Node);
1392 OS << ">";
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) {
1404 OS << " ";
1405 dumpBareDeclRef(Node->getDecl());
1406 dumpNestedNameSpecifier(Node->getQualifier());
1407 if (Node->getDecl() != Node->getFoundDecl()) {
1408 OS << " (";
1409 dumpBareDeclRef(Node->getFoundDecl());
1410 OS << ")";
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) {
1435 OS << " (";
1436 if (!Node->requiresADL())
1437 OS << "no ";
1438 OS << "ADL) = '" << Node->getName() << '\'';
1440 UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
1441 E = Node->decls_end();
1442 if (I == E)
1443 OS << " empty";
1444 for (; I != E; ++I)
1445 dumpPointer(*I);
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);
1491 OS << " ";
1492 Str->outputString(OS);
1495 void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
1496 if (auto *Field = ILE->getInitializedFieldInUnion()) {
1497 OS << " field ";
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);
1568 OS << ">";
1571 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1572 OS << " " << (Node->getValue() ? "true" : "false");
1575 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1576 if (Node->isImplicit())
1577 OS << " implicit";
1578 if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter())
1579 OS << " dependent_capture";
1580 OS << " this";
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())
1601 OS << " list";
1604 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1605 CXXConstructorDecl *Ctor = Node->getConstructor();
1606 dumpType(Ctor->getType());
1607 if (Node->isElidable())
1608 OS << " elidable";
1609 if (Node->isListInitialization())
1610 OS << " list";
1611 if (Node->isStdInitListInitialization())
1612 OS << " std::initializer_list";
1613 if (Node->requiresZeroInitialization())
1614 OS << " zeroing";
1615 if (Node->isImmediateEscalating())
1616 OS << " immediate-escalating";
1619 void TextNodeDumper::VisitCXXBindTemporaryExpr(
1620 const CXXBindTemporaryExpr *Node) {
1621 OS << " (CXXTemporary";
1622 dumpPointer(Node);
1623 OS << ")";
1626 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
1627 if (Node->isGlobalNew())
1628 OS << " global";
1629 if (Node->isArray())
1630 OS << " array";
1631 if (Node->getOperatorNew()) {
1632 OS << ' ';
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())
1641 OS << " global";
1642 if (Node->isArrayForm())
1643 OS << " array";
1644 if (Node->getOperatorDelete()) {
1645 OS << ' ';
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) {
1696 OS << " selector=";
1697 Node->getSelector().print(OS);
1698 switch (Node->getReceiverKind()) {
1699 case ObjCMessageExpr::Instance:
1700 break;
1702 case ObjCMessageExpr::Class:
1703 OS << " class=";
1704 dumpBareType(Node->getClassReceiver());
1705 break;
1707 case ObjCMessageExpr::SuperInstance:
1708 OS << " super (instance)";
1709 break;
1711 case ObjCMessageExpr::SuperClass:
1712 OS << " super (class)";
1713 break;
1717 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
1718 if (auto *BoxingMethod = Node->getBoxingMethod()) {
1719 OS << " selector=";
1720 BoxingMethod->getSelector().print(OS);
1724 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
1725 if (!Node->getCatchParamDecl())
1726 OS << " catch all";
1729 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
1730 dumpType(Node->getEncodedType());
1733 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1734 OS << " ";
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);
1747 else
1748 OS << "(null)";
1750 OS << "\" Setter=\"";
1751 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
1752 Setter->getSelector().print(OS);
1753 else
1754 OS << "(null)";
1755 OS << "\"";
1756 } else {
1757 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
1758 << '"';
1761 if (Node->isSuperReceiver())
1762 OS << " super";
1764 OS << " Messaging=";
1765 if (Node->isMessagingGetter() && Node->isMessagingSetter())
1766 OS << "Getter&Setter";
1767 else if (Node->isMessagingGetter())
1768 OS << "Getter";
1769 else if (Node->isMessagingSetter())
1770 OS << "Setter";
1773 void TextNodeDumper::VisitObjCSubscriptRefExpr(
1774 const ObjCSubscriptRefExpr *Node) {
1775 if (Node->isArraySubscriptRefExpr())
1776 OS << " Kind=ArraySubscript GetterForArray=\"";
1777 else
1778 OS << " Kind=DictionarySubscript GetterForDictionary=\"";
1779 if (Node->getAtIndexMethodDecl())
1780 Node->getAtIndexMethodDecl()->getSelector().print(OS);
1781 else
1782 OS << "(null)";
1784 if (Node->isArraySubscriptRefExpr())
1785 OS << "\" SetterForArray=\"";
1786 else
1787 OS << "\" SetterForDictionary=\"";
1788 if (Node->setAtIndexMethodDecl())
1789 Node->setAtIndexMethodDecl()->getSelector().print(OS);
1790 else
1791 OS << "(null)";
1794 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
1795 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
1798 void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) {
1799 OS << " ";
1800 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1801 Visit(Node->getIteratorDecl(I));
1802 OS << " = ";
1803 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1804 OS << " begin ";
1805 Visit(Range.Begin);
1806 OS << " end ";
1807 Visit(Range.End);
1808 if (Range.Step) {
1809 OS << " step ";
1810 Visit(Range.Step);
1815 void TextNodeDumper::VisitConceptSpecializationExpr(
1816 const ConceptSpecializationExpr *Node) {
1817 OS << " ";
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:
1835 break;
1836 case ArraySizeModifier::Static:
1837 OS << " static";
1838 break;
1839 case ArraySizeModifier::Star:
1840 OS << " *";
1841 break;
1843 OS << " " << T->getIndexTypeQualifiers().getAsString();
1846 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
1847 OS << " " << T->getSize();
1848 VisitArrayType(T);
1851 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
1852 OS << " ";
1853 dumpSourceRange(T->getBracketsRange());
1854 VisitArrayType(T);
1857 void TextNodeDumper::VisitDependentSizedArrayType(
1858 const DependentSizedArrayType *T) {
1859 VisitArrayType(T);
1860 OS << " ";
1861 dumpSourceRange(T->getBracketsRange());
1864 void TextNodeDumper::VisitDependentSizedExtVectorType(
1865 const DependentSizedExtVectorType *T) {
1866 OS << " ";
1867 dumpLocation(T->getAttributeLoc());
1870 void TextNodeDumper::VisitVectorType(const VectorType *T) {
1871 switch (T->getVectorKind()) {
1872 case VectorKind::Generic:
1873 break;
1874 case VectorKind::AltiVecVector:
1875 OS << " altivec";
1876 break;
1877 case VectorKind::AltiVecPixel:
1878 OS << " altivec pixel";
1879 break;
1880 case VectorKind::AltiVecBool:
1881 OS << " altivec bool";
1882 break;
1883 case VectorKind::Neon:
1884 OS << " neon";
1885 break;
1886 case VectorKind::NeonPoly:
1887 OS << " neon poly";
1888 break;
1889 case VectorKind::SveFixedLengthData:
1890 OS << " fixed-length sve data vector";
1891 break;
1892 case VectorKind::SveFixedLengthPredicate:
1893 OS << " fixed-length sve predicate vector";
1894 break;
1895 case VectorKind::RVVFixedLengthData:
1896 OS << " fixed-length rvv data vector";
1897 break;
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";
1903 break;
1905 OS << " " << T->getNumElements();
1908 void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
1909 auto EI = T->getExtInfo();
1910 if (EI.getNoReturn())
1911 OS << " noreturn";
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";
1923 if (T->isConst())
1924 OS << " const";
1925 if (T->isVolatile())
1926 OS << " volatile";
1927 if (T->isRestrict())
1928 OS << " restrict";
1929 if (T->getExtProtoInfo().Variadic)
1930 OS << " variadic";
1931 switch (EPI.RefQualifier) {
1932 case RQ_None:
1933 break;
1934 case RQ_LValue:
1935 OS << " &";
1936 break;
1937 case RQ_RValue:
1938 OS << " &&";
1939 break;
1942 switch (EPI.ExceptionSpec.Type) {
1943 case EST_None:
1944 break;
1945 case EST_DynamicNone:
1946 OS << " exceptionspec_dynamic_none";
1947 break;
1948 case EST_Dynamic:
1949 OS << " exceptionspec_dynamic";
1950 break;
1951 case EST_MSAny:
1952 OS << " exceptionspec_ms_any";
1953 break;
1954 case EST_NoThrow:
1955 OS << " exceptionspec_nothrow";
1956 break;
1957 case EST_BasicNoexcept:
1958 OS << " exceptionspec_basic_noexcept";
1959 break;
1960 case EST_DependentNoexcept:
1961 OS << " exceptionspec_dependent_noexcept";
1962 break;
1963 case EST_NoexceptFalse:
1964 OS << " exceptionspec_noexcept_false";
1965 break;
1966 case EST_NoexceptTrue:
1967 OS << " exceptionspec_noexcept_true";
1968 break;
1969 case EST_Unevaluated:
1970 OS << " exceptionspec_unevaluated";
1971 break;
1972 case EST_Uninstantiated:
1973 OS << " exceptionspec_uninstantiated";
1974 break;
1975 case EST_Unparsed:
1976 OS << " exceptionspec_unparsed";
1977 break;
1979 if (!EPI.ExceptionSpec.Exceptions.empty()) {
1980 AddChild([=] {
1981 OS << "Exceptions:";
1982 for (unsigned I = 0, N = EPI.ExceptionSpec.Exceptions.size(); I != N;
1983 ++I) {
1984 if (I)
1985 OS << ",";
1986 dumpType(EPI.ExceptionSpec.Exceptions[I]);
1990 if (EPI.ExceptionSpec.NoexceptExpr) {
1991 AddChild([=] {
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())
2010 OS << " divergent";
2013 void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
2014 dumpDeclRef(T->getDecl());
2015 if (!T->typeMatchesDecl())
2016 OS << " divergent";
2019 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
2020 switch (T->getUTTKind()) {
2021 #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
2022 case UnaryTransformType::Enum: \
2023 OS << " " #Trait; \
2024 break;
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())
2036 OS << " pack";
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())
2058 OS << " undeduced";
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())
2071 OS << " alias";
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) {
2099 dumpName(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())
2108 OS << " class";
2109 else
2110 OS << " struct";
2112 dumpName(D);
2113 if (D->isModulePrivate())
2114 OS << " __module_private__";
2115 if (D->isFixed())
2116 dumpType(D->getIntegerType());
2119 void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
2120 OS << ' ' << D->getKindName();
2121 dumpName(D);
2122 if (D->isModulePrivate())
2123 OS << " __module_private__";
2124 if (D->isCompleteDefinition())
2125 OS << " definition";
2128 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
2129 dumpName(D);
2130 dumpType(D->getType());
2133 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
2134 dumpName(D);
2135 dumpType(D->getType());
2137 for (const auto *Child : D->chain())
2138 dumpDeclRef(Child);
2141 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
2142 dumpName(D);
2143 dumpType(D->getType());
2144 dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
2146 StorageClass SC = D->getStorageClass();
2147 if (SC != SC_None)
2148 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
2149 if (D->isInlineSpecified())
2150 OS << " inline";
2151 if (D->isVirtualAsWritten())
2152 OS << " virtual";
2153 if (D->isModulePrivate())
2154 OS << " __module_private__";
2156 if (D->isPureVirtual())
2157 OS << " pure";
2158 if (D->isDefaulted()) {
2159 OS << " default";
2160 if (D->isDeleted())
2161 OS << "_delete";
2163 if (D->isDeletedAsWritten())
2164 OS << " delete";
2165 if (D->isTrivial())
2166 OS << " trivial";
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) {
2177 default:
2178 break;
2179 case EST_Unevaluated:
2180 OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
2181 break;
2182 case EST_Uninstantiated:
2183 OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
2184 break;
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) << "'";
2196 AddChild([=] {
2197 auto Overrides = MD->overridden_methods();
2198 OS << "Overrides: [ ";
2199 dumpOverride(*Overrides.begin());
2200 for (const auto *Override : llvm::drop_begin(Overrides)) {
2201 OS << ", ";
2202 dumpOverride(Override);
2204 OS << " ]";
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:
2231 return;
2232 case DeductionCandidate::Aggregate:
2233 OS << " aggregate ";
2234 break;
2238 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
2239 const LifetimeExtendedTemporaryDecl *D) {
2240 OS << " extended by ";
2241 dumpBareDeclRef(D->getExtendingDecl());
2242 OS << " mangling ";
2244 ColorScope Color(OS, ShowColors, ValueColor);
2245 OS << D->getManglingNumber();
2249 void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
2250 dumpName(D);
2251 dumpType(D->getType());
2252 if (D->isMutable())
2253 OS << " mutable";
2254 if (D->isModulePrivate())
2255 OS << " __module_private__";
2258 void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
2259 dumpNestedNameSpecifier(D->getQualifier());
2260 dumpName(D);
2261 if (const auto *P = dyn_cast<ParmVarDecl>(D);
2262 P && P->isExplicitObjectParameter())
2263 OS << " this";
2265 dumpType(D->getType());
2266 dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
2267 StorageClass SC = D->getStorageClass();
2268 if (SC != SC_None)
2269 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
2270 switch (D->getTLSKind()) {
2271 case VarDecl::TLS_None:
2272 break;
2273 case VarDecl::TLS_Static:
2274 OS << " tls";
2275 break;
2276 case VarDecl::TLS_Dynamic:
2277 OS << " tls_dynamic";
2278 break;
2280 if (D->isModulePrivate())
2281 OS << " __module_private__";
2282 if (D->isNRVOVariable())
2283 OS << " nrvo";
2284 if (D->isInline())
2285 OS << " inline";
2286 if (D->isConstexpr())
2287 OS << " constexpr";
2288 if (D->hasInit()) {
2289 switch (D->getInitStyle()) {
2290 case VarDecl::CInit:
2291 OS << " cinit";
2292 break;
2293 case VarDecl::CallInit:
2294 OS << " callinit";
2295 break;
2296 case VarDecl::ListInit:
2297 OS << " listinit";
2298 break;
2299 case VarDecl::ParenListInit:
2300 OS << " parenlistinit";
2303 if (D->needsDestruction(D->getASTContext()))
2304 OS << " destroyed";
2305 if (D->isParameterPack())
2306 OS << " pack";
2308 if (D->hasInit()) {
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();
2314 if (Value)
2315 AddChild("value", [=] { Visit(*Value, E->getType()); });
2320 void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
2321 dumpName(D);
2322 dumpType(D->getType());
2325 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
2326 if (D->isNothrow())
2327 OS << " nothrow";
2330 void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
2331 OS << ' ' << D->getImportedModule()->getFullModuleName();
2333 for (Decl *InitD :
2334 D->getASTContext().getModuleInitializers(D->getImportedModule()))
2335 dumpDeclRef(InitD, "initializer");
2338 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
2339 OS << ' ';
2340 switch (D->getCommentKind()) {
2341 case PCK_Unknown:
2342 llvm_unreachable("unexpected pragma comment kind");
2343 case PCK_Compiler:
2344 OS << "compiler";
2345 break;
2346 case PCK_ExeStr:
2347 OS << "exestr";
2348 break;
2349 case PCK_Lib:
2350 OS << "lib";
2351 break;
2352 case PCK_Linker:
2353 OS << "linker";
2354 break;
2355 case PCK_User:
2356 OS << "user";
2357 break;
2359 StringRef Arg = D->getArg();
2360 if (!Arg.empty())
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) {
2377 dumpName(D);
2378 dumpType(D->getType());
2379 OS << " combiner";
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 = ";
2387 break;
2388 case OMPDeclareReductionInitKind::Copy:
2389 OS << " omp_priv ()";
2390 break;
2391 case OMPDeclareReductionInitKind::Call:
2392 break;
2397 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
2398 for (const auto *C : D->clauselists()) {
2399 AddChild([=] {
2400 if (!C) {
2401 ColorScope Color(OS, ShowColors, NullColor);
2402 OS << "<<<NULL>>> OMPClause";
2403 return;
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";
2412 dumpPointer(C);
2413 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
2418 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
2419 dumpName(D);
2420 dumpType(D->getType());
2423 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
2424 dumpName(D);
2425 if (D->isInline())
2426 OS << " inline";
2427 if (D->isNested())
2428 OS << " nested";
2429 if (!D->isFirstDecl())
2430 dumpDeclRef(D->getFirstDecl(), "original");
2433 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
2434 OS << ' ';
2435 dumpBareDeclRef(D->getNominatedNamespace());
2438 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
2439 dumpName(D);
2440 dumpDeclRef(D->getAliasedNamespace());
2443 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
2444 dumpName(D);
2445 dumpType(D->getUnderlyingType());
2448 void TextNodeDumper::VisitTypeAliasTemplateDecl(
2449 const TypeAliasTemplateDecl *D) {
2450 dumpName(D);
2453 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
2454 VisitRecordDecl(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())
2465 return;
2467 AddChild([=] {
2469 ColorScope Color(OS, ShowColors, DeclKindNameColor);
2470 OS << "DefinitionData";
2472 #define FLAG(fn, name) \
2473 if (D->fn()) \
2474 OS << " " #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);
2486 FLAG(isPOD, pod);
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);
2498 AddChild([=] {
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);
2512 AddChild([=] {
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);
2530 AddChild([=] {
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);
2547 AddChild([=] {
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);
2562 AddChild([=] {
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);
2576 AddChild([=] {
2578 ColorScope Color(OS, ShowColors, DeclKindNameColor);
2579 OS << "Destructor";
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()) {
2595 AddChild([=] {
2596 if (I.isVirtual())
2597 OS << "virtual ";
2598 dumpAccessSpecifier(I.getAccessSpecifier());
2599 dumpType(I.getType());
2600 if (I.isPackExpansion())
2601 OS << "...";
2606 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
2607 dumpName(D);
2610 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
2611 dumpName(D);
2614 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
2615 dumpName(D);
2618 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
2619 dumpName(D);
2622 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2623 if (const auto *TC = D->getTypeConstraint()) {
2624 OS << " ";
2625 dumpBareDeclRef(TC->getNamedConcept());
2626 if (TC->getNamedConcept() != TC->getFoundDecl()) {
2627 OS << " (";
2628 dumpBareDeclRef(TC->getFoundDecl());
2629 OS << ")";
2631 } else if (D->wasDeclaredWithTypename())
2632 OS << " typename";
2633 else
2634 OS << " class";
2635 OS << " depth " << D->getDepth() << " index " << D->getIndex();
2636 if (D->isParameterPack())
2637 OS << " ...";
2638 dumpName(D);
2641 void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2642 const NonTypeTemplateParmDecl *D) {
2643 dumpType(D->getType());
2644 OS << " depth " << D->getDepth() << " index " << D->getIndex();
2645 if (D->isParameterPack())
2646 OS << " ...";
2647 dumpName(D);
2650 void TextNodeDumper::VisitTemplateTemplateParmDecl(
2651 const TemplateTemplateParmDecl *D) {
2652 OS << " depth " << D->getDepth() << " index " << D->getIndex();
2653 if (D->isParameterPack())
2654 OS << " ...";
2655 dumpName(D);
2658 void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
2659 OS << ' ';
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) {
2667 OS << ' ';
2668 dumpBareDeclRef(D->getEnumDecl());
2671 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2672 const UnresolvedUsingTypenameDecl *D) {
2673 OS << ' ';
2674 if (D->getQualifier())
2675 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2676 OS << D->getDeclName();
2679 void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2680 const UnresolvedUsingValueDecl *D) {
2681 OS << ' ';
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) {
2689 OS << ' ';
2690 dumpBareDeclRef(D->getTargetDecl());
2693 void TextNodeDumper::VisitConstructorUsingShadowDecl(
2694 const ConstructorUsingShadowDecl *D) {
2695 if (D->constructsVirtualBase())
2696 OS << " virtual";
2698 AddChild([=] {
2699 OS << "target ";
2700 dumpBareDeclRef(D->getTargetDecl());
2703 AddChild([=] {
2704 OS << "nominated ";
2705 dumpBareDeclRef(D->getNominatedBaseClass());
2706 OS << ' ';
2707 dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
2710 AddChild([=] {
2711 OS << "constructed ";
2712 dumpBareDeclRef(D->getConstructedBaseClass());
2713 OS << ' ';
2714 dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
2718 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
2719 switch (D->getLanguage()) {
2720 case LinkageSpecLanguageIDs::C:
2721 OS << " C";
2722 break;
2723 case LinkageSpecLanguageIDs::CXX:
2724 OS << " C++";
2725 break;
2729 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
2730 OS << ' ';
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())
2738 OS << "...";
2741 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
2742 dumpName(D);
2743 dumpType(D->getType());
2744 if (D->getSynthesize())
2745 OS << " synthesize";
2747 switch (D->getAccessControl()) {
2748 case ObjCIvarDecl::None:
2749 OS << " none";
2750 break;
2751 case ObjCIvarDecl::Private:
2752 OS << " private";
2753 break;
2754 case ObjCIvarDecl::Protected:
2755 OS << " protected";
2756 break;
2757 case ObjCIvarDecl::Public:
2758 OS << " public";
2759 break;
2760 case ObjCIvarDecl::Package:
2761 OS << " package";
2762 break;
2766 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
2767 if (D->isInstanceMethod())
2768 OS << " -";
2769 else
2770 OS << " +";
2771 dumpName(D);
2772 dumpType(D->getReturnType());
2774 if (D->isVariadic())
2775 OS << " variadic";
2778 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
2779 dumpName(D);
2780 switch (D->getVariance()) {
2781 case ObjCTypeParamVariance::Invariant:
2782 break;
2784 case ObjCTypeParamVariance::Covariant:
2785 OS << " covariant";
2786 break;
2788 case ObjCTypeParamVariance::Contravariant:
2789 OS << " contravariant";
2790 break;
2793 if (D->hasExplicitBound())
2794 OS << " bounded";
2795 dumpType(D->getUnderlyingType());
2798 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
2799 dumpName(D);
2800 dumpDeclRef(D->getClassInterface());
2801 dumpDeclRef(D->getImplementation());
2802 for (const auto *P : D->protocols())
2803 dumpDeclRef(P);
2806 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
2807 dumpName(D);
2808 dumpDeclRef(D->getClassInterface());
2809 dumpDeclRef(D->getCategoryDecl());
2812 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
2813 dumpName(D);
2815 for (const auto *Child : D->protocols())
2816 dumpDeclRef(Child);
2819 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
2820 dumpName(D);
2821 dumpDeclRef(D->getSuperClass(), "super");
2823 dumpDeclRef(D->getImplementation());
2824 for (const auto *Child : D->protocols())
2825 dumpDeclRef(Child);
2828 void TextNodeDumper::VisitObjCImplementationDecl(
2829 const ObjCImplementationDecl *D) {
2830 dumpName(D);
2831 dumpDeclRef(D->getSuperClass(), "super");
2832 dumpDeclRef(D->getClassInterface());
2835 void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2836 const ObjCCompatibleAliasDecl *D) {
2837 dumpName(D);
2838 dumpDeclRef(D->getClassInterface());
2841 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
2842 dumpName(D);
2843 dumpType(D->getType());
2845 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
2846 OS << " required";
2847 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
2848 OS << " optional";
2850 ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
2851 if (Attrs != ObjCPropertyAttribute::kind_noattr) {
2852 if (Attrs & ObjCPropertyAttribute::kind_readonly)
2853 OS << " readonly";
2854 if (Attrs & ObjCPropertyAttribute::kind_assign)
2855 OS << " assign";
2856 if (Attrs & ObjCPropertyAttribute::kind_readwrite)
2857 OS << " readwrite";
2858 if (Attrs & ObjCPropertyAttribute::kind_retain)
2859 OS << " retain";
2860 if (Attrs & ObjCPropertyAttribute::kind_copy)
2861 OS << " copy";
2862 if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
2863 OS << " nonatomic";
2864 if (Attrs & ObjCPropertyAttribute::kind_atomic)
2865 OS << " atomic";
2866 if (Attrs & ObjCPropertyAttribute::kind_weak)
2867 OS << " weak";
2868 if (Attrs & ObjCPropertyAttribute::kind_strong)
2869 OS << " strong";
2870 if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
2871 OS << " unsafe_unretained";
2872 if (Attrs & ObjCPropertyAttribute::kind_class)
2873 OS << " class";
2874 if (Attrs & ObjCPropertyAttribute::kind_direct)
2875 OS << " 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";
2887 else
2888 OS << " dynamic";
2889 dumpDeclRef(D->getPropertyDecl());
2890 dumpDeclRef(D->getPropertyIvarDecl());
2893 void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
2894 if (D->isVariadic())
2895 OS << " variadic";
2897 if (D->capturesCXXThis())
2898 OS << " captures_this";
2901 void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
2902 dumpName(D);
2905 void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
2906 VisitStmt(S);
2907 if (S->hasStoredFPFeatures())
2908 printFPOptions(S->getStoredFPFeatures());
2911 void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) {
2912 if (D->isCBuffer())
2913 OS << " cbuffer";
2914 else
2915 OS << " tbuffer";
2916 dumpName(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())
2929 OS << " <orphan>";
2930 else
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();