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