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