blob: 97fcaba2c970f4e20f907dec998a89c673dfd5b3 [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 Kellyd8744a72018-12-05 21:12:39 +0000275void TextNodeDumper::dumpPointer(const void *Ptr) {
276 ColorScope Color(OS, ShowColors, AddressColor);
277 OS << ' ' << Ptr;
278}
279
280void TextNodeDumper::dumpLocation(SourceLocation Loc) {
281 if (!SM)
282 return;
283
284 ColorScope Color(OS, ShowColors, LocationColor);
285 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
286
287 // The general format we print out is filename:line:col, but we drop pieces
288 // that haven't changed since the last loc printed.
289 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
290
291 if (PLoc.isInvalid()) {
292 OS << "<invalid sloc>";
293 return;
294 }
295
296 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
297 OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
298 << PLoc.getColumn();
299 LastLocFilename = PLoc.getFilename();
300 LastLocLine = PLoc.getLine();
301 } else if (PLoc.getLine() != LastLocLine) {
302 OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
303 LastLocLine = PLoc.getLine();
304 } else {
305 OS << "col" << ':' << PLoc.getColumn();
306 }
307}
308
309void TextNodeDumper::dumpSourceRange(SourceRange R) {
310 // Can't translate locations if a SourceManager isn't available.
311 if (!SM)
312 return;
313
314 OS << " <";
315 dumpLocation(R.getBegin());
316 if (R.getBegin() != R.getEnd()) {
317 OS << ", ";
318 dumpLocation(R.getEnd());
319 }
320 OS << ">";
321
322 // <t2.c:123:421[blah], t2.c:412:321>
323}
324
325void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
326 ColorScope Color(OS, ShowColors, TypeColor);
327
328 SplitQualType T_split = T.split();
329 OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'";
330
331 if (Desugar && !T.isNull()) {
332 // If the type is sugared, also dump a (shallow) desugared type.
333 SplitQualType D_split = T.getSplitDesugaredType();
334 if (T_split != D_split)
335 OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
336 }
337}
338
339void TextNodeDumper::dumpType(QualType T) {
340 OS << ' ';
341 dumpBareType(T);
342}
343
344void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
345 if (!D) {
346 ColorScope Color(OS, ShowColors, NullColor);
347 OS << "<<<NULL>>>";
348 return;
349 }
350
351 {
352 ColorScope Color(OS, ShowColors, DeclKindNameColor);
353 OS << D->getDeclKindName();
354 }
355 dumpPointer(D);
356
357 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
358 ColorScope Color(OS, ShowColors, DeclNameColor);
359 OS << " '" << ND->getDeclName() << '\'';
360 }
361
362 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
363 dumpType(VD->getType());
364}
365
366void TextNodeDumper::dumpName(const NamedDecl *ND) {
367 if (ND->getDeclName()) {
368 ColorScope Color(OS, ShowColors, DeclNameColor);
369 OS << ' ' << ND->getNameAsString();
370 }
371}
372
373void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
374 switch (AS) {
375 case AS_none:
376 break;
377 case AS_public:
378 OS << "public";
379 break;
380 case AS_protected:
381 OS << "protected";
382 break;
383 case AS_private:
384 OS << "private";
385 break;
386 }
387}
388
389void TextNodeDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
390 OS << "(CXXTemporary";
391 dumpPointer(Temporary);
392 OS << ")";
393}
Stephen Kellye26a88a2018-12-09 13:30:17 +0000394
Stephen Kelly9bc90a22019-01-12 15:45:05 +0000395void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
Stephen Kellyd186dbc2019-01-08 23:11:24 +0000396 if (!D)
397 return;
398
Stephen Kelly12243212019-01-10 20:58:21 +0000399 AddChild([=] {
Stephen Kelly9bc90a22019-01-12 15:45:05 +0000400 if (!Label.empty())
Stephen Kellyd186dbc2019-01-08 23:11:24 +0000401 OS << Label << ' ';
402 dumpBareDeclRef(D);
403 });
404}
405
Stephen Kellye26a88a2018-12-09 13:30:17 +0000406const char *TextNodeDumper::getCommandName(unsigned CommandID) {
407 if (Traits)
408 return Traits->getCommandInfo(CommandID)->Name;
409 const comments::CommandInfo *Info =
410 comments::CommandTraits::getBuiltinCommandInfo(CommandID);
411 if (Info)
412 return Info->Name;
413 return "<not a builtin command>";
414}
415
416void TextNodeDumper::visitTextComment(const comments::TextComment *C,
417 const comments::FullComment *) {
418 OS << " Text=\"" << C->getText() << "\"";
419}
420
421void TextNodeDumper::visitInlineCommandComment(
422 const comments::InlineCommandComment *C, const comments::FullComment *) {
423 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
424 switch (C->getRenderKind()) {
425 case comments::InlineCommandComment::RenderNormal:
426 OS << " RenderNormal";
427 break;
428 case comments::InlineCommandComment::RenderBold:
429 OS << " RenderBold";
430 break;
431 case comments::InlineCommandComment::RenderMonospaced:
432 OS << " RenderMonospaced";
433 break;
434 case comments::InlineCommandComment::RenderEmphasized:
435 OS << " RenderEmphasized";
436 break;
437 }
438
439 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
440 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
441}
442
443void TextNodeDumper::visitHTMLStartTagComment(
444 const comments::HTMLStartTagComment *C, const comments::FullComment *) {
445 OS << " Name=\"" << C->getTagName() << "\"";
446 if (C->getNumAttrs() != 0) {
447 OS << " Attrs: ";
448 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
449 const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
450 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
451 }
452 }
453 if (C->isSelfClosing())
454 OS << " SelfClosing";
455}
456
457void TextNodeDumper::visitHTMLEndTagComment(
458 const comments::HTMLEndTagComment *C, const comments::FullComment *) {
459 OS << " Name=\"" << C->getTagName() << "\"";
460}
461
462void TextNodeDumper::visitBlockCommandComment(
463 const comments::BlockCommandComment *C, const comments::FullComment *) {
464 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
465 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
466 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
467}
468
469void TextNodeDumper::visitParamCommandComment(
470 const comments::ParamCommandComment *C, const comments::FullComment *FC) {
471 OS << " "
472 << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
473
474 if (C->isDirectionExplicit())
475 OS << " explicitly";
476 else
477 OS << " implicitly";
478
479 if (C->hasParamName()) {
480 if (C->isParamIndexValid())
481 OS << " Param=\"" << C->getParamName(FC) << "\"";
482 else
483 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
484 }
485
486 if (C->isParamIndexValid() && !C->isVarArgParam())
487 OS << " ParamIndex=" << C->getParamIndex();
488}
489
490void TextNodeDumper::visitTParamCommandComment(
491 const comments::TParamCommandComment *C, const comments::FullComment *FC) {
492 if (C->hasParamName()) {
493 if (C->isPositionValid())
494 OS << " Param=\"" << C->getParamName(FC) << "\"";
495 else
496 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
497 }
498
499 if (C->isPositionValid()) {
500 OS << " Position=<";
501 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
502 OS << C->getIndex(i);
503 if (i != e - 1)
504 OS << ", ";
505 }
506 OS << ">";
507 }
508}
509
510void TextNodeDumper::visitVerbatimBlockComment(
511 const comments::VerbatimBlockComment *C, const comments::FullComment *) {
512 OS << " Name=\"" << getCommandName(C->getCommandID())
513 << "\""
514 " CloseName=\""
515 << C->getCloseName() << "\"";
516}
517
518void TextNodeDumper::visitVerbatimBlockLineComment(
519 const comments::VerbatimBlockLineComment *C,
520 const comments::FullComment *) {
521 OS << " Text=\"" << C->getText() << "\"";
522}
523
524void TextNodeDumper::visitVerbatimLineComment(
525 const comments::VerbatimLineComment *C, const comments::FullComment *) {
526 OS << " Text=\"" << C->getText() << "\"";
527}
Stephen Kelly63a6f3a2019-01-12 16:35:37 +0000528
529void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
530 OS << " null";
531}
532
533void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
534 OS << " type";
535 dumpType(TA.getAsType());
536}
537
538void TextNodeDumper::VisitDeclarationTemplateArgument(
539 const TemplateArgument &TA) {
540 OS << " decl";
541 dumpDeclRef(TA.getAsDecl());
542}
543
544void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
545 OS << " nullptr";
546}
547
548void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
549 OS << " integral " << TA.getAsIntegral();
550}
551
552void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
553 OS << " template ";
554 TA.getAsTemplate().dump(OS);
555}
556
557void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
558 const TemplateArgument &TA) {
559 OS << " template expansion ";
560 TA.getAsTemplateOrTemplatePattern().dump(OS);
561}
562
563void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
564 OS << " expr";
565}
566
567void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
568 OS << " pack";
569}
Stephen Kelly07b76d22019-01-12 16:53:27 +0000570
571static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
572 if (Node->path_empty())
573 return;
574
575 OS << " (";
576 bool First = true;
577 for (CastExpr::path_const_iterator I = Node->path_begin(),
578 E = Node->path_end();
579 I != E; ++I) {
580 const CXXBaseSpecifier *Base = *I;
581 if (!First)
582 OS << " -> ";
583
584 const CXXRecordDecl *RD =
585 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
586
587 if (Base->isVirtual())
588 OS << "virtual ";
589 OS << RD->getName();
590 First = false;
591 }
592
593 OS << ')';
594}
595
596void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
597 if (Node->hasInitStorage())
598 OS << " has_init";
599 if (Node->hasVarStorage())
600 OS << " has_var";
601 if (Node->hasElseStorage())
602 OS << " has_else";
603}
604
605void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
606 if (Node->hasInitStorage())
607 OS << " has_init";
608 if (Node->hasVarStorage())
609 OS << " has_var";
610}
611
612void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
613 if (Node->hasVarStorage())
614 OS << " has_var";
615}
616
617void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
618 OS << " '" << Node->getName() << "'";
619}
620
621void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
622 OS << " '" << Node->getLabel()->getName() << "'";
623 dumpPointer(Node->getLabel());
624}
625
626void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
627 if (Node->caseStmtIsGNURange())
628 OS << " gnu_range";
629}
630
631void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
632 if (Node->usesADL())
633 OS << " adl";
634}
635
636void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
637 OS << " <";
638 {
639 ColorScope Color(OS, ShowColors, CastColor);
640 OS << Node->getCastKindName();
641 }
642 dumpBasePath(OS, Node);
643 OS << ">";
644}
645
646void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
647 VisitCastExpr(Node);
648 if (Node->isPartOfExplicitCast())
649 OS << " part_of_explicit_cast";
650}
651
652void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
653 OS << " ";
654 dumpBareDeclRef(Node->getDecl());
655 if (Node->getDecl() != Node->getFoundDecl()) {
656 OS << " (";
657 dumpBareDeclRef(Node->getFoundDecl());
658 OS << ")";
659 }
660}
661
662void TextNodeDumper::VisitUnresolvedLookupExpr(
663 const UnresolvedLookupExpr *Node) {
664 OS << " (";
665 if (!Node->requiresADL())
666 OS << "no ";
667 OS << "ADL) = '" << Node->getName() << '\'';
668
669 UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
670 E = Node->decls_end();
671 if (I == E)
672 OS << " empty";
673 for (; I != E; ++I)
674 dumpPointer(*I);
675}
676
677void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
678 {
679 ColorScope Color(OS, ShowColors, DeclKindNameColor);
680 OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
681 }
682 OS << "='" << *Node->getDecl() << "'";
683 dumpPointer(Node->getDecl());
684 if (Node->isFreeIvar())
685 OS << " isFreeIvar";
686}
687
688void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
689 OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
690}
691
692void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
693 ColorScope Color(OS, ShowColors, ValueColor);
694 OS << " " << Node->getValue();
695}
696
697void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
698 bool isSigned = Node->getType()->isSignedIntegerType();
699 ColorScope Color(OS, ShowColors, ValueColor);
700 OS << " " << Node->getValue().toString(10, isSigned);
701}
702
703void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
704 ColorScope Color(OS, ShowColors, ValueColor);
705 OS << " " << Node->getValueAsString(/*Radix=*/10);
706}
707
708void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
709 ColorScope Color(OS, ShowColors, ValueColor);
710 OS << " " << Node->getValueAsApproximateDouble();
711}
712
713void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
714 ColorScope Color(OS, ShowColors, ValueColor);
715 OS << " ";
716 Str->outputString(OS);
717}
718
719void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
720 if (auto *Field = ILE->getInitializedFieldInUnion()) {
721 OS << " field ";
722 dumpBareDeclRef(Field);
723 }
724}
725
726void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
727 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
728 << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
729 if (!Node->canOverflow())
730 OS << " cannot overflow";
731}
732
733void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
734 const UnaryExprOrTypeTraitExpr *Node) {
735 switch (Node->getKind()) {
736 case UETT_SizeOf:
737 OS << " sizeof";
738 break;
739 case UETT_AlignOf:
740 OS << " alignof";
741 break;
742 case UETT_VecStep:
743 OS << " vec_step";
744 break;
745 case UETT_OpenMPRequiredSimdAlign:
746 OS << " __builtin_omp_required_simd_align";
747 break;
748 case UETT_PreferredAlignOf:
749 OS << " __alignof";
750 break;
751 }
752 if (Node->isArgumentType())
753 dumpType(Node->getArgumentType());
754}
755
756void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
757 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
758 dumpPointer(Node->getMemberDecl());
759}
760
761void TextNodeDumper::VisitExtVectorElementExpr(
762 const ExtVectorElementExpr *Node) {
763 OS << " " << Node->getAccessor().getNameStart();
764}
765
766void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
767 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
768}
769
770void TextNodeDumper::VisitCompoundAssignOperator(
771 const CompoundAssignOperator *Node) {
772 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
773 << "' ComputeLHSTy=";
774 dumpBareType(Node->getComputationLHSType());
775 OS << " ComputeResultTy=";
776 dumpBareType(Node->getComputationResultType());
777}
778
779void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
780 OS << " " << Node->getLabel()->getName();
781 dumpPointer(Node->getLabel());
782}
783
784void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
785 OS << " " << Node->getCastName() << "<"
786 << Node->getTypeAsWritten().getAsString() << ">"
787 << " <" << Node->getCastKindName();
788 dumpBasePath(OS, Node);
789 OS << ">";
790}
791
792void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
793 OS << " " << (Node->getValue() ? "true" : "false");
794}
795
796void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
797 OS << " this";
798}
799
800void TextNodeDumper::VisitCXXFunctionalCastExpr(
801 const CXXFunctionalCastExpr *Node) {
802 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
803 << Node->getCastKindName() << ">";
804}
805
806void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
807 const CXXUnresolvedConstructExpr *Node) {
808 dumpType(Node->getTypeAsWritten());
809 if (Node->isListInitialization())
810 OS << " list";
811}
812
813void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
814 CXXConstructorDecl *Ctor = Node->getConstructor();
815 dumpType(Ctor->getType());
816 if (Node->isElidable())
817 OS << " elidable";
818 if (Node->isListInitialization())
819 OS << " list";
820 if (Node->isStdInitListInitialization())
821 OS << " std::initializer_list";
822 if (Node->requiresZeroInitialization())
823 OS << " zeroing";
824}
825
826void TextNodeDumper::VisitCXXBindTemporaryExpr(
827 const CXXBindTemporaryExpr *Node) {
828 OS << " ";
829 dumpCXXTemporary(Node->getTemporary());
830}
831
832void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
833 if (Node->isGlobalNew())
834 OS << " global";
835 if (Node->isArray())
836 OS << " array";
837 if (Node->getOperatorNew()) {
838 OS << ' ';
839 dumpBareDeclRef(Node->getOperatorNew());
840 }
841 // We could dump the deallocation function used in case of error, but it's
842 // usually not that interesting.
843}
844
845void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
846 if (Node->isGlobalDelete())
847 OS << " global";
848 if (Node->isArrayForm())
849 OS << " array";
850 if (Node->getOperatorDelete()) {
851 OS << ' ';
852 dumpBareDeclRef(Node->getOperatorDelete());
853 }
854}
855
856void TextNodeDumper::VisitMaterializeTemporaryExpr(
857 const MaterializeTemporaryExpr *Node) {
858 if (const ValueDecl *VD = Node->getExtendingDecl()) {
859 OS << " extended by ";
860 dumpBareDeclRef(VD);
861 }
862}
863
864void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
865 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
866 dumpDeclRef(Node->getObject(i), "cleanup");
867}
868
869void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
870 dumpPointer(Node->getPack());
871 dumpName(Node->getPack());
872}
873
874void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
875 const CXXDependentScopeMemberExpr *Node) {
876 OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
877}
878
879void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
880 OS << " selector=";
881 Node->getSelector().print(OS);
882 switch (Node->getReceiverKind()) {
883 case ObjCMessageExpr::Instance:
884 break;
885
886 case ObjCMessageExpr::Class:
887 OS << " class=";
888 dumpBareType(Node->getClassReceiver());
889 break;
890
891 case ObjCMessageExpr::SuperInstance:
892 OS << " super (instance)";
893 break;
894
895 case ObjCMessageExpr::SuperClass:
896 OS << " super (class)";
897 break;
898 }
899}
900
901void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
902 if (auto *BoxingMethod = Node->getBoxingMethod()) {
903 OS << " selector=";
904 BoxingMethod->getSelector().print(OS);
905 }
906}
907
908void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
909 if (!Node->getCatchParamDecl())
910 OS << " catch all";
911}
912
913void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
914 dumpType(Node->getEncodedType());
915}
916
917void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
918 OS << " ";
919 Node->getSelector().print(OS);
920}
921
922void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
923 OS << ' ' << *Node->getProtocol();
924}
925
926void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
927 if (Node->isImplicitProperty()) {
928 OS << " Kind=MethodRef Getter=\"";
929 if (Node->getImplicitPropertyGetter())
930 Node->getImplicitPropertyGetter()->getSelector().print(OS);
931 else
932 OS << "(null)";
933
934 OS << "\" Setter=\"";
935 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
936 Setter->getSelector().print(OS);
937 else
938 OS << "(null)";
939 OS << "\"";
940 } else {
941 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
942 << '"';
943 }
944
945 if (Node->isSuperReceiver())
946 OS << " super";
947
948 OS << " Messaging=";
949 if (Node->isMessagingGetter() && Node->isMessagingSetter())
950 OS << "Getter&Setter";
951 else if (Node->isMessagingGetter())
952 OS << "Getter";
953 else if (Node->isMessagingSetter())
954 OS << "Setter";
955}
956
957void TextNodeDumper::VisitObjCSubscriptRefExpr(
958 const ObjCSubscriptRefExpr *Node) {
959 if (Node->isArraySubscriptRefExpr())
960 OS << " Kind=ArraySubscript GetterForArray=\"";
961 else
962 OS << " Kind=DictionarySubscript GetterForDictionary=\"";
963 if (Node->getAtIndexMethodDecl())
964 Node->getAtIndexMethodDecl()->getSelector().print(OS);
965 else
966 OS << "(null)";
967
968 if (Node->isArraySubscriptRefExpr())
969 OS << "\" SetterForArray=\"";
970 else
971 OS << "\" SetterForDictionary=\"";
972 if (Node->setAtIndexMethodDecl())
973 Node->setAtIndexMethodDecl()->getSelector().print(OS);
974 else
975 OS << "(null)";
976}
977
978void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
979 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
980}
Stephen Kellyf08ca202019-01-15 09:30:00 +0000981
982void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
983 if (T->isSpelledAsLValue())
984 OS << " written as lvalue reference";
985}
986
987void TextNodeDumper::VisitArrayType(const ArrayType *T) {
988 switch (T->getSizeModifier()) {
989 case ArrayType::Normal:
990 break;
991 case ArrayType::Static:
992 OS << " static";
993 break;
994 case ArrayType::Star:
995 OS << " *";
996 break;
997 }
998 OS << " " << T->getIndexTypeQualifiers().getAsString();
999}
1000
1001void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
1002 OS << " " << T->getSize();
1003 VisitArrayType(T);
1004}
1005
1006void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
1007 OS << " ";
1008 dumpSourceRange(T->getBracketsRange());
1009 VisitArrayType(T);
1010}
1011
1012void TextNodeDumper::VisitDependentSizedArrayType(
1013 const DependentSizedArrayType *T) {
1014 VisitArrayType(T);
1015 OS << " ";
1016 dumpSourceRange(T->getBracketsRange());
1017}
1018
1019void TextNodeDumper::VisitDependentSizedExtVectorType(
1020 const DependentSizedExtVectorType *T) {
1021 OS << " ";
1022 dumpLocation(T->getAttributeLoc());
1023}
1024
1025void TextNodeDumper::VisitVectorType(const VectorType *T) {
1026 switch (T->getVectorKind()) {
1027 case VectorType::GenericVector:
1028 break;
1029 case VectorType::AltiVecVector:
1030 OS << " altivec";
1031 break;
1032 case VectorType::AltiVecPixel:
1033 OS << " altivec pixel";
1034 break;
1035 case VectorType::AltiVecBool:
1036 OS << " altivec bool";
1037 break;
1038 case VectorType::NeonVector:
1039 OS << " neon";
1040 break;
1041 case VectorType::NeonPolyVector:
1042 OS << " neon poly";
1043 break;
1044 }
1045 OS << " " << T->getNumElements();
1046}
1047
1048void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
1049 auto EI = T->getExtInfo();
1050 if (EI.getNoReturn())
1051 OS << " noreturn";
1052 if (EI.getProducesResult())
1053 OS << " produces_result";
1054 if (EI.getHasRegParm())
1055 OS << " regparm " << EI.getRegParm();
1056 OS << " " << FunctionType::getNameForCallConv(EI.getCC());
1057}
1058
1059void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
1060 auto EPI = T->getExtProtoInfo();
1061 if (EPI.HasTrailingReturn)
1062 OS << " trailing_return";
1063 if (T->isConst())
1064 OS << " const";
1065 if (T->isVolatile())
1066 OS << " volatile";
1067 if (T->isRestrict())
1068 OS << " restrict";
1069 switch (EPI.RefQualifier) {
1070 case RQ_None:
1071 break;
1072 case RQ_LValue:
1073 OS << " &";
1074 break;
1075 case RQ_RValue:
1076 OS << " &&";
1077 break;
1078 }
1079 // FIXME: Exception specification.
1080 // FIXME: Consumed parameters.
1081 VisitFunctionType(T);
1082}
1083
1084void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1085 dumpDeclRef(T->getDecl());
1086}
1087
1088void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
1089 dumpDeclRef(T->getDecl());
1090}
1091
1092void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
1093 switch (T->getUTTKind()) {
1094 case UnaryTransformType::EnumUnderlyingType:
1095 OS << " underlying_type";
1096 break;
1097 }
1098}
1099
1100void TextNodeDumper::VisitTagType(const TagType *T) {
1101 dumpDeclRef(T->getDecl());
1102}
1103
1104void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1105 OS << " depth " << T->getDepth() << " index " << T->getIndex();
1106 if (T->isParameterPack())
1107 OS << " pack";
1108 dumpDeclRef(T->getDecl());
1109}
1110
1111void TextNodeDumper::VisitAutoType(const AutoType *T) {
1112 if (T->isDecltypeAuto())
1113 OS << " decltype(auto)";
1114 if (!T->isDeduced())
1115 OS << " undeduced";
1116}
1117
1118void TextNodeDumper::VisitTemplateSpecializationType(
1119 const TemplateSpecializationType *T) {
1120 if (T->isTypeAlias())
1121 OS << " alias";
1122 OS << " ";
1123 T->getTemplateName().dump(OS);
1124}
1125
1126void TextNodeDumper::VisitInjectedClassNameType(
1127 const InjectedClassNameType *T) {
1128 dumpDeclRef(T->getDecl());
1129}
1130
1131void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1132 dumpDeclRef(T->getDecl());
1133}
1134
1135void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
1136 if (auto N = T->getNumExpansions())
1137 OS << " expansions " << *N;
1138}