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