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