TextNodeDumper.cpp revision 1.1 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.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "clang/AST/TextNodeDumper.h"
14 #include "clang/AST/DeclFriend.h"
15 #include "clang/AST/DeclOpenMP.h"
16 #include "clang/AST/DeclTemplate.h"
17 #include "clang/AST/LocInfoType.h"
18
19 using namespace clang;
20
21 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
22
23 template <typename T>
24 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
25 const T *First = D->getFirstDecl();
26 if (First != D)
27 OS << " first " << First;
28 }
29
30 template <typename T>
31 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
32 const T *Prev = D->getPreviousDecl();
33 if (Prev)
34 OS << " prev " << Prev;
35 }
36
37 /// Dump the previous declaration in the redeclaration chain for a declaration,
38 /// if any.
39 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
40 switch (D->getKind()) {
41 #define DECL(DERIVED, BASE) \
42 case Decl::DERIVED: \
43 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
44 #define ABSTRACT_DECL(DECL)
45 #include "clang/AST/DeclNodes.inc"
46 }
47 llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
48 }
49
50 TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors,
51 const SourceManager *SM,
52 const PrintingPolicy &PrintPolicy,
53 const comments::CommandTraits *Traits)
54 : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors), SM(SM),
55 PrintPolicy(PrintPolicy), Traits(Traits) {}
56
57 void TextNodeDumper::Visit(const comments::Comment *C,
58 const comments::FullComment *FC) {
59 if (!C) {
60 ColorScope Color(OS, ShowColors, NullColor);
61 OS << "<<<NULL>>>";
62 return;
63 }
64
65 {
66 ColorScope Color(OS, ShowColors, CommentColor);
67 OS << C->getCommentKindName();
68 }
69 dumpPointer(C);
70 dumpSourceRange(C->getSourceRange());
71
72 ConstCommentVisitor<TextNodeDumper, void,
73 const comments::FullComment *>::visit(C, FC);
74 }
75
76 void TextNodeDumper::Visit(const Attr *A) {
77 {
78 ColorScope Color(OS, ShowColors, AttrColor);
79
80 switch (A->getKind()) {
81 #define ATTR(X) \
82 case attr::X: \
83 OS << #X; \
84 break;
85 #include "clang/Basic/AttrList.inc"
86 }
87 OS << "Attr";
88 }
89 dumpPointer(A);
90 dumpSourceRange(A->getRange());
91 if (A->isInherited())
92 OS << " Inherited";
93 if (A->isImplicit())
94 OS << " Implicit";
95
96 ConstAttrVisitor<TextNodeDumper>::Visit(A);
97 }
98
99 void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
100 const Decl *From, StringRef Label) {
101 OS << "TemplateArgument";
102 if (R.isValid())
103 dumpSourceRange(R);
104
105 if (From)
106 dumpDeclRef(From, Label);
107
108 ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
109 }
110
111 void TextNodeDumper::Visit(const Stmt *Node) {
112 if (!Node) {
113 ColorScope Color(OS, ShowColors, NullColor);
114 OS << "<<<NULL>>>";
115 return;
116 }
117 {
118 ColorScope Color(OS, ShowColors, StmtColor);
119 OS << Node->getStmtClassName();
120 }
121 dumpPointer(Node);
122 dumpSourceRange(Node->getSourceRange());
123
124 if (Node->isOMPStructuredBlock())
125 OS << " openmp_structured_block";
126
127 if (const auto *E = dyn_cast<Expr>(Node)) {
128 dumpType(E->getType());
129
130 {
131 ColorScope Color(OS, ShowColors, ValueKindColor);
132 switch (E->getValueKind()) {
133 case VK_RValue:
134 break;
135 case VK_LValue:
136 OS << " lvalue";
137 break;
138 case VK_XValue:
139 OS << " xvalue";
140 break;
141 }
142 }
143
144 {
145 ColorScope Color(OS, ShowColors, ObjectKindColor);
146 switch (E->getObjectKind()) {
147 case OK_Ordinary:
148 break;
149 case OK_BitField:
150 OS << " bitfield";
151 break;
152 case OK_ObjCProperty:
153 OS << " objcproperty";
154 break;
155 case OK_ObjCSubscript:
156 OS << " objcsubscript";
157 break;
158 case OK_VectorComponent:
159 OS << " vectorcomponent";
160 break;
161 }
162 }
163 }
164
165 ConstStmtVisitor<TextNodeDumper>::Visit(Node);
166 }
167
168 void TextNodeDumper::Visit(const Type *T) {
169 if (!T) {
170 ColorScope Color(OS, ShowColors, NullColor);
171 OS << "<<<NULL>>>";
172 return;
173 }
174 if (isa<LocInfoType>(T)) {
175 {
176 ColorScope Color(OS, ShowColors, TypeColor);
177 OS << "LocInfo Type";
178 }
179 dumpPointer(T);
180 return;
181 }
182
183 {
184 ColorScope Color(OS, ShowColors, TypeColor);
185 OS << T->getTypeClassName() << "Type";
186 }
187 dumpPointer(T);
188 OS << " ";
189 dumpBareType(QualType(T, 0), false);
190
191 QualType SingleStepDesugar =
192 T->getLocallyUnqualifiedSingleStepDesugaredType();
193 if (SingleStepDesugar != QualType(T, 0))
194 OS << " sugar";
195
196 if (T->isDependentType())
197 OS << " dependent";
198 else if (T->isInstantiationDependentType())
199 OS << " instantiation_dependent";
200
201 if (T->isVariablyModifiedType())
202 OS << " variably_modified";
203 if (T->containsUnexpandedParameterPack())
204 OS << " contains_unexpanded_pack";
205 if (T->isFromAST())
206 OS << " imported";
207
208 TypeVisitor<TextNodeDumper>::Visit(T);
209 }
210
211 void TextNodeDumper::Visit(QualType T) {
212 OS << "QualType";
213 dumpPointer(T.getAsOpaquePtr());
214 OS << " ";
215 dumpBareType(T, false);
216 OS << " " << T.split().Quals.getAsString();
217 }
218
219 void TextNodeDumper::Visit(const Decl *D) {
220 if (!D) {
221 ColorScope Color(OS, ShowColors, NullColor);
222 OS << "<<<NULL>>>";
223 return;
224 }
225
226 {
227 ColorScope Color(OS, ShowColors, DeclKindNameColor);
228 OS << D->getDeclKindName() << "Decl";
229 }
230 dumpPointer(D);
231 if (D->getLexicalDeclContext() != D->getDeclContext())
232 OS << " parent " << cast<Decl>(D->getDeclContext());
233 dumpPreviousDecl(OS, D);
234 dumpSourceRange(D->getSourceRange());
235 OS << ' ';
236 dumpLocation(D->getLocation());
237 if (D->isFromASTFile())
238 OS << " imported";
239 if (Module *M = D->getOwningModule())
240 OS << " in " << M->getFullModuleName();
241 if (auto *ND = dyn_cast<NamedDecl>(D))
242 for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
243 const_cast<NamedDecl *>(ND)))
244 AddChild([=] { OS << "also in " << M->getFullModuleName(); });
245 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
246 if (ND->isHidden())
247 OS << " hidden";
248 if (D->isImplicit())
249 OS << " implicit";
250
251 if (D->isUsed())
252 OS << " used";
253 else if (D->isThisDeclarationReferenced())
254 OS << " referenced";
255
256 if (D->isInvalidDecl())
257 OS << " invalid";
258 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
259 if (FD->isConstexprSpecified())
260 OS << " constexpr";
261 if (FD->isConsteval())
262 OS << " consteval";
263 }
264
265 if (!isa<FunctionDecl>(*D)) {
266 const auto *MD = dyn_cast<ObjCMethodDecl>(D);
267 if (!MD || !MD->isThisDeclarationADefinition()) {
268 const auto *DC = dyn_cast<DeclContext>(D);
269 if (DC && DC->hasExternalLexicalStorage()) {
270 ColorScope Color(OS, ShowColors, UndeserializedColor);
271 OS << " <undeserialized declarations>";
272 }
273 }
274 }
275
276 ConstDeclVisitor<TextNodeDumper>::Visit(D);
277 }
278
279 void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
280 OS << "CXXCtorInitializer";
281 if (Init->isAnyMemberInitializer()) {
282 OS << ' ';
283 dumpBareDeclRef(Init->getAnyMember());
284 } else if (Init->isBaseInitializer()) {
285 dumpType(QualType(Init->getBaseClass(), 0));
286 } else if (Init->isDelegatingInitializer()) {
287 dumpType(Init->getTypeSourceInfo()->getType());
288 } else {
289 llvm_unreachable("Unknown initializer type");
290 }
291 }
292
293 void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
294 OS << "capture";
295 if (C.isByRef())
296 OS << " byref";
297 if (C.isNested())
298 OS << " nested";
299 if (C.getVariable()) {
300 OS << ' ';
301 dumpBareDeclRef(C.getVariable());
302 }
303 }
304
305 void TextNodeDumper::Visit(const OMPClause *C) {
306 if (!C) {
307 ColorScope Color(OS, ShowColors, NullColor);
308 OS << "<<<NULL>>> OMPClause";
309 return;
310 }
311 {
312 ColorScope Color(OS, ShowColors, AttrColor);
313 StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
314 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
315 << ClauseName.drop_front() << "Clause";
316 }
317 dumpPointer(C);
318 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
319 if (C->isImplicit())
320 OS << " <implicit>";
321 }
322
323 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
324 const TypeSourceInfo *TSI = A.getTypeSourceInfo();
325 if (TSI) {
326 OS << "case ";
327 dumpType(TSI->getType());
328 } else {
329 OS << "default";
330 }
331
332 if (A.isSelected())
333 OS << " selected";
334 }
335
336 void TextNodeDumper::dumpPointer(const void *Ptr) {
337 ColorScope Color(OS, ShowColors, AddressColor);
338 OS << ' ' << Ptr;
339 }
340
341 void TextNodeDumper::dumpLocation(SourceLocation Loc) {
342 if (!SM)
343 return;
344
345 ColorScope Color(OS, ShowColors, LocationColor);
346 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
347
348 // The general format we print out is filename:line:col, but we drop pieces
349 // that haven't changed since the last loc printed.
350 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
351
352 if (PLoc.isInvalid()) {
353 OS << "<invalid sloc>";
354 return;
355 }
356
357 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
358 OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
359 << PLoc.getColumn();
360 LastLocFilename = PLoc.getFilename();
361 LastLocLine = PLoc.getLine();
362 } else if (PLoc.getLine() != LastLocLine) {
363 OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
364 LastLocLine = PLoc.getLine();
365 } else {
366 OS << "col" << ':' << PLoc.getColumn();
367 }
368 }
369
370 void TextNodeDumper::dumpSourceRange(SourceRange R) {
371 // Can't translate locations if a SourceManager isn't available.
372 if (!SM)
373 return;
374
375 OS << " <";
376 dumpLocation(R.getBegin());
377 if (R.getBegin() != R.getEnd()) {
378 OS << ", ";
379 dumpLocation(R.getEnd());
380 }
381 OS << ">";
382
383 // <t2.c:123:421[blah], t2.c:412:321>
384 }
385
386 void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
387 ColorScope Color(OS, ShowColors, TypeColor);
388
389 SplitQualType T_split = T.split();
390 OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'";
391
392 if (Desugar && !T.isNull()) {
393 // If the type is sugared, also dump a (shallow) desugared type.
394 SplitQualType D_split = T.getSplitDesugaredType();
395 if (T_split != D_split)
396 OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
397 }
398 }
399
400 void TextNodeDumper::dumpType(QualType T) {
401 OS << ' ';
402 dumpBareType(T);
403 }
404
405 void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
406 if (!D) {
407 ColorScope Color(OS, ShowColors, NullColor);
408 OS << "<<<NULL>>>";
409 return;
410 }
411
412 {
413 ColorScope Color(OS, ShowColors, DeclKindNameColor);
414 OS << D->getDeclKindName();
415 }
416 dumpPointer(D);
417
418 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
419 ColorScope Color(OS, ShowColors, DeclNameColor);
420 OS << " '" << ND->getDeclName() << '\'';
421 }
422
423 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
424 dumpType(VD->getType());
425 }
426
427 void TextNodeDumper::dumpName(const NamedDecl *ND) {
428 if (ND->getDeclName()) {
429 ColorScope Color(OS, ShowColors, DeclNameColor);
430 OS << ' ' << ND->getNameAsString();
431 }
432 }
433
434 void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
435 switch (AS) {
436 case AS_none:
437 break;
438 case AS_public:
439 OS << "public";
440 break;
441 case AS_protected:
442 OS << "protected";
443 break;
444 case AS_private:
445 OS << "private";
446 break;
447 }
448 }
449
450 void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
451 if (!D)
452 return;
453
454 AddChild([=] {
455 if (!Label.empty())
456 OS << Label << ' ';
457 dumpBareDeclRef(D);
458 });
459 }
460
461 const char *TextNodeDumper::getCommandName(unsigned CommandID) {
462 if (Traits)
463 return Traits->getCommandInfo(CommandID)->Name;
464 const comments::CommandInfo *Info =
465 comments::CommandTraits::getBuiltinCommandInfo(CommandID);
466 if (Info)
467 return Info->Name;
468 return "<not a builtin command>";
469 }
470
471 void TextNodeDumper::visitTextComment(const comments::TextComment *C,
472 const comments::FullComment *) {
473 OS << " Text=\"" << C->getText() << "\"";
474 }
475
476 void TextNodeDumper::visitInlineCommandComment(
477 const comments::InlineCommandComment *C, const comments::FullComment *) {
478 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
479 switch (C->getRenderKind()) {
480 case comments::InlineCommandComment::RenderNormal:
481 OS << " RenderNormal";
482 break;
483 case comments::InlineCommandComment::RenderBold:
484 OS << " RenderBold";
485 break;
486 case comments::InlineCommandComment::RenderMonospaced:
487 OS << " RenderMonospaced";
488 break;
489 case comments::InlineCommandComment::RenderEmphasized:
490 OS << " RenderEmphasized";
491 break;
492 }
493
494 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
495 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
496 }
497
498 void TextNodeDumper::visitHTMLStartTagComment(
499 const comments::HTMLStartTagComment *C, const comments::FullComment *) {
500 OS << " Name=\"" << C->getTagName() << "\"";
501 if (C->getNumAttrs() != 0) {
502 OS << " Attrs: ";
503 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
504 const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
505 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
506 }
507 }
508 if (C->isSelfClosing())
509 OS << " SelfClosing";
510 }
511
512 void TextNodeDumper::visitHTMLEndTagComment(
513 const comments::HTMLEndTagComment *C, const comments::FullComment *) {
514 OS << " Name=\"" << C->getTagName() << "\"";
515 }
516
517 void TextNodeDumper::visitBlockCommandComment(
518 const comments::BlockCommandComment *C, const comments::FullComment *) {
519 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
520 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
521 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
522 }
523
524 void TextNodeDumper::visitParamCommandComment(
525 const comments::ParamCommandComment *C, const comments::FullComment *FC) {
526 OS << " "
527 << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
528
529 if (C->isDirectionExplicit())
530 OS << " explicitly";
531 else
532 OS << " implicitly";
533
534 if (C->hasParamName()) {
535 if (C->isParamIndexValid())
536 OS << " Param=\"" << C->getParamName(FC) << "\"";
537 else
538 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
539 }
540
541 if (C->isParamIndexValid() && !C->isVarArgParam())
542 OS << " ParamIndex=" << C->getParamIndex();
543 }
544
545 void TextNodeDumper::visitTParamCommandComment(
546 const comments::TParamCommandComment *C, const comments::FullComment *FC) {
547 if (C->hasParamName()) {
548 if (C->isPositionValid())
549 OS << " Param=\"" << C->getParamName(FC) << "\"";
550 else
551 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
552 }
553
554 if (C->isPositionValid()) {
555 OS << " Position=<";
556 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
557 OS << C->getIndex(i);
558 if (i != e - 1)
559 OS << ", ";
560 }
561 OS << ">";
562 }
563 }
564
565 void TextNodeDumper::visitVerbatimBlockComment(
566 const comments::VerbatimBlockComment *C, const comments::FullComment *) {
567 OS << " Name=\"" << getCommandName(C->getCommandID())
568 << "\""
569 " CloseName=\""
570 << C->getCloseName() << "\"";
571 }
572
573 void TextNodeDumper::visitVerbatimBlockLineComment(
574 const comments::VerbatimBlockLineComment *C,
575 const comments::FullComment *) {
576 OS << " Text=\"" << C->getText() << "\"";
577 }
578
579 void TextNodeDumper::visitVerbatimLineComment(
580 const comments::VerbatimLineComment *C, const comments::FullComment *) {
581 OS << " Text=\"" << C->getText() << "\"";
582 }
583
584 void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
585 OS << " null";
586 }
587
588 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
589 OS << " type";
590 dumpType(TA.getAsType());
591 }
592
593 void TextNodeDumper::VisitDeclarationTemplateArgument(
594 const TemplateArgument &TA) {
595 OS << " decl";
596 dumpDeclRef(TA.getAsDecl());
597 }
598
599 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
600 OS << " nullptr";
601 }
602
603 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
604 OS << " integral " << TA.getAsIntegral();
605 }
606
607 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
608 OS << " template ";
609 TA.getAsTemplate().dump(OS);
610 }
611
612 void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
613 const TemplateArgument &TA) {
614 OS << " template expansion ";
615 TA.getAsTemplateOrTemplatePattern().dump(OS);
616 }
617
618 void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
619 OS << " expr";
620 }
621
622 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
623 OS << " pack";
624 }
625
626 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
627 if (Node->path_empty())
628 return;
629
630 OS << " (";
631 bool First = true;
632 for (CastExpr::path_const_iterator I = Node->path_begin(),
633 E = Node->path_end();
634 I != E; ++I) {
635 const CXXBaseSpecifier *Base = *I;
636 if (!First)
637 OS << " -> ";
638
639 const auto *RD =
640 cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
641
642 if (Base->isVirtual())
643 OS << "virtual ";
644 OS << RD->getName();
645 First = false;
646 }
647
648 OS << ')';
649 }
650
651 void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
652 if (Node->hasInitStorage())
653 OS << " has_init";
654 if (Node->hasVarStorage())
655 OS << " has_var";
656 if (Node->hasElseStorage())
657 OS << " has_else";
658 }
659
660 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
661 if (Node->hasInitStorage())
662 OS << " has_init";
663 if (Node->hasVarStorage())
664 OS << " has_var";
665 }
666
667 void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
668 if (Node->hasVarStorage())
669 OS << " has_var";
670 }
671
672 void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
673 OS << " '" << Node->getName() << "'";
674 }
675
676 void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
677 OS << " '" << Node->getLabel()->getName() << "'";
678 dumpPointer(Node->getLabel());
679 }
680
681 void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
682 if (Node->caseStmtIsGNURange())
683 OS << " gnu_range";
684 }
685
686 void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
687 if (Node->getResultAPValueKind() != APValue::None) {
688 ColorScope Color(OS, ShowColors, ValueColor);
689 OS << " ";
690 Node->getAPValueResult().dump(OS);
691 }
692 }
693
694 void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
695 if (Node->usesADL())
696 OS << " adl";
697 }
698
699 void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
700 OS << " <";
701 {
702 ColorScope Color(OS, ShowColors, CastColor);
703 OS << Node->getCastKindName();
704 }
705 dumpBasePath(OS, Node);
706 OS << ">";
707 }
708
709 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
710 VisitCastExpr(Node);
711 if (Node->isPartOfExplicitCast())
712 OS << " part_of_explicit_cast";
713 }
714
715 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
716 OS << " ";
717 dumpBareDeclRef(Node->getDecl());
718 if (Node->getDecl() != Node->getFoundDecl()) {
719 OS << " (";
720 dumpBareDeclRef(Node->getFoundDecl());
721 OS << ")";
722 }
723 switch (Node->isNonOdrUse()) {
724 case NOUR_None: break;
725 case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
726 case NOUR_Constant: OS << " non_odr_use_constant"; break;
727 case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
728 }
729 }
730
731 void TextNodeDumper::VisitUnresolvedLookupExpr(
732 const UnresolvedLookupExpr *Node) {
733 OS << " (";
734 if (!Node->requiresADL())
735 OS << "no ";
736 OS << "ADL) = '" << Node->getName() << '\'';
737
738 UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
739 E = Node->decls_end();
740 if (I == E)
741 OS << " empty";
742 for (; I != E; ++I)
743 dumpPointer(*I);
744 }
745
746 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
747 {
748 ColorScope Color(OS, ShowColors, DeclKindNameColor);
749 OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
750 }
751 OS << "='" << *Node->getDecl() << "'";
752 dumpPointer(Node->getDecl());
753 if (Node->isFreeIvar())
754 OS << " isFreeIvar";
755 }
756
757 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
758 OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
759 }
760
761 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
762 ColorScope Color(OS, ShowColors, ValueColor);
763 OS << " " << Node->getValue();
764 }
765
766 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
767 bool isSigned = Node->getType()->isSignedIntegerType();
768 ColorScope Color(OS, ShowColors, ValueColor);
769 OS << " " << Node->getValue().toString(10, isSigned);
770 }
771
772 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
773 ColorScope Color(OS, ShowColors, ValueColor);
774 OS << " " << Node->getValueAsString(/*Radix=*/10);
775 }
776
777 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
778 ColorScope Color(OS, ShowColors, ValueColor);
779 OS << " " << Node->getValueAsApproximateDouble();
780 }
781
782 void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
783 ColorScope Color(OS, ShowColors, ValueColor);
784 OS << " ";
785 Str->outputString(OS);
786 }
787
788 void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
789 if (auto *Field = ILE->getInitializedFieldInUnion()) {
790 OS << " field ";
791 dumpBareDeclRef(Field);
792 }
793 }
794
795 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
796 if (E->isResultDependent())
797 OS << " result_dependent";
798 }
799
800 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
801 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
802 << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
803 if (!Node->canOverflow())
804 OS << " cannot overflow";
805 }
806
807 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
808 const UnaryExprOrTypeTraitExpr *Node) {
809 switch (Node->getKind()) {
810 case UETT_SizeOf:
811 OS << " sizeof";
812 break;
813 case UETT_AlignOf:
814 OS << " alignof";
815 break;
816 case UETT_VecStep:
817 OS << " vec_step";
818 break;
819 case UETT_OpenMPRequiredSimdAlign:
820 OS << " __builtin_omp_required_simd_align";
821 break;
822 case UETT_PreferredAlignOf:
823 OS << " __alignof";
824 break;
825 }
826 if (Node->isArgumentType())
827 dumpType(Node->getArgumentType());
828 }
829
830 void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
831 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
832 dumpPointer(Node->getMemberDecl());
833 switch (Node->isNonOdrUse()) {
834 case NOUR_None: break;
835 case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
836 case NOUR_Constant: OS << " non_odr_use_constant"; break;
837 case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
838 }
839 }
840
841 void TextNodeDumper::VisitExtVectorElementExpr(
842 const ExtVectorElementExpr *Node) {
843 OS << " " << Node->getAccessor().getNameStart();
844 }
845
846 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
847 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
848 }
849
850 void TextNodeDumper::VisitCompoundAssignOperator(
851 const CompoundAssignOperator *Node) {
852 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
853 << "' ComputeLHSTy=";
854 dumpBareType(Node->getComputationLHSType());
855 OS << " ComputeResultTy=";
856 dumpBareType(Node->getComputationResultType());
857 }
858
859 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
860 OS << " " << Node->getLabel()->getName();
861 dumpPointer(Node->getLabel());
862 }
863
864 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
865 OS << " " << Node->getCastName() << "<"
866 << Node->getTypeAsWritten().getAsString() << ">"
867 << " <" << Node->getCastKindName();
868 dumpBasePath(OS, Node);
869 OS << ">";
870 }
871
872 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
873 OS << " " << (Node->getValue() ? "true" : "false");
874 }
875
876 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
877 if (Node->isImplicit())
878 OS << " implicit";
879 OS << " this";
880 }
881
882 void TextNodeDumper::VisitCXXFunctionalCastExpr(
883 const CXXFunctionalCastExpr *Node) {
884 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
885 << Node->getCastKindName() << ">";
886 }
887
888 void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
889 const CXXUnresolvedConstructExpr *Node) {
890 dumpType(Node->getTypeAsWritten());
891 if (Node->isListInitialization())
892 OS << " list";
893 }
894
895 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
896 CXXConstructorDecl *Ctor = Node->getConstructor();
897 dumpType(Ctor->getType());
898 if (Node->isElidable())
899 OS << " elidable";
900 if (Node->isListInitialization())
901 OS << " list";
902 if (Node->isStdInitListInitialization())
903 OS << " std::initializer_list";
904 if (Node->requiresZeroInitialization())
905 OS << " zeroing";
906 }
907
908 void TextNodeDumper::VisitCXXBindTemporaryExpr(
909 const CXXBindTemporaryExpr *Node) {
910 OS << " (CXXTemporary";
911 dumpPointer(Node);
912 OS << ")";
913 }
914
915 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
916 if (Node->isGlobalNew())
917 OS << " global";
918 if (Node->isArray())
919 OS << " array";
920 if (Node->getOperatorNew()) {
921 OS << ' ';
922 dumpBareDeclRef(Node->getOperatorNew());
923 }
924 // We could dump the deallocation function used in case of error, but it's
925 // usually not that interesting.
926 }
927
928 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
929 if (Node->isGlobalDelete())
930 OS << " global";
931 if (Node->isArrayForm())
932 OS << " array";
933 if (Node->getOperatorDelete()) {
934 OS << ' ';
935 dumpBareDeclRef(Node->getOperatorDelete());
936 }
937 }
938
939 void TextNodeDumper::VisitMaterializeTemporaryExpr(
940 const MaterializeTemporaryExpr *Node) {
941 if (const ValueDecl *VD = Node->getExtendingDecl()) {
942 OS << " extended by ";
943 dumpBareDeclRef(VD);
944 }
945 }
946
947 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
948 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
949 dumpDeclRef(Node->getObject(i), "cleanup");
950 }
951
952 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
953 dumpPointer(Node->getPack());
954 dumpName(Node->getPack());
955 }
956
957 void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
958 const CXXDependentScopeMemberExpr *Node) {
959 OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
960 }
961
962 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
963 OS << " selector=";
964 Node->getSelector().print(OS);
965 switch (Node->getReceiverKind()) {
966 case ObjCMessageExpr::Instance:
967 break;
968
969 case ObjCMessageExpr::Class:
970 OS << " class=";
971 dumpBareType(Node->getClassReceiver());
972 break;
973
974 case ObjCMessageExpr::SuperInstance:
975 OS << " super (instance)";
976 break;
977
978 case ObjCMessageExpr::SuperClass:
979 OS << " super (class)";
980 break;
981 }
982 }
983
984 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
985 if (auto *BoxingMethod = Node->getBoxingMethod()) {
986 OS << " selector=";
987 BoxingMethod->getSelector().print(OS);
988 }
989 }
990
991 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
992 if (!Node->getCatchParamDecl())
993 OS << " catch all";
994 }
995
996 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
997 dumpType(Node->getEncodedType());
998 }
999
1000 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1001 OS << " ";
1002 Node->getSelector().print(OS);
1003 }
1004
1005 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
1006 OS << ' ' << *Node->getProtocol();
1007 }
1008
1009 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
1010 if (Node->isImplicitProperty()) {
1011 OS << " Kind=MethodRef Getter=\"";
1012 if (Node->getImplicitPropertyGetter())
1013 Node->getImplicitPropertyGetter()->getSelector().print(OS);
1014 else
1015 OS << "(null)";
1016
1017 OS << "\" Setter=\"";
1018 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
1019 Setter->getSelector().print(OS);
1020 else
1021 OS << "(null)";
1022 OS << "\"";
1023 } else {
1024 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
1025 << '"';
1026 }
1027
1028 if (Node->isSuperReceiver())
1029 OS << " super";
1030
1031 OS << " Messaging=";
1032 if (Node->isMessagingGetter() && Node->isMessagingSetter())
1033 OS << "Getter&Setter";
1034 else if (Node->isMessagingGetter())
1035 OS << "Getter";
1036 else if (Node->isMessagingSetter())
1037 OS << "Setter";
1038 }
1039
1040 void TextNodeDumper::VisitObjCSubscriptRefExpr(
1041 const ObjCSubscriptRefExpr *Node) {
1042 if (Node->isArraySubscriptRefExpr())
1043 OS << " Kind=ArraySubscript GetterForArray=\"";
1044 else
1045 OS << " Kind=DictionarySubscript GetterForDictionary=\"";
1046 if (Node->getAtIndexMethodDecl())
1047 Node->getAtIndexMethodDecl()->getSelector().print(OS);
1048 else
1049 OS << "(null)";
1050
1051 if (Node->isArraySubscriptRefExpr())
1052 OS << "\" SetterForArray=\"";
1053 else
1054 OS << "\" SetterForDictionary=\"";
1055 if (Node->setAtIndexMethodDecl())
1056 Node->setAtIndexMethodDecl()->getSelector().print(OS);
1057 else
1058 OS << "(null)";
1059 }
1060
1061 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
1062 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
1063 }
1064
1065 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
1066 if (T->isSpelledAsLValue())
1067 OS << " written as lvalue reference";
1068 }
1069
1070 void TextNodeDumper::VisitArrayType(const ArrayType *T) {
1071 switch (T->getSizeModifier()) {
1072 case ArrayType::Normal:
1073 break;
1074 case ArrayType::Static:
1075 OS << " static";
1076 break;
1077 case ArrayType::Star:
1078 OS << " *";
1079 break;
1080 }
1081 OS << " " << T->getIndexTypeQualifiers().getAsString();
1082 }
1083
1084 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
1085 OS << " " << T->getSize();
1086 VisitArrayType(T);
1087 }
1088
1089 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
1090 OS << " ";
1091 dumpSourceRange(T->getBracketsRange());
1092 VisitArrayType(T);
1093 }
1094
1095 void TextNodeDumper::VisitDependentSizedArrayType(
1096 const DependentSizedArrayType *T) {
1097 VisitArrayType(T);
1098 OS << " ";
1099 dumpSourceRange(T->getBracketsRange());
1100 }
1101
1102 void TextNodeDumper::VisitDependentSizedExtVectorType(
1103 const DependentSizedExtVectorType *T) {
1104 OS << " ";
1105 dumpLocation(T->getAttributeLoc());
1106 }
1107
1108 void TextNodeDumper::VisitVectorType(const VectorType *T) {
1109 switch (T->getVectorKind()) {
1110 case VectorType::GenericVector:
1111 break;
1112 case VectorType::AltiVecVector:
1113 OS << " altivec";
1114 break;
1115 case VectorType::AltiVecPixel:
1116 OS << " altivec pixel";
1117 break;
1118 case VectorType::AltiVecBool:
1119 OS << " altivec bool";
1120 break;
1121 case VectorType::NeonVector:
1122 OS << " neon";
1123 break;
1124 case VectorType::NeonPolyVector:
1125 OS << " neon poly";
1126 break;
1127 }
1128 OS << " " << T->getNumElements();
1129 }
1130
1131 void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
1132 auto EI = T->getExtInfo();
1133 if (EI.getNoReturn())
1134 OS << " noreturn";
1135 if (EI.getProducesResult())
1136 OS << " produces_result";
1137 if (EI.getHasRegParm())
1138 OS << " regparm " << EI.getRegParm();
1139 OS << " " << FunctionType::getNameForCallConv(EI.getCC());
1140 }
1141
1142 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
1143 auto EPI = T->getExtProtoInfo();
1144 if (EPI.HasTrailingReturn)
1145 OS << " trailing_return";
1146 if (T->isConst())
1147 OS << " const";
1148 if (T->isVolatile())
1149 OS << " volatile";
1150 if (T->isRestrict())
1151 OS << " restrict";
1152 if (T->getExtProtoInfo().Variadic)
1153 OS << " variadic";
1154 switch (EPI.RefQualifier) {
1155 case RQ_None:
1156 break;
1157 case RQ_LValue:
1158 OS << " &";
1159 break;
1160 case RQ_RValue:
1161 OS << " &&";
1162 break;
1163 }
1164 // FIXME: Exception specification.
1165 // FIXME: Consumed parameters.
1166 VisitFunctionType(T);
1167 }
1168
1169 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1170 dumpDeclRef(T->getDecl());
1171 }
1172
1173 void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
1174 dumpDeclRef(T->getDecl());
1175 }
1176
1177 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
1178 switch (T->getUTTKind()) {
1179 case UnaryTransformType::EnumUnderlyingType:
1180 OS << " underlying_type";
1181 break;
1182 }
1183 }
1184
1185 void TextNodeDumper::VisitTagType(const TagType *T) {
1186 dumpDeclRef(T->getDecl());
1187 }
1188
1189 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1190 OS << " depth " << T->getDepth() << " index " << T->getIndex();
1191 if (T->isParameterPack())
1192 OS << " pack";
1193 dumpDeclRef(T->getDecl());
1194 }
1195
1196 void TextNodeDumper::VisitAutoType(const AutoType *T) {
1197 if (T->isDecltypeAuto())
1198 OS << " decltype(auto)";
1199 if (!T->isDeduced())
1200 OS << " undeduced";
1201 }
1202
1203 void TextNodeDumper::VisitTemplateSpecializationType(
1204 const TemplateSpecializationType *T) {
1205 if (T->isTypeAlias())
1206 OS << " alias";
1207 OS << " ";
1208 T->getTemplateName().dump(OS);
1209 }
1210
1211 void TextNodeDumper::VisitInjectedClassNameType(
1212 const InjectedClassNameType *T) {
1213 dumpDeclRef(T->getDecl());
1214 }
1215
1216 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1217 dumpDeclRef(T->getDecl());
1218 }
1219
1220 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
1221 if (auto N = T->getNumExpansions())
1222 OS << " expansions " << *N;
1223 }
1224
1225 void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
1226
1227 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
1228 dumpName(D);
1229 dumpType(D->getUnderlyingType());
1230 if (D->isModulePrivate())
1231 OS << " __module_private__";
1232 }
1233
1234 void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
1235 if (D->isScoped()) {
1236 if (D->isScopedUsingClassTag())
1237 OS << " class";
1238 else
1239 OS << " struct";
1240 }
1241 dumpName(D);
1242 if (D->isModulePrivate())
1243 OS << " __module_private__";
1244 if (D->isFixed())
1245 dumpType(D->getIntegerType());
1246 }
1247
1248 void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
1249 OS << ' ' << D->getKindName();
1250 dumpName(D);
1251 if (D->isModulePrivate())
1252 OS << " __module_private__";
1253 if (D->isCompleteDefinition())
1254 OS << " definition";
1255 }
1256
1257 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
1258 dumpName(D);
1259 dumpType(D->getType());
1260 }
1261
1262 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
1263 dumpName(D);
1264 dumpType(D->getType());
1265
1266 for (const auto *Child : D->chain())
1267 dumpDeclRef(Child);
1268 }
1269
1270 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
1271 dumpName(D);
1272 dumpType(D->getType());
1273
1274 StorageClass SC = D->getStorageClass();
1275 if (SC != SC_None)
1276 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1277 if (D->isInlineSpecified())
1278 OS << " inline";
1279 if (D->isVirtualAsWritten())
1280 OS << " virtual";
1281 if (D->isModulePrivate())
1282 OS << " __module_private__";
1283
1284 if (D->isPure())
1285 OS << " pure";
1286 if (D->isDefaulted()) {
1287 OS << " default";
1288 if (D->isDeleted())
1289 OS << "_delete";
1290 }
1291 if (D->isDeletedAsWritten())
1292 OS << " delete";
1293 if (D->isTrivial())
1294 OS << " trivial";
1295
1296 if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
1297 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
1298 switch (EPI.ExceptionSpec.Type) {
1299 default:
1300 break;
1301 case EST_Unevaluated:
1302 OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
1303 break;
1304 case EST_Uninstantiated:
1305 OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
1306 break;
1307 }
1308 }
1309
1310 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
1311 if (MD->size_overridden_methods() != 0) {
1312 auto dumpOverride = [=](const CXXMethodDecl *D) {
1313 SplitQualType T_split = D->getType().split();
1314 OS << D << " " << D->getParent()->getName()
1315 << "::" << D->getNameAsString() << " '"
1316 << QualType::getAsString(T_split, PrintPolicy) << "'";
1317 };
1318
1319 AddChild([=] {
1320 auto Overrides = MD->overridden_methods();
1321 OS << "Overrides: [ ";
1322 dumpOverride(*Overrides.begin());
1323 for (const auto *Override :
1324 llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
1325 OS << ", ";
1326 dumpOverride(Override);
1327 }
1328 OS << " ]";
1329 });
1330 }
1331 }
1332
1333 // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
1334 // the Params are set later, it is possible for a dump during debugging to
1335 // encounter a FunctionDecl that has been created but hasn't been assigned
1336 // ParmVarDecls yet.
1337 if (!D->param_empty() && !D->param_begin())
1338 OS << " <<<NULL params x " << D->getNumParams() << ">>>";
1339 }
1340
1341 void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
1342 dumpName(D);
1343 dumpType(D->getType());
1344 if (D->isMutable())
1345 OS << " mutable";
1346 if (D->isModulePrivate())
1347 OS << " __module_private__";
1348 }
1349
1350 void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
1351 dumpName(D);
1352 dumpType(D->getType());
1353 StorageClass SC = D->getStorageClass();
1354 if (SC != SC_None)
1355 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1356 switch (D->getTLSKind()) {
1357 case VarDecl::TLS_None:
1358 break;
1359 case VarDecl::TLS_Static:
1360 OS << " tls";
1361 break;
1362 case VarDecl::TLS_Dynamic:
1363 OS << " tls_dynamic";
1364 break;
1365 }
1366 if (D->isModulePrivate())
1367 OS << " __module_private__";
1368 if (D->isNRVOVariable())
1369 OS << " nrvo";
1370 if (D->isInline())
1371 OS << " inline";
1372 if (D->isConstexpr())
1373 OS << " constexpr";
1374 if (D->hasInit()) {
1375 switch (D->getInitStyle()) {
1376 case VarDecl::CInit:
1377 OS << " cinit";
1378 break;
1379 case VarDecl::CallInit:
1380 OS << " callinit";
1381 break;
1382 case VarDecl::ListInit:
1383 OS << " listinit";
1384 break;
1385 }
1386 }
1387 if (D->needsDestruction(D->getASTContext()))
1388 OS << " destroyed";
1389 if (D->isParameterPack())
1390 OS << " pack";
1391 }
1392
1393 void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
1394 dumpName(D);
1395 dumpType(D->getType());
1396 }
1397
1398 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
1399 if (D->isNothrow())
1400 OS << " nothrow";
1401 }
1402
1403 void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
1404 OS << ' ' << D->getImportedModule()->getFullModuleName();
1405
1406 for (Decl *InitD :
1407 D->getASTContext().getModuleInitializers(D->getImportedModule()))
1408 dumpDeclRef(InitD, "initializer");
1409 }
1410
1411 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
1412 OS << ' ';
1413 switch (D->getCommentKind()) {
1414 case PCK_Unknown:
1415 llvm_unreachable("unexpected pragma comment kind");
1416 case PCK_Compiler:
1417 OS << "compiler";
1418 break;
1419 case PCK_ExeStr:
1420 OS << "exestr";
1421 break;
1422 case PCK_Lib:
1423 OS << "lib";
1424 break;
1425 case PCK_Linker:
1426 OS << "linker";
1427 break;
1428 case PCK_User:
1429 OS << "user";
1430 break;
1431 }
1432 StringRef Arg = D->getArg();
1433 if (!Arg.empty())
1434 OS << " \"" << Arg << "\"";
1435 }
1436
1437 void TextNodeDumper::VisitPragmaDetectMismatchDecl(
1438 const PragmaDetectMismatchDecl *D) {
1439 OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
1440 }
1441
1442 void TextNodeDumper::VisitOMPExecutableDirective(
1443 const OMPExecutableDirective *D) {
1444 if (D->isStandaloneDirective())
1445 OS << " openmp_standalone_directive";
1446 }
1447
1448 void TextNodeDumper::VisitOMPDeclareReductionDecl(
1449 const OMPDeclareReductionDecl *D) {
1450 dumpName(D);
1451 dumpType(D->getType());
1452 OS << " combiner";
1453 dumpPointer(D->getCombiner());
1454 if (const auto *Initializer = D->getInitializer()) {
1455 OS << " initializer";
1456 dumpPointer(Initializer);
1457 switch (D->getInitializerKind()) {
1458 case OMPDeclareReductionDecl::DirectInit:
1459 OS << " omp_priv = ";
1460 break;
1461 case OMPDeclareReductionDecl::CopyInit:
1462 OS << " omp_priv ()";
1463 break;
1464 case OMPDeclareReductionDecl::CallInit:
1465 break;
1466 }
1467 }
1468 }
1469
1470 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
1471 for (const auto *C : D->clauselists()) {
1472 AddChild([=] {
1473 if (!C) {
1474 ColorScope Color(OS, ShowColors, NullColor);
1475 OS << "<<<NULL>>> OMPClause";
1476 return;
1477 }
1478 {
1479 ColorScope Color(OS, ShowColors, AttrColor);
1480 StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
1481 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
1482 << ClauseName.drop_front() << "Clause";
1483 }
1484 dumpPointer(C);
1485 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
1486 });
1487 }
1488 }
1489
1490 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
1491 dumpName(D);
1492 dumpType(D->getType());
1493 }
1494
1495 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
1496 dumpName(D);
1497 if (D->isInline())
1498 OS << " inline";
1499 if (!D->isOriginalNamespace())
1500 dumpDeclRef(D->getOriginalNamespace(), "original");
1501 }
1502
1503 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
1504 OS << ' ';
1505 dumpBareDeclRef(D->getNominatedNamespace());
1506 }
1507
1508 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
1509 dumpName(D);
1510 dumpDeclRef(D->getAliasedNamespace());
1511 }
1512
1513 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
1514 dumpName(D);
1515 dumpType(D->getUnderlyingType());
1516 }
1517
1518 void TextNodeDumper::VisitTypeAliasTemplateDecl(
1519 const TypeAliasTemplateDecl *D) {
1520 dumpName(D);
1521 }
1522
1523 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
1524 VisitRecordDecl(D);
1525 if (!D->isCompleteDefinition())
1526 return;
1527
1528 AddChild([=] {
1529 {
1530 ColorScope Color(OS, ShowColors, DeclKindNameColor);
1531 OS << "DefinitionData";
1532 }
1533 #define FLAG(fn, name) \
1534 if (D->fn()) \
1535 OS << " " #name;
1536 FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
1537
1538 FLAG(isGenericLambda, generic);
1539 FLAG(isLambda, lambda);
1540
1541 FLAG(isAnonymousStructOrUnion, is_anonymous);
1542 FLAG(canPassInRegisters, pass_in_registers);
1543 FLAG(isEmpty, empty);
1544 FLAG(isAggregate, aggregate);
1545 FLAG(isStandardLayout, standard_layout);
1546 FLAG(isTriviallyCopyable, trivially_copyable);
1547 FLAG(isPOD, pod);
1548 FLAG(isTrivial, trivial);
1549 FLAG(isPolymorphic, polymorphic);
1550 FLAG(isAbstract, abstract);
1551 FLAG(isLiteral, literal);
1552
1553 FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
1554 FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
1555 FLAG(hasMutableFields, has_mutable_fields);
1556 FLAG(hasVariantMembers, has_variant_members);
1557 FLAG(allowConstDefaultInit, can_const_default_init);
1558
1559 AddChild([=] {
1560 {
1561 ColorScope Color(OS, ShowColors, DeclKindNameColor);
1562 OS << "DefaultConstructor";
1563 }
1564 FLAG(hasDefaultConstructor, exists);
1565 FLAG(hasTrivialDefaultConstructor, trivial);
1566 FLAG(hasNonTrivialDefaultConstructor, non_trivial);
1567 FLAG(hasUserProvidedDefaultConstructor, user_provided);
1568 FLAG(hasConstexprDefaultConstructor, constexpr);
1569 FLAG(needsImplicitDefaultConstructor, needs_implicit);
1570 FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
1571 });
1572
1573 AddChild([=] {
1574 {
1575 ColorScope Color(OS, ShowColors, DeclKindNameColor);
1576 OS << "CopyConstructor";
1577 }
1578 FLAG(hasSimpleCopyConstructor, simple);
1579 FLAG(hasTrivialCopyConstructor, trivial);
1580 FLAG(hasNonTrivialCopyConstructor, non_trivial);
1581 FLAG(hasUserDeclaredCopyConstructor, user_declared);
1582 FLAG(hasCopyConstructorWithConstParam, has_const_param);
1583 FLAG(needsImplicitCopyConstructor, needs_implicit);
1584 FLAG(needsOverloadResolutionForCopyConstructor,
1585 needs_overload_resolution);
1586 if (!D->needsOverloadResolutionForCopyConstructor())
1587 FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
1588 FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
1589 });
1590
1591 AddChild([=] {
1592 {
1593 ColorScope Color(OS, ShowColors, DeclKindNameColor);
1594 OS << "MoveConstructor";
1595 }
1596 FLAG(hasMoveConstructor, exists);
1597 FLAG(hasSimpleMoveConstructor, simple);
1598 FLAG(hasTrivialMoveConstructor, trivial);
1599 FLAG(hasNonTrivialMoveConstructor, non_trivial);
1600 FLAG(hasUserDeclaredMoveConstructor, user_declared);
1601 FLAG(needsImplicitMoveConstructor, needs_implicit);
1602 FLAG(needsOverloadResolutionForMoveConstructor,
1603 needs_overload_resolution);
1604 if (!D->needsOverloadResolutionForMoveConstructor())
1605 FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
1606 });
1607
1608 AddChild([=] {
1609 {
1610 ColorScope Color(OS, ShowColors, DeclKindNameColor);
1611 OS << "CopyAssignment";
1612 }
1613 FLAG(hasTrivialCopyAssignment, trivial);
1614 FLAG(hasNonTrivialCopyAssignment, non_trivial);
1615 FLAG(hasCopyAssignmentWithConstParam, has_const_param);
1616 FLAG(hasUserDeclaredCopyAssignment, user_declared);
1617 FLAG(needsImplicitCopyAssignment, needs_implicit);
1618 FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
1619 FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
1620 });
1621
1622 AddChild([=] {
1623 {
1624 ColorScope Color(OS, ShowColors, DeclKindNameColor);
1625 OS << "MoveAssignment";
1626 }
1627 FLAG(hasMoveAssignment, exists);
1628 FLAG(hasSimpleMoveAssignment, simple);
1629 FLAG(hasTrivialMoveAssignment, trivial);
1630 FLAG(hasNonTrivialMoveAssignment, non_trivial);
1631 FLAG(hasUserDeclaredMoveAssignment, user_declared);
1632 FLAG(needsImplicitMoveAssignment, needs_implicit);
1633 FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
1634 });
1635
1636 AddChild([=] {
1637 {
1638 ColorScope Color(OS, ShowColors, DeclKindNameColor);
1639 OS << "Destructor";
1640 }
1641 FLAG(hasSimpleDestructor, simple);
1642 FLAG(hasIrrelevantDestructor, irrelevant);
1643 FLAG(hasTrivialDestructor, trivial);
1644 FLAG(hasNonTrivialDestructor, non_trivial);
1645 FLAG(hasUserDeclaredDestructor, user_declared);
1646 FLAG(hasConstexprDestructor, constexpr);
1647 FLAG(needsImplicitDestructor, needs_implicit);
1648 FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
1649 if (!D->needsOverloadResolutionForDestructor())
1650 FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
1651 });
1652 });
1653
1654 for (const auto &I : D->bases()) {
1655 AddChild([=] {
1656 if (I.isVirtual())
1657 OS << "virtual ";
1658 dumpAccessSpecifier(I.getAccessSpecifier());
1659 dumpType(I.getType());
1660 if (I.isPackExpansion())
1661 OS << "...";
1662 });
1663 }
1664 }
1665
1666 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
1667 dumpName(D);
1668 }
1669
1670 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
1671 dumpName(D);
1672 }
1673
1674 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
1675 dumpName(D);
1676 }
1677
1678 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
1679 dumpName(D);
1680 }
1681
1682 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
1683 if (D->wasDeclaredWithTypename())
1684 OS << " typename";
1685 else
1686 OS << " class";
1687 OS << " depth " << D->getDepth() << " index " << D->getIndex();
1688 if (D->isParameterPack())
1689 OS << " ...";
1690 dumpName(D);
1691 }
1692
1693 void TextNodeDumper::VisitNonTypeTemplateParmDecl(
1694 const NonTypeTemplateParmDecl *D) {
1695 dumpType(D->getType());
1696 OS << " depth " << D->getDepth() << " index " << D->getIndex();
1697 if (D->isParameterPack())
1698 OS << " ...";
1699 dumpName(D);
1700 }
1701
1702 void TextNodeDumper::VisitTemplateTemplateParmDecl(
1703 const TemplateTemplateParmDecl *D) {
1704 OS << " depth " << D->getDepth() << " index " << D->getIndex();
1705 if (D->isParameterPack())
1706 OS << " ...";
1707 dumpName(D);
1708 }
1709
1710 void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
1711 OS << ' ';
1712 if (D->getQualifier())
1713 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1714 OS << D->getNameAsString();
1715 }
1716
1717 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
1718 const UnresolvedUsingTypenameDecl *D) {
1719 OS << ' ';
1720 if (D->getQualifier())
1721 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1722 OS << D->getNameAsString();
1723 }
1724
1725 void TextNodeDumper::VisitUnresolvedUsingValueDecl(
1726 const UnresolvedUsingValueDecl *D) {
1727 OS << ' ';
1728 if (D->getQualifier())
1729 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1730 OS << D->getNameAsString();
1731 dumpType(D->getType());
1732 }
1733
1734 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
1735 OS << ' ';
1736 dumpBareDeclRef(D->getTargetDecl());
1737 }
1738
1739 void TextNodeDumper::VisitConstructorUsingShadowDecl(
1740 const ConstructorUsingShadowDecl *D) {
1741 if (D->constructsVirtualBase())
1742 OS << " virtual";
1743
1744 AddChild([=] {
1745 OS << "target ";
1746 dumpBareDeclRef(D->getTargetDecl());
1747 });
1748
1749 AddChild([=] {
1750 OS << "nominated ";
1751 dumpBareDeclRef(D->getNominatedBaseClass());
1752 OS << ' ';
1753 dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
1754 });
1755
1756 AddChild([=] {
1757 OS << "constructed ";
1758 dumpBareDeclRef(D->getConstructedBaseClass());
1759 OS << ' ';
1760 dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
1761 });
1762 }
1763
1764 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
1765 switch (D->getLanguage()) {
1766 case LinkageSpecDecl::lang_c:
1767 OS << " C";
1768 break;
1769 case LinkageSpecDecl::lang_cxx:
1770 OS << " C++";
1771 break;
1772 case LinkageSpecDecl::lang_cxx_11:
1773 OS << " C++11";
1774 break;
1775 case LinkageSpecDecl::lang_cxx_14:
1776 OS << " C++14";
1777 break;
1778 }
1779 }
1780
1781 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
1782 OS << ' ';
1783 dumpAccessSpecifier(D->getAccess());
1784 }
1785
1786 void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
1787 if (TypeSourceInfo *T = D->getFriendType())
1788 dumpType(T->getType());
1789 }
1790
1791 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
1792 dumpName(D);
1793 dumpType(D->getType());
1794 if (D->getSynthesize())
1795 OS << " synthesize";
1796
1797 switch (D->getAccessControl()) {
1798 case ObjCIvarDecl::None:
1799 OS << " none";
1800 break;
1801 case ObjCIvarDecl::Private:
1802 OS << " private";
1803 break;
1804 case ObjCIvarDecl::Protected:
1805 OS << " protected";
1806 break;
1807 case ObjCIvarDecl::Public:
1808 OS << " public";
1809 break;
1810 case ObjCIvarDecl::Package:
1811 OS << " package";
1812 break;
1813 }
1814 }
1815
1816 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
1817 if (D->isInstanceMethod())
1818 OS << " -";
1819 else
1820 OS << " +";
1821 dumpName(D);
1822 dumpType(D->getReturnType());
1823
1824 if (D->isVariadic())
1825 OS << " variadic";
1826 }
1827
1828 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
1829 dumpName(D);
1830 switch (D->getVariance()) {
1831 case ObjCTypeParamVariance::Invariant:
1832 break;
1833
1834 case ObjCTypeParamVariance::Covariant:
1835 OS << " covariant";
1836 break;
1837
1838 case ObjCTypeParamVariance::Contravariant:
1839 OS << " contravariant";
1840 break;
1841 }
1842
1843 if (D->hasExplicitBound())
1844 OS << " bounded";
1845 dumpType(D->getUnderlyingType());
1846 }
1847
1848 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
1849 dumpName(D);
1850 dumpDeclRef(D->getClassInterface());
1851 dumpDeclRef(D->getImplementation());
1852 for (const auto *P : D->protocols())
1853 dumpDeclRef(P);
1854 }
1855
1856 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
1857 dumpName(D);
1858 dumpDeclRef(D->getClassInterface());
1859 dumpDeclRef(D->getCategoryDecl());
1860 }
1861
1862 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
1863 dumpName(D);
1864
1865 for (const auto *Child : D->protocols())
1866 dumpDeclRef(Child);
1867 }
1868
1869 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
1870 dumpName(D);
1871 dumpDeclRef(D->getSuperClass(), "super");
1872
1873 dumpDeclRef(D->getImplementation());
1874 for (const auto *Child : D->protocols())
1875 dumpDeclRef(Child);
1876 }
1877
1878 void TextNodeDumper::VisitObjCImplementationDecl(
1879 const ObjCImplementationDecl *D) {
1880 dumpName(D);
1881 dumpDeclRef(D->getSuperClass(), "super");
1882 dumpDeclRef(D->getClassInterface());
1883 }
1884
1885 void TextNodeDumper::VisitObjCCompatibleAliasDecl(
1886 const ObjCCompatibleAliasDecl *D) {
1887 dumpName(D);
1888 dumpDeclRef(D->getClassInterface());
1889 }
1890
1891 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
1892 dumpName(D);
1893 dumpType(D->getType());
1894
1895 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
1896 OS << " required";
1897 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
1898 OS << " optional";
1899
1900 ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
1901 if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
1902 if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
1903 OS << " readonly";
1904 if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
1905 OS << " assign";
1906 if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
1907 OS << " readwrite";
1908 if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
1909 OS << " retain";
1910 if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
1911 OS << " copy";
1912 if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
1913 OS << " nonatomic";
1914 if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
1915 OS << " atomic";
1916 if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
1917 OS << " weak";
1918 if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
1919 OS << " strong";
1920 if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
1921 OS << " unsafe_unretained";
1922 if (Attrs & ObjCPropertyDecl::OBJC_PR_class)
1923 OS << " class";
1924 if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
1925 dumpDeclRef(D->getGetterMethodDecl(), "getter");
1926 if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
1927 dumpDeclRef(D->getSetterMethodDecl(), "setter");
1928 }
1929 }
1930
1931 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
1932 dumpName(D->getPropertyDecl());
1933 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
1934 OS << " synthesize";
1935 else
1936 OS << " dynamic";
1937 dumpDeclRef(D->getPropertyDecl());
1938 dumpDeclRef(D->getPropertyIvarDecl());
1939 }
1940
1941 void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
1942 if (D->isVariadic())
1943 OS << " variadic";
1944
1945 if (D->capturesCXXThis())
1946 OS << " captures_this";
1947 }
1948
1949 void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
1950 dumpName(D);
1951 }
1952