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