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