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