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