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