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