blob: c20e55ee8a086539ad6baa2feac45e6bbc3b325c [file] [log] [blame]
Stephen Kellyd8744a72018-12-05 21:12:39 +00001//===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements AST dumping of components of individual AST nodes.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/TextNodeDumper.h"
Stephen Kellyd83fe892019-01-15 09:35:52 +000015#include "clang/AST/DeclFriend.h"
16#include "clang/AST/DeclOpenMP.h"
Stephen Kellyf08ca202019-01-15 09:30:00 +000017#include "clang/AST/DeclTemplate.h"
Stephen Kelly449fa762019-01-14 20:11:02 +000018#include "clang/AST/LocInfoType.h"
Stephen Kellyd8744a72018-12-05 21:12:39 +000019
20using namespace clang;
21
Stephen Kellyd83fe892019-01-15 09:35:52 +000022static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
23
24template <typename T>
25static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
26 const T *First = D->getFirstDecl();
27 if (First != D)
28 OS << " first " << First;
29}
30
31template <typename T>
32static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
33 const T *Prev = D->getPreviousDecl();
34 if (Prev)
35 OS << " prev " << Prev;
36}
37
38/// Dump the previous declaration in the redeclaration chain for a declaration,
39/// if any.
40static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
41 switch (D->getKind()) {
42#define DECL(DERIVED, BASE) \
43 case Decl::DERIVED: \
44 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
45#define ABSTRACT_DECL(DECL)
46#include "clang/AST/DeclNodes.inc"
47 }
48 llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
49}
50
Stephen Kellyd8744a72018-12-05 21:12:39 +000051TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors,
52 const SourceManager *SM,
Stephen Kellye26a88a2018-12-09 13:30:17 +000053 const PrintingPolicy &PrintPolicy,
54 const comments::CommandTraits *Traits)
Stephen Kellyb6d674f2019-01-08 22:32:48 +000055 : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors), SM(SM),
56 PrintPolicy(PrintPolicy), Traits(Traits) {}
Stephen Kellye26a88a2018-12-09 13:30:17 +000057
58void TextNodeDumper::Visit(const comments::Comment *C,
59 const comments::FullComment *FC) {
60 if (!C) {
61 ColorScope Color(OS, ShowColors, NullColor);
62 OS << "<<<NULL>>>";
63 return;
64 }
65
66 {
67 ColorScope Color(OS, ShowColors, CommentColor);
68 OS << C->getCommentKindName();
69 }
70 dumpPointer(C);
71 dumpSourceRange(C->getSourceRange());
72
73 ConstCommentVisitor<TextNodeDumper, void,
74 const comments::FullComment *>::visit(C, FC);
75}
Stephen Kellyd8744a72018-12-05 21:12:39 +000076
Stephen Kellydb8fac12019-01-11 19:16:01 +000077void TextNodeDumper::Visit(const Attr *A) {
78 {
79 ColorScope Color(OS, ShowColors, AttrColor);
80
81 switch (A->getKind()) {
82#define ATTR(X) \
83 case attr::X: \
84 OS << #X; \
85 break;
86#include "clang/Basic/AttrList.inc"
87 }
88 OS << "Attr";
89 }
90 dumpPointer(A);
91 dumpSourceRange(A->getRange());
92 if (A->isInherited())
93 OS << " Inherited";
94 if (A->isImplicit())
95 OS << " Implicit";
96
97 ConstAttrVisitor<TextNodeDumper>::Visit(A);
98}
99
Stephen Kelly63a6f3a2019-01-12 16:35:37 +0000100void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
101 const Decl *From, StringRef Label) {
102 OS << "TemplateArgument";
103 if (R.isValid())
104 dumpSourceRange(R);
105
Stephen Kelly4b5e7cd2019-01-14 19:50:34 +0000106 if (From)
Stephen Kelly63a6f3a2019-01-12 16:35:37 +0000107 dumpDeclRef(From, Label);
Stephen Kelly63a6f3a2019-01-12 16:35:37 +0000108
109 ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
110}
111
Stephen Kelly07b76d22019-01-12 16:53:27 +0000112void TextNodeDumper::Visit(const Stmt *Node) {
113 if (!Node) {
114 ColorScope Color(OS, ShowColors, NullColor);
115 OS << "<<<NULL>>>";
116 return;
117 }
118 {
119 ColorScope Color(OS, ShowColors, StmtColor);
120 OS << Node->getStmtClassName();
121 }
122 dumpPointer(Node);
123 dumpSourceRange(Node->getSourceRange());
124
125 if (const auto *E = dyn_cast<Expr>(Node)) {
126 dumpType(E->getType());
127
128 {
129 ColorScope Color(OS, ShowColors, ValueKindColor);
130 switch (E->getValueKind()) {
131 case VK_RValue:
132 break;
133 case VK_LValue:
134 OS << " lvalue";
135 break;
136 case VK_XValue:
137 OS << " xvalue";
138 break;
139 }
140 }
141
142 {
143 ColorScope Color(OS, ShowColors, ObjectKindColor);
144 switch (E->getObjectKind()) {
145 case OK_Ordinary:
146 break;
147 case OK_BitField:
148 OS << " bitfield";
149 break;
150 case OK_ObjCProperty:
151 OS << " objcproperty";
152 break;
153 case OK_ObjCSubscript:
154 OS << " objcsubscript";
155 break;
156 case OK_VectorComponent:
157 OS << " vectorcomponent";
158 break;
159 }
160 }
161 }
162
163 ConstStmtVisitor<TextNodeDumper>::Visit(Node);
164}
165
Stephen Kelly449fa762019-01-14 20:11:02 +0000166void TextNodeDumper::Visit(const Type *T) {
167 if (!T) {
168 ColorScope Color(OS, ShowColors, NullColor);
169 OS << "<<<NULL>>>";
170 return;
171 }
172 if (isa<LocInfoType>(T)) {
173 {
174 ColorScope Color(OS, ShowColors, TypeColor);
175 OS << "LocInfo Type";
176 }
177 dumpPointer(T);
178 return;
179 }
180
181 {
182 ColorScope Color(OS, ShowColors, TypeColor);
183 OS << T->getTypeClassName() << "Type";
184 }
185 dumpPointer(T);
186 OS << " ";
187 dumpBareType(QualType(T, 0), false);
188
189 QualType SingleStepDesugar =
190 T->getLocallyUnqualifiedSingleStepDesugaredType();
191 if (SingleStepDesugar != QualType(T, 0))
192 OS << " sugar";
193
194 if (T->isDependentType())
195 OS << " dependent";
196 else if (T->isInstantiationDependentType())
197 OS << " instantiation_dependent";
198
199 if (T->isVariablyModifiedType())
200 OS << " variably_modified";
201 if (T->containsUnexpandedParameterPack())
202 OS << " contains_unexpanded_pack";
203 if (T->isFromAST())
204 OS << " imported";
Stephen Kellyf08ca202019-01-15 09:30:00 +0000205
206 TypeVisitor<TextNodeDumper>::Visit(T);
Stephen Kelly449fa762019-01-14 20:11:02 +0000207}
208
Stephen Kelly58c65042019-01-14 20:15:29 +0000209void TextNodeDumper::Visit(QualType T) {
210 OS << "QualType";
211 dumpPointer(T.getAsOpaquePtr());
212 OS << " ";
213 dumpBareType(T, false);
214 OS << " " << T.split().Quals.getAsString();
215}
216
Stephen Kellyd83fe892019-01-15 09:35:52 +0000217void TextNodeDumper::Visit(const Decl *D) {
218 if (!D) {
219 ColorScope Color(OS, ShowColors, NullColor);
220 OS << "<<<NULL>>>";
221 return;
222 }
223
224 {
225 ColorScope Color(OS, ShowColors, DeclKindNameColor);
226 OS << D->getDeclKindName() << "Decl";
227 }
228 dumpPointer(D);
229 if (D->getLexicalDeclContext() != D->getDeclContext())
230 OS << " parent " << cast<Decl>(D->getDeclContext());
231 dumpPreviousDecl(OS, D);
232 dumpSourceRange(D->getSourceRange());
233 OS << ' ';
234 dumpLocation(D->getLocation());
235 if (D->isFromASTFile())
236 OS << " imported";
237 if (Module *M = D->getOwningModule())
238 OS << " in " << M->getFullModuleName();
239 if (auto *ND = dyn_cast<NamedDecl>(D))
240 for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
241 const_cast<NamedDecl *>(ND)))
242 AddChild([=] { OS << "also in " << M->getFullModuleName(); });
243 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
244 if (ND->isHidden())
245 OS << " hidden";
246 if (D->isImplicit())
247 OS << " implicit";
248
249 if (D->isUsed())
250 OS << " used";
251 else if (D->isThisDeclarationReferenced())
252 OS << " referenced";
253
254 if (D->isInvalidDecl())
255 OS << " invalid";
256 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
257 if (FD->isConstexpr())
258 OS << " constexpr";
259}
260
Stephen Kelly0e050fa2019-01-15 20:17:33 +0000261void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
262 OS << "CXXCtorInitializer";
263 if (Init->isAnyMemberInitializer()) {
264 OS << ' ';
265 dumpBareDeclRef(Init->getAnyMember());
266 } else if (Init->isBaseInitializer()) {
267 dumpType(QualType(Init->getBaseClass(), 0));
268 } else if (Init->isDelegatingInitializer()) {
269 dumpType(Init->getTypeSourceInfo()->getType());
270 } else {
271 llvm_unreachable("Unknown initializer type");
272 }
273}
274
Stephen Kelly3cdd1a72019-01-15 20:31:31 +0000275void TextNodeDumper::Visit(const OMPClause *C) {
276 if (!C) {
277 ColorScope Color(OS, ShowColors, NullColor);
278 OS << "<<<NULL>>> OMPClause";
279 return;
280 }
281 {
282 ColorScope Color(OS, ShowColors, AttrColor);
283 StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
284 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
285 << ClauseName.drop_front() << "Clause";
286 }
287 dumpPointer(C);
288 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
289 if (C->isImplicit())
290 OS << " <implicit>";
291}
292
Stephen Kellyd8744a72018-12-05 21:12:39 +0000293void TextNodeDumper::dumpPointer(const void *Ptr) {
294 ColorScope Color(OS, ShowColors, AddressColor);
295 OS << ' ' << Ptr;
296}
297
298void TextNodeDumper::dumpLocation(SourceLocation Loc) {
299 if (!SM)
300 return;
301
302 ColorScope Color(OS, ShowColors, LocationColor);
303 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
304
305 // The general format we print out is filename:line:col, but we drop pieces
306 // that haven't changed since the last loc printed.
307 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
308
309 if (PLoc.isInvalid()) {
310 OS << "<invalid sloc>";
311 return;
312 }
313
314 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
315 OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
316 << PLoc.getColumn();
317 LastLocFilename = PLoc.getFilename();
318 LastLocLine = PLoc.getLine();
319 } else if (PLoc.getLine() != LastLocLine) {
320 OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
321 LastLocLine = PLoc.getLine();
322 } else {
323 OS << "col" << ':' << PLoc.getColumn();
324 }
325}
326
327void TextNodeDumper::dumpSourceRange(SourceRange R) {
328 // Can't translate locations if a SourceManager isn't available.
329 if (!SM)
330 return;
331
332 OS << " <";
333 dumpLocation(R.getBegin());
334 if (R.getBegin() != R.getEnd()) {
335 OS << ", ";
336 dumpLocation(R.getEnd());
337 }
338 OS << ">";
339
340 // <t2.c:123:421[blah], t2.c:412:321>
341}
342
343void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
344 ColorScope Color(OS, ShowColors, TypeColor);
345
346 SplitQualType T_split = T.split();
347 OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'";
348
349 if (Desugar && !T.isNull()) {
350 // If the type is sugared, also dump a (shallow) desugared type.
351 SplitQualType D_split = T.getSplitDesugaredType();
352 if (T_split != D_split)
353 OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
354 }
355}
356
357void TextNodeDumper::dumpType(QualType T) {
358 OS << ' ';
359 dumpBareType(T);
360}
361
362void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
363 if (!D) {
364 ColorScope Color(OS, ShowColors, NullColor);
365 OS << "<<<NULL>>>";
366 return;
367 }
368
369 {
370 ColorScope Color(OS, ShowColors, DeclKindNameColor);
371 OS << D->getDeclKindName();
372 }
373 dumpPointer(D);
374
375 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
376 ColorScope Color(OS, ShowColors, DeclNameColor);
377 OS << " '" << ND->getDeclName() << '\'';
378 }
379
380 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
381 dumpType(VD->getType());
382}
383
384void TextNodeDumper::dumpName(const NamedDecl *ND) {
385 if (ND->getDeclName()) {
386 ColorScope Color(OS, ShowColors, DeclNameColor);
387 OS << ' ' << ND->getNameAsString();
388 }
389}
390
391void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
392 switch (AS) {
393 case AS_none:
394 break;
395 case AS_public:
396 OS << "public";
397 break;
398 case AS_protected:
399 OS << "protected";
400 break;
401 case AS_private:
402 OS << "private";
403 break;
404 }
405}
406
407void TextNodeDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
408 OS << "(CXXTemporary";
409 dumpPointer(Temporary);
410 OS << ")";
411}
Stephen Kellye26a88a2018-12-09 13:30:17 +0000412
Stephen Kelly9bc90a22019-01-12 15:45:05 +0000413void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
Stephen Kellyd186dbc2019-01-08 23:11:24 +0000414 if (!D)
415 return;
416
Stephen Kelly12243212019-01-10 20:58:21 +0000417 AddChild([=] {
Stephen Kelly9bc90a22019-01-12 15:45:05 +0000418 if (!Label.empty())
Stephen Kellyd186dbc2019-01-08 23:11:24 +0000419 OS << Label << ' ';
420 dumpBareDeclRef(D);
421 });
422}
423
Stephen Kellye26a88a2018-12-09 13:30:17 +0000424const char *TextNodeDumper::getCommandName(unsigned CommandID) {
425 if (Traits)
426 return Traits->getCommandInfo(CommandID)->Name;
427 const comments::CommandInfo *Info =
428 comments::CommandTraits::getBuiltinCommandInfo(CommandID);
429 if (Info)
430 return Info->Name;
431 return "<not a builtin command>";
432}
433
434void TextNodeDumper::visitTextComment(const comments::TextComment *C,
435 const comments::FullComment *) {
436 OS << " Text=\"" << C->getText() << "\"";
437}
438
439void TextNodeDumper::visitInlineCommandComment(
440 const comments::InlineCommandComment *C, const comments::FullComment *) {
441 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
442 switch (C->getRenderKind()) {
443 case comments::InlineCommandComment::RenderNormal:
444 OS << " RenderNormal";
445 break;
446 case comments::InlineCommandComment::RenderBold:
447 OS << " RenderBold";
448 break;
449 case comments::InlineCommandComment::RenderMonospaced:
450 OS << " RenderMonospaced";
451 break;
452 case comments::InlineCommandComment::RenderEmphasized:
453 OS << " RenderEmphasized";
454 break;
455 }
456
457 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
458 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
459}
460
461void TextNodeDumper::visitHTMLStartTagComment(
462 const comments::HTMLStartTagComment *C, const comments::FullComment *) {
463 OS << " Name=\"" << C->getTagName() << "\"";
464 if (C->getNumAttrs() != 0) {
465 OS << " Attrs: ";
466 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
467 const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
468 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
469 }
470 }
471 if (C->isSelfClosing())
472 OS << " SelfClosing";
473}
474
475void TextNodeDumper::visitHTMLEndTagComment(
476 const comments::HTMLEndTagComment *C, const comments::FullComment *) {
477 OS << " Name=\"" << C->getTagName() << "\"";
478}
479
480void TextNodeDumper::visitBlockCommandComment(
481 const comments::BlockCommandComment *C, const comments::FullComment *) {
482 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
483 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
484 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
485}
486
487void TextNodeDumper::visitParamCommandComment(
488 const comments::ParamCommandComment *C, const comments::FullComment *FC) {
489 OS << " "
490 << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
491
492 if (C->isDirectionExplicit())
493 OS << " explicitly";
494 else
495 OS << " implicitly";
496
497 if (C->hasParamName()) {
498 if (C->isParamIndexValid())
499 OS << " Param=\"" << C->getParamName(FC) << "\"";
500 else
501 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
502 }
503
504 if (C->isParamIndexValid() && !C->isVarArgParam())
505 OS << " ParamIndex=" << C->getParamIndex();
506}
507
508void TextNodeDumper::visitTParamCommandComment(
509 const comments::TParamCommandComment *C, const comments::FullComment *FC) {
510 if (C->hasParamName()) {
511 if (C->isPositionValid())
512 OS << " Param=\"" << C->getParamName(FC) << "\"";
513 else
514 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
515 }
516
517 if (C->isPositionValid()) {
518 OS << " Position=<";
519 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
520 OS << C->getIndex(i);
521 if (i != e - 1)
522 OS << ", ";
523 }
524 OS << ">";
525 }
526}
527
528void TextNodeDumper::visitVerbatimBlockComment(
529 const comments::VerbatimBlockComment *C, const comments::FullComment *) {
530 OS << " Name=\"" << getCommandName(C->getCommandID())
531 << "\""
532 " CloseName=\""
533 << C->getCloseName() << "\"";
534}
535
536void TextNodeDumper::visitVerbatimBlockLineComment(
537 const comments::VerbatimBlockLineComment *C,
538 const comments::FullComment *) {
539 OS << " Text=\"" << C->getText() << "\"";
540}
541
542void TextNodeDumper::visitVerbatimLineComment(
543 const comments::VerbatimLineComment *C, const comments::FullComment *) {
544 OS << " Text=\"" << C->getText() << "\"";
545}
Stephen Kelly63a6f3a2019-01-12 16:35:37 +0000546
547void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
548 OS << " null";
549}
550
551void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
552 OS << " type";
553 dumpType(TA.getAsType());
554}
555
556void TextNodeDumper::VisitDeclarationTemplateArgument(
557 const TemplateArgument &TA) {
558 OS << " decl";
559 dumpDeclRef(TA.getAsDecl());
560}
561
562void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
563 OS << " nullptr";
564}
565
566void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
567 OS << " integral " << TA.getAsIntegral();
568}
569
570void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
571 OS << " template ";
572 TA.getAsTemplate().dump(OS);
573}
574
575void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
576 const TemplateArgument &TA) {
577 OS << " template expansion ";
578 TA.getAsTemplateOrTemplatePattern().dump(OS);
579}
580
581void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
582 OS << " expr";
583}
584
585void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
586 OS << " pack";
587}
Stephen Kelly07b76d22019-01-12 16:53:27 +0000588
589static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
590 if (Node->path_empty())
591 return;
592
593 OS << " (";
594 bool First = true;
595 for (CastExpr::path_const_iterator I = Node->path_begin(),
596 E = Node->path_end();
597 I != E; ++I) {
598 const CXXBaseSpecifier *Base = *I;
599 if (!First)
600 OS << " -> ";
601
602 const CXXRecordDecl *RD =
603 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
604
605 if (Base->isVirtual())
606 OS << "virtual ";
607 OS << RD->getName();
608 First = false;
609 }
610
611 OS << ')';
612}
613
614void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
615 if (Node->hasInitStorage())
616 OS << " has_init";
617 if (Node->hasVarStorage())
618 OS << " has_var";
619 if (Node->hasElseStorage())
620 OS << " has_else";
621}
622
623void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
624 if (Node->hasInitStorage())
625 OS << " has_init";
626 if (Node->hasVarStorage())
627 OS << " has_var";
628}
629
630void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
631 if (Node->hasVarStorage())
632 OS << " has_var";
633}
634
635void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
636 OS << " '" << Node->getName() << "'";
637}
638
639void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
640 OS << " '" << Node->getLabel()->getName() << "'";
641 dumpPointer(Node->getLabel());
642}
643
644void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
645 if (Node->caseStmtIsGNURange())
646 OS << " gnu_range";
647}
648
649void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
650 if (Node->usesADL())
651 OS << " adl";
652}
653
654void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
655 OS << " <";
656 {
657 ColorScope Color(OS, ShowColors, CastColor);
658 OS << Node->getCastKindName();
659 }
660 dumpBasePath(OS, Node);
661 OS << ">";
662}
663
664void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
665 VisitCastExpr(Node);
666 if (Node->isPartOfExplicitCast())
667 OS << " part_of_explicit_cast";
668}
669
670void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
671 OS << " ";
672 dumpBareDeclRef(Node->getDecl());
673 if (Node->getDecl() != Node->getFoundDecl()) {
674 OS << " (";
675 dumpBareDeclRef(Node->getFoundDecl());
676 OS << ")";
677 }
678}
679
680void TextNodeDumper::VisitUnresolvedLookupExpr(
681 const UnresolvedLookupExpr *Node) {
682 OS << " (";
683 if (!Node->requiresADL())
684 OS << "no ";
685 OS << "ADL) = '" << Node->getName() << '\'';
686
687 UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
688 E = Node->decls_end();
689 if (I == E)
690 OS << " empty";
691 for (; I != E; ++I)
692 dumpPointer(*I);
693}
694
695void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
696 {
697 ColorScope Color(OS, ShowColors, DeclKindNameColor);
698 OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
699 }
700 OS << "='" << *Node->getDecl() << "'";
701 dumpPointer(Node->getDecl());
702 if (Node->isFreeIvar())
703 OS << " isFreeIvar";
704}
705
706void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
707 OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
708}
709
710void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
711 ColorScope Color(OS, ShowColors, ValueColor);
712 OS << " " << Node->getValue();
713}
714
715void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
716 bool isSigned = Node->getType()->isSignedIntegerType();
717 ColorScope Color(OS, ShowColors, ValueColor);
718 OS << " " << Node->getValue().toString(10, isSigned);
719}
720
721void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
722 ColorScope Color(OS, ShowColors, ValueColor);
723 OS << " " << Node->getValueAsString(/*Radix=*/10);
724}
725
726void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
727 ColorScope Color(OS, ShowColors, ValueColor);
728 OS << " " << Node->getValueAsApproximateDouble();
729}
730
731void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
732 ColorScope Color(OS, ShowColors, ValueColor);
733 OS << " ";
734 Str->outputString(OS);
735}
736
737void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
738 if (auto *Field = ILE->getInitializedFieldInUnion()) {
739 OS << " field ";
740 dumpBareDeclRef(Field);
741 }
742}
743
744void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
745 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
746 << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
747 if (!Node->canOverflow())
748 OS << " cannot overflow";
749}
750
751void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
752 const UnaryExprOrTypeTraitExpr *Node) {
753 switch (Node->getKind()) {
754 case UETT_SizeOf:
755 OS << " sizeof";
756 break;
757 case UETT_AlignOf:
758 OS << " alignof";
759 break;
760 case UETT_VecStep:
761 OS << " vec_step";
762 break;
763 case UETT_OpenMPRequiredSimdAlign:
764 OS << " __builtin_omp_required_simd_align";
765 break;
766 case UETT_PreferredAlignOf:
767 OS << " __alignof";
768 break;
769 }
770 if (Node->isArgumentType())
771 dumpType(Node->getArgumentType());
772}
773
774void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
775 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
776 dumpPointer(Node->getMemberDecl());
777}
778
779void TextNodeDumper::VisitExtVectorElementExpr(
780 const ExtVectorElementExpr *Node) {
781 OS << " " << Node->getAccessor().getNameStart();
782}
783
784void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
785 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
786}
787
788void TextNodeDumper::VisitCompoundAssignOperator(
789 const CompoundAssignOperator *Node) {
790 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
791 << "' ComputeLHSTy=";
792 dumpBareType(Node->getComputationLHSType());
793 OS << " ComputeResultTy=";
794 dumpBareType(Node->getComputationResultType());
795}
796
797void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
798 OS << " " << Node->getLabel()->getName();
799 dumpPointer(Node->getLabel());
800}
801
802void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
803 OS << " " << Node->getCastName() << "<"
804 << Node->getTypeAsWritten().getAsString() << ">"
805 << " <" << Node->getCastKindName();
806 dumpBasePath(OS, Node);
807 OS << ">";
808}
809
810void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
811 OS << " " << (Node->getValue() ? "true" : "false");
812}
813
814void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
815 OS << " this";
816}
817
818void TextNodeDumper::VisitCXXFunctionalCastExpr(
819 const CXXFunctionalCastExpr *Node) {
820 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
821 << Node->getCastKindName() << ">";
822}
823
824void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
825 const CXXUnresolvedConstructExpr *Node) {
826 dumpType(Node->getTypeAsWritten());
827 if (Node->isListInitialization())
828 OS << " list";
829}
830
831void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
832 CXXConstructorDecl *Ctor = Node->getConstructor();
833 dumpType(Ctor->getType());
834 if (Node->isElidable())
835 OS << " elidable";
836 if (Node->isListInitialization())
837 OS << " list";
838 if (Node->isStdInitListInitialization())
839 OS << " std::initializer_list";
840 if (Node->requiresZeroInitialization())
841 OS << " zeroing";
842}
843
844void TextNodeDumper::VisitCXXBindTemporaryExpr(
845 const CXXBindTemporaryExpr *Node) {
846 OS << " ";
847 dumpCXXTemporary(Node->getTemporary());
848}
849
850void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
851 if (Node->isGlobalNew())
852 OS << " global";
853 if (Node->isArray())
854 OS << " array";
855 if (Node->getOperatorNew()) {
856 OS << ' ';
857 dumpBareDeclRef(Node->getOperatorNew());
858 }
859 // We could dump the deallocation function used in case of error, but it's
860 // usually not that interesting.
861}
862
863void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
864 if (Node->isGlobalDelete())
865 OS << " global";
866 if (Node->isArrayForm())
867 OS << " array";
868 if (Node->getOperatorDelete()) {
869 OS << ' ';
870 dumpBareDeclRef(Node->getOperatorDelete());
871 }
872}
873
874void TextNodeDumper::VisitMaterializeTemporaryExpr(
875 const MaterializeTemporaryExpr *Node) {
876 if (const ValueDecl *VD = Node->getExtendingDecl()) {
877 OS << " extended by ";
878 dumpBareDeclRef(VD);
879 }
880}
881
882void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
883 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
884 dumpDeclRef(Node->getObject(i), "cleanup");
885}
886
887void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
888 dumpPointer(Node->getPack());
889 dumpName(Node->getPack());
890}
891
892void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
893 const CXXDependentScopeMemberExpr *Node) {
894 OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
895}
896
897void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
898 OS << " selector=";
899 Node->getSelector().print(OS);
900 switch (Node->getReceiverKind()) {
901 case ObjCMessageExpr::Instance:
902 break;
903
904 case ObjCMessageExpr::Class:
905 OS << " class=";
906 dumpBareType(Node->getClassReceiver());
907 break;
908
909 case ObjCMessageExpr::SuperInstance:
910 OS << " super (instance)";
911 break;
912
913 case ObjCMessageExpr::SuperClass:
914 OS << " super (class)";
915 break;
916 }
917}
918
919void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
920 if (auto *BoxingMethod = Node->getBoxingMethod()) {
921 OS << " selector=";
922 BoxingMethod->getSelector().print(OS);
923 }
924}
925
926void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
927 if (!Node->getCatchParamDecl())
928 OS << " catch all";
929}
930
931void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
932 dumpType(Node->getEncodedType());
933}
934
935void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
936 OS << " ";
937 Node->getSelector().print(OS);
938}
939
940void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
941 OS << ' ' << *Node->getProtocol();
942}
943
944void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
945 if (Node->isImplicitProperty()) {
946 OS << " Kind=MethodRef Getter=\"";
947 if (Node->getImplicitPropertyGetter())
948 Node->getImplicitPropertyGetter()->getSelector().print(OS);
949 else
950 OS << "(null)";
951
952 OS << "\" Setter=\"";
953 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
954 Setter->getSelector().print(OS);
955 else
956 OS << "(null)";
957 OS << "\"";
958 } else {
959 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
960 << '"';
961 }
962
963 if (Node->isSuperReceiver())
964 OS << " super";
965
966 OS << " Messaging=";
967 if (Node->isMessagingGetter() && Node->isMessagingSetter())
968 OS << "Getter&Setter";
969 else if (Node->isMessagingGetter())
970 OS << "Getter";
971 else if (Node->isMessagingSetter())
972 OS << "Setter";
973}
974
975void TextNodeDumper::VisitObjCSubscriptRefExpr(
976 const ObjCSubscriptRefExpr *Node) {
977 if (Node->isArraySubscriptRefExpr())
978 OS << " Kind=ArraySubscript GetterForArray=\"";
979 else
980 OS << " Kind=DictionarySubscript GetterForDictionary=\"";
981 if (Node->getAtIndexMethodDecl())
982 Node->getAtIndexMethodDecl()->getSelector().print(OS);
983 else
984 OS << "(null)";
985
986 if (Node->isArraySubscriptRefExpr())
987 OS << "\" SetterForArray=\"";
988 else
989 OS << "\" SetterForDictionary=\"";
990 if (Node->setAtIndexMethodDecl())
991 Node->setAtIndexMethodDecl()->getSelector().print(OS);
992 else
993 OS << "(null)";
994}
995
996void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
997 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
998}
Stephen Kellyf08ca202019-01-15 09:30:00 +0000999
1000void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
1001 if (T->isSpelledAsLValue())
1002 OS << " written as lvalue reference";
1003}
1004
1005void TextNodeDumper::VisitArrayType(const ArrayType *T) {
1006 switch (T->getSizeModifier()) {
1007 case ArrayType::Normal:
1008 break;
1009 case ArrayType::Static:
1010 OS << " static";
1011 break;
1012 case ArrayType::Star:
1013 OS << " *";
1014 break;
1015 }
1016 OS << " " << T->getIndexTypeQualifiers().getAsString();
1017}
1018
1019void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
1020 OS << " " << T->getSize();
1021 VisitArrayType(T);
1022}
1023
1024void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
1025 OS << " ";
1026 dumpSourceRange(T->getBracketsRange());
1027 VisitArrayType(T);
1028}
1029
1030void TextNodeDumper::VisitDependentSizedArrayType(
1031 const DependentSizedArrayType *T) {
1032 VisitArrayType(T);
1033 OS << " ";
1034 dumpSourceRange(T->getBracketsRange());
1035}
1036
1037void TextNodeDumper::VisitDependentSizedExtVectorType(
1038 const DependentSizedExtVectorType *T) {
1039 OS << " ";
1040 dumpLocation(T->getAttributeLoc());
1041}
1042
1043void TextNodeDumper::VisitVectorType(const VectorType *T) {
1044 switch (T->getVectorKind()) {
1045 case VectorType::GenericVector:
1046 break;
1047 case VectorType::AltiVecVector:
1048 OS << " altivec";
1049 break;
1050 case VectorType::AltiVecPixel:
1051 OS << " altivec pixel";
1052 break;
1053 case VectorType::AltiVecBool:
1054 OS << " altivec bool";
1055 break;
1056 case VectorType::NeonVector:
1057 OS << " neon";
1058 break;
1059 case VectorType::NeonPolyVector:
1060 OS << " neon poly";
1061 break;
1062 }
1063 OS << " " << T->getNumElements();
1064}
1065
1066void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
1067 auto EI = T->getExtInfo();
1068 if (EI.getNoReturn())
1069 OS << " noreturn";
1070 if (EI.getProducesResult())
1071 OS << " produces_result";
1072 if (EI.getHasRegParm())
1073 OS << " regparm " << EI.getRegParm();
1074 OS << " " << FunctionType::getNameForCallConv(EI.getCC());
1075}
1076
1077void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
1078 auto EPI = T->getExtProtoInfo();
1079 if (EPI.HasTrailingReturn)
1080 OS << " trailing_return";
1081 if (T->isConst())
1082 OS << " const";
1083 if (T->isVolatile())
1084 OS << " volatile";
1085 if (T->isRestrict())
1086 OS << " restrict";
1087 switch (EPI.RefQualifier) {
1088 case RQ_None:
1089 break;
1090 case RQ_LValue:
1091 OS << " &";
1092 break;
1093 case RQ_RValue:
1094 OS << " &&";
1095 break;
1096 }
1097 // FIXME: Exception specification.
1098 // FIXME: Consumed parameters.
1099 VisitFunctionType(T);
1100}
1101
1102void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1103 dumpDeclRef(T->getDecl());
1104}
1105
1106void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
1107 dumpDeclRef(T->getDecl());
1108}
1109
1110void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
1111 switch (T->getUTTKind()) {
1112 case UnaryTransformType::EnumUnderlyingType:
1113 OS << " underlying_type";
1114 break;
1115 }
1116}
1117
1118void TextNodeDumper::VisitTagType(const TagType *T) {
1119 dumpDeclRef(T->getDecl());
1120}
1121
1122void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1123 OS << " depth " << T->getDepth() << " index " << T->getIndex();
1124 if (T->isParameterPack())
1125 OS << " pack";
1126 dumpDeclRef(T->getDecl());
1127}
1128
1129void TextNodeDumper::VisitAutoType(const AutoType *T) {
1130 if (T->isDecltypeAuto())
1131 OS << " decltype(auto)";
1132 if (!T->isDeduced())
1133 OS << " undeduced";
1134}
1135
1136void TextNodeDumper::VisitTemplateSpecializationType(
1137 const TemplateSpecializationType *T) {
1138 if (T->isTypeAlias())
1139 OS << " alias";
1140 OS << " ";
1141 T->getTemplateName().dump(OS);
1142}
1143
1144void TextNodeDumper::VisitInjectedClassNameType(
1145 const InjectedClassNameType *T) {
1146 dumpDeclRef(T->getDecl());
1147}
1148
1149void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1150 dumpDeclRef(T->getDecl());
1151}
1152
1153void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
1154 if (auto N = T->getNumExpansions())
1155 OS << " expansions " << *N;
1156}