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