blob: 9c20e08b902ce8306379b28638f04ddaf717af8b [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"
15
16using namespace clang;
17
18TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors,
19 const SourceManager *SM,
Stephen Kellye26a88a2018-12-09 13:30:17 +000020 const PrintingPolicy &PrintPolicy,
21 const comments::CommandTraits *Traits)
Stephen Kellyb6d674f2019-01-08 22:32:48 +000022 : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors), SM(SM),
23 PrintPolicy(PrintPolicy), Traits(Traits) {}
Stephen Kellye26a88a2018-12-09 13:30:17 +000024
25void TextNodeDumper::Visit(const comments::Comment *C,
26 const comments::FullComment *FC) {
27 if (!C) {
28 ColorScope Color(OS, ShowColors, NullColor);
29 OS << "<<<NULL>>>";
30 return;
31 }
32
33 {
34 ColorScope Color(OS, ShowColors, CommentColor);
35 OS << C->getCommentKindName();
36 }
37 dumpPointer(C);
38 dumpSourceRange(C->getSourceRange());
39
40 ConstCommentVisitor<TextNodeDumper, void,
41 const comments::FullComment *>::visit(C, FC);
42}
Stephen Kellyd8744a72018-12-05 21:12:39 +000043
Stephen Kellydb8fac12019-01-11 19:16:01 +000044void TextNodeDumper::Visit(const Attr *A) {
45 {
46 ColorScope Color(OS, ShowColors, AttrColor);
47
48 switch (A->getKind()) {
49#define ATTR(X) \
50 case attr::X: \
51 OS << #X; \
52 break;
53#include "clang/Basic/AttrList.inc"
54 }
55 OS << "Attr";
56 }
57 dumpPointer(A);
58 dumpSourceRange(A->getRange());
59 if (A->isInherited())
60 OS << " Inherited";
61 if (A->isImplicit())
62 OS << " Implicit";
63
64 ConstAttrVisitor<TextNodeDumper>::Visit(A);
65}
66
Stephen Kelly63a6f3a2019-01-12 16:35:37 +000067void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
68 const Decl *From, StringRef Label) {
69 OS << "TemplateArgument";
70 if (R.isValid())
71 dumpSourceRange(R);
72
73 if (From) {
74 dumpDeclRef(From, Label);
75 }
76
77 ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
78}
79
Stephen Kelly07b76d22019-01-12 16:53:27 +000080void TextNodeDumper::Visit(const Stmt *Node) {
81 if (!Node) {
82 ColorScope Color(OS, ShowColors, NullColor);
83 OS << "<<<NULL>>>";
84 return;
85 }
86 {
87 ColorScope Color(OS, ShowColors, StmtColor);
88 OS << Node->getStmtClassName();
89 }
90 dumpPointer(Node);
91 dumpSourceRange(Node->getSourceRange());
92
93 if (const auto *E = dyn_cast<Expr>(Node)) {
94 dumpType(E->getType());
95
96 {
97 ColorScope Color(OS, ShowColors, ValueKindColor);
98 switch (E->getValueKind()) {
99 case VK_RValue:
100 break;
101 case VK_LValue:
102 OS << " lvalue";
103 break;
104 case VK_XValue:
105 OS << " xvalue";
106 break;
107 }
108 }
109
110 {
111 ColorScope Color(OS, ShowColors, ObjectKindColor);
112 switch (E->getObjectKind()) {
113 case OK_Ordinary:
114 break;
115 case OK_BitField:
116 OS << " bitfield";
117 break;
118 case OK_ObjCProperty:
119 OS << " objcproperty";
120 break;
121 case OK_ObjCSubscript:
122 OS << " objcsubscript";
123 break;
124 case OK_VectorComponent:
125 OS << " vectorcomponent";
126 break;
127 }
128 }
129 }
130
131 ConstStmtVisitor<TextNodeDumper>::Visit(Node);
132}
133
Stephen Kellyd8744a72018-12-05 21:12:39 +0000134void TextNodeDumper::dumpPointer(const void *Ptr) {
135 ColorScope Color(OS, ShowColors, AddressColor);
136 OS << ' ' << Ptr;
137}
138
139void TextNodeDumper::dumpLocation(SourceLocation Loc) {
140 if (!SM)
141 return;
142
143 ColorScope Color(OS, ShowColors, LocationColor);
144 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
145
146 // The general format we print out is filename:line:col, but we drop pieces
147 // that haven't changed since the last loc printed.
148 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
149
150 if (PLoc.isInvalid()) {
151 OS << "<invalid sloc>";
152 return;
153 }
154
155 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
156 OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
157 << PLoc.getColumn();
158 LastLocFilename = PLoc.getFilename();
159 LastLocLine = PLoc.getLine();
160 } else if (PLoc.getLine() != LastLocLine) {
161 OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
162 LastLocLine = PLoc.getLine();
163 } else {
164 OS << "col" << ':' << PLoc.getColumn();
165 }
166}
167
168void TextNodeDumper::dumpSourceRange(SourceRange R) {
169 // Can't translate locations if a SourceManager isn't available.
170 if (!SM)
171 return;
172
173 OS << " <";
174 dumpLocation(R.getBegin());
175 if (R.getBegin() != R.getEnd()) {
176 OS << ", ";
177 dumpLocation(R.getEnd());
178 }
179 OS << ">";
180
181 // <t2.c:123:421[blah], t2.c:412:321>
182}
183
184void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
185 ColorScope Color(OS, ShowColors, TypeColor);
186
187 SplitQualType T_split = T.split();
188 OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'";
189
190 if (Desugar && !T.isNull()) {
191 // If the type is sugared, also dump a (shallow) desugared type.
192 SplitQualType D_split = T.getSplitDesugaredType();
193 if (T_split != D_split)
194 OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
195 }
196}
197
198void TextNodeDumper::dumpType(QualType T) {
199 OS << ' ';
200 dumpBareType(T);
201}
202
203void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
204 if (!D) {
205 ColorScope Color(OS, ShowColors, NullColor);
206 OS << "<<<NULL>>>";
207 return;
208 }
209
210 {
211 ColorScope Color(OS, ShowColors, DeclKindNameColor);
212 OS << D->getDeclKindName();
213 }
214 dumpPointer(D);
215
216 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
217 ColorScope Color(OS, ShowColors, DeclNameColor);
218 OS << " '" << ND->getDeclName() << '\'';
219 }
220
221 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
222 dumpType(VD->getType());
223}
224
225void TextNodeDumper::dumpName(const NamedDecl *ND) {
226 if (ND->getDeclName()) {
227 ColorScope Color(OS, ShowColors, DeclNameColor);
228 OS << ' ' << ND->getNameAsString();
229 }
230}
231
232void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
233 switch (AS) {
234 case AS_none:
235 break;
236 case AS_public:
237 OS << "public";
238 break;
239 case AS_protected:
240 OS << "protected";
241 break;
242 case AS_private:
243 OS << "private";
244 break;
245 }
246}
247
248void TextNodeDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
249 OS << "(CXXTemporary";
250 dumpPointer(Temporary);
251 OS << ")";
252}
Stephen Kellye26a88a2018-12-09 13:30:17 +0000253
Stephen Kelly9bc90a22019-01-12 15:45:05 +0000254void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
Stephen Kellyd186dbc2019-01-08 23:11:24 +0000255 if (!D)
256 return;
257
Stephen Kelly12243212019-01-10 20:58:21 +0000258 AddChild([=] {
Stephen Kelly9bc90a22019-01-12 15:45:05 +0000259 if (!Label.empty())
Stephen Kellyd186dbc2019-01-08 23:11:24 +0000260 OS << Label << ' ';
261 dumpBareDeclRef(D);
262 });
263}
264
Stephen Kellye26a88a2018-12-09 13:30:17 +0000265const char *TextNodeDumper::getCommandName(unsigned CommandID) {
266 if (Traits)
267 return Traits->getCommandInfo(CommandID)->Name;
268 const comments::CommandInfo *Info =
269 comments::CommandTraits::getBuiltinCommandInfo(CommandID);
270 if (Info)
271 return Info->Name;
272 return "<not a builtin command>";
273}
274
275void TextNodeDumper::visitTextComment(const comments::TextComment *C,
276 const comments::FullComment *) {
277 OS << " Text=\"" << C->getText() << "\"";
278}
279
280void TextNodeDumper::visitInlineCommandComment(
281 const comments::InlineCommandComment *C, const comments::FullComment *) {
282 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
283 switch (C->getRenderKind()) {
284 case comments::InlineCommandComment::RenderNormal:
285 OS << " RenderNormal";
286 break;
287 case comments::InlineCommandComment::RenderBold:
288 OS << " RenderBold";
289 break;
290 case comments::InlineCommandComment::RenderMonospaced:
291 OS << " RenderMonospaced";
292 break;
293 case comments::InlineCommandComment::RenderEmphasized:
294 OS << " RenderEmphasized";
295 break;
296 }
297
298 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
299 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
300}
301
302void TextNodeDumper::visitHTMLStartTagComment(
303 const comments::HTMLStartTagComment *C, const comments::FullComment *) {
304 OS << " Name=\"" << C->getTagName() << "\"";
305 if (C->getNumAttrs() != 0) {
306 OS << " Attrs: ";
307 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
308 const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
309 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
310 }
311 }
312 if (C->isSelfClosing())
313 OS << " SelfClosing";
314}
315
316void TextNodeDumper::visitHTMLEndTagComment(
317 const comments::HTMLEndTagComment *C, const comments::FullComment *) {
318 OS << " Name=\"" << C->getTagName() << "\"";
319}
320
321void TextNodeDumper::visitBlockCommandComment(
322 const comments::BlockCommandComment *C, const comments::FullComment *) {
323 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
324 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
325 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
326}
327
328void TextNodeDumper::visitParamCommandComment(
329 const comments::ParamCommandComment *C, const comments::FullComment *FC) {
330 OS << " "
331 << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
332
333 if (C->isDirectionExplicit())
334 OS << " explicitly";
335 else
336 OS << " implicitly";
337
338 if (C->hasParamName()) {
339 if (C->isParamIndexValid())
340 OS << " Param=\"" << C->getParamName(FC) << "\"";
341 else
342 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
343 }
344
345 if (C->isParamIndexValid() && !C->isVarArgParam())
346 OS << " ParamIndex=" << C->getParamIndex();
347}
348
349void TextNodeDumper::visitTParamCommandComment(
350 const comments::TParamCommandComment *C, const comments::FullComment *FC) {
351 if (C->hasParamName()) {
352 if (C->isPositionValid())
353 OS << " Param=\"" << C->getParamName(FC) << "\"";
354 else
355 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
356 }
357
358 if (C->isPositionValid()) {
359 OS << " Position=<";
360 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
361 OS << C->getIndex(i);
362 if (i != e - 1)
363 OS << ", ";
364 }
365 OS << ">";
366 }
367}
368
369void TextNodeDumper::visitVerbatimBlockComment(
370 const comments::VerbatimBlockComment *C, const comments::FullComment *) {
371 OS << " Name=\"" << getCommandName(C->getCommandID())
372 << "\""
373 " CloseName=\""
374 << C->getCloseName() << "\"";
375}
376
377void TextNodeDumper::visitVerbatimBlockLineComment(
378 const comments::VerbatimBlockLineComment *C,
379 const comments::FullComment *) {
380 OS << " Text=\"" << C->getText() << "\"";
381}
382
383void TextNodeDumper::visitVerbatimLineComment(
384 const comments::VerbatimLineComment *C, const comments::FullComment *) {
385 OS << " Text=\"" << C->getText() << "\"";
386}
Stephen Kelly63a6f3a2019-01-12 16:35:37 +0000387
388void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
389 OS << " null";
390}
391
392void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
393 OS << " type";
394 dumpType(TA.getAsType());
395}
396
397void TextNodeDumper::VisitDeclarationTemplateArgument(
398 const TemplateArgument &TA) {
399 OS << " decl";
400 dumpDeclRef(TA.getAsDecl());
401}
402
403void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
404 OS << " nullptr";
405}
406
407void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
408 OS << " integral " << TA.getAsIntegral();
409}
410
411void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
412 OS << " template ";
413 TA.getAsTemplate().dump(OS);
414}
415
416void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
417 const TemplateArgument &TA) {
418 OS << " template expansion ";
419 TA.getAsTemplateOrTemplatePattern().dump(OS);
420}
421
422void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
423 OS << " expr";
424}
425
426void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
427 OS << " pack";
428}
Stephen Kelly07b76d22019-01-12 16:53:27 +0000429
430static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
431 if (Node->path_empty())
432 return;
433
434 OS << " (";
435 bool First = true;
436 for (CastExpr::path_const_iterator I = Node->path_begin(),
437 E = Node->path_end();
438 I != E; ++I) {
439 const CXXBaseSpecifier *Base = *I;
440 if (!First)
441 OS << " -> ";
442
443 const CXXRecordDecl *RD =
444 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
445
446 if (Base->isVirtual())
447 OS << "virtual ";
448 OS << RD->getName();
449 First = false;
450 }
451
452 OS << ')';
453}
454
455void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
456 if (Node->hasInitStorage())
457 OS << " has_init";
458 if (Node->hasVarStorage())
459 OS << " has_var";
460 if (Node->hasElseStorage())
461 OS << " has_else";
462}
463
464void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
465 if (Node->hasInitStorage())
466 OS << " has_init";
467 if (Node->hasVarStorage())
468 OS << " has_var";
469}
470
471void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
472 if (Node->hasVarStorage())
473 OS << " has_var";
474}
475
476void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
477 OS << " '" << Node->getName() << "'";
478}
479
480void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
481 OS << " '" << Node->getLabel()->getName() << "'";
482 dumpPointer(Node->getLabel());
483}
484
485void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
486 if (Node->caseStmtIsGNURange())
487 OS << " gnu_range";
488}
489
490void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
491 if (Node->usesADL())
492 OS << " adl";
493}
494
495void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
496 OS << " <";
497 {
498 ColorScope Color(OS, ShowColors, CastColor);
499 OS << Node->getCastKindName();
500 }
501 dumpBasePath(OS, Node);
502 OS << ">";
503}
504
505void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
506 VisitCastExpr(Node);
507 if (Node->isPartOfExplicitCast())
508 OS << " part_of_explicit_cast";
509}
510
511void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
512 OS << " ";
513 dumpBareDeclRef(Node->getDecl());
514 if (Node->getDecl() != Node->getFoundDecl()) {
515 OS << " (";
516 dumpBareDeclRef(Node->getFoundDecl());
517 OS << ")";
518 }
519}
520
521void TextNodeDumper::VisitUnresolvedLookupExpr(
522 const UnresolvedLookupExpr *Node) {
523 OS << " (";
524 if (!Node->requiresADL())
525 OS << "no ";
526 OS << "ADL) = '" << Node->getName() << '\'';
527
528 UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
529 E = Node->decls_end();
530 if (I == E)
531 OS << " empty";
532 for (; I != E; ++I)
533 dumpPointer(*I);
534}
535
536void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
537 {
538 ColorScope Color(OS, ShowColors, DeclKindNameColor);
539 OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
540 }
541 OS << "='" << *Node->getDecl() << "'";
542 dumpPointer(Node->getDecl());
543 if (Node->isFreeIvar())
544 OS << " isFreeIvar";
545}
546
547void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
548 OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
549}
550
551void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
552 ColorScope Color(OS, ShowColors, ValueColor);
553 OS << " " << Node->getValue();
554}
555
556void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
557 bool isSigned = Node->getType()->isSignedIntegerType();
558 ColorScope Color(OS, ShowColors, ValueColor);
559 OS << " " << Node->getValue().toString(10, isSigned);
560}
561
562void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
563 ColorScope Color(OS, ShowColors, ValueColor);
564 OS << " " << Node->getValueAsString(/*Radix=*/10);
565}
566
567void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
568 ColorScope Color(OS, ShowColors, ValueColor);
569 OS << " " << Node->getValueAsApproximateDouble();
570}
571
572void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
573 ColorScope Color(OS, ShowColors, ValueColor);
574 OS << " ";
575 Str->outputString(OS);
576}
577
578void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
579 if (auto *Field = ILE->getInitializedFieldInUnion()) {
580 OS << " field ";
581 dumpBareDeclRef(Field);
582 }
583}
584
585void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
586 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
587 << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
588 if (!Node->canOverflow())
589 OS << " cannot overflow";
590}
591
592void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
593 const UnaryExprOrTypeTraitExpr *Node) {
594 switch (Node->getKind()) {
595 case UETT_SizeOf:
596 OS << " sizeof";
597 break;
598 case UETT_AlignOf:
599 OS << " alignof";
600 break;
601 case UETT_VecStep:
602 OS << " vec_step";
603 break;
604 case UETT_OpenMPRequiredSimdAlign:
605 OS << " __builtin_omp_required_simd_align";
606 break;
607 case UETT_PreferredAlignOf:
608 OS << " __alignof";
609 break;
610 }
611 if (Node->isArgumentType())
612 dumpType(Node->getArgumentType());
613}
614
615void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
616 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
617 dumpPointer(Node->getMemberDecl());
618}
619
620void TextNodeDumper::VisitExtVectorElementExpr(
621 const ExtVectorElementExpr *Node) {
622 OS << " " << Node->getAccessor().getNameStart();
623}
624
625void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
626 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
627}
628
629void TextNodeDumper::VisitCompoundAssignOperator(
630 const CompoundAssignOperator *Node) {
631 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
632 << "' ComputeLHSTy=";
633 dumpBareType(Node->getComputationLHSType());
634 OS << " ComputeResultTy=";
635 dumpBareType(Node->getComputationResultType());
636}
637
638void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
639 OS << " " << Node->getLabel()->getName();
640 dumpPointer(Node->getLabel());
641}
642
643void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
644 OS << " " << Node->getCastName() << "<"
645 << Node->getTypeAsWritten().getAsString() << ">"
646 << " <" << Node->getCastKindName();
647 dumpBasePath(OS, Node);
648 OS << ">";
649}
650
651void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
652 OS << " " << (Node->getValue() ? "true" : "false");
653}
654
655void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
656 OS << " this";
657}
658
659void TextNodeDumper::VisitCXXFunctionalCastExpr(
660 const CXXFunctionalCastExpr *Node) {
661 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
662 << Node->getCastKindName() << ">";
663}
664
665void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
666 const CXXUnresolvedConstructExpr *Node) {
667 dumpType(Node->getTypeAsWritten());
668 if (Node->isListInitialization())
669 OS << " list";
670}
671
672void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
673 CXXConstructorDecl *Ctor = Node->getConstructor();
674 dumpType(Ctor->getType());
675 if (Node->isElidable())
676 OS << " elidable";
677 if (Node->isListInitialization())
678 OS << " list";
679 if (Node->isStdInitListInitialization())
680 OS << " std::initializer_list";
681 if (Node->requiresZeroInitialization())
682 OS << " zeroing";
683}
684
685void TextNodeDumper::VisitCXXBindTemporaryExpr(
686 const CXXBindTemporaryExpr *Node) {
687 OS << " ";
688 dumpCXXTemporary(Node->getTemporary());
689}
690
691void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
692 if (Node->isGlobalNew())
693 OS << " global";
694 if (Node->isArray())
695 OS << " array";
696 if (Node->getOperatorNew()) {
697 OS << ' ';
698 dumpBareDeclRef(Node->getOperatorNew());
699 }
700 // We could dump the deallocation function used in case of error, but it's
701 // usually not that interesting.
702}
703
704void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
705 if (Node->isGlobalDelete())
706 OS << " global";
707 if (Node->isArrayForm())
708 OS << " array";
709 if (Node->getOperatorDelete()) {
710 OS << ' ';
711 dumpBareDeclRef(Node->getOperatorDelete());
712 }
713}
714
715void TextNodeDumper::VisitMaterializeTemporaryExpr(
716 const MaterializeTemporaryExpr *Node) {
717 if (const ValueDecl *VD = Node->getExtendingDecl()) {
718 OS << " extended by ";
719 dumpBareDeclRef(VD);
720 }
721}
722
723void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
724 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
725 dumpDeclRef(Node->getObject(i), "cleanup");
726}
727
728void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
729 dumpPointer(Node->getPack());
730 dumpName(Node->getPack());
731}
732
733void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
734 const CXXDependentScopeMemberExpr *Node) {
735 OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
736}
737
738void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
739 OS << " selector=";
740 Node->getSelector().print(OS);
741 switch (Node->getReceiverKind()) {
742 case ObjCMessageExpr::Instance:
743 break;
744
745 case ObjCMessageExpr::Class:
746 OS << " class=";
747 dumpBareType(Node->getClassReceiver());
748 break;
749
750 case ObjCMessageExpr::SuperInstance:
751 OS << " super (instance)";
752 break;
753
754 case ObjCMessageExpr::SuperClass:
755 OS << " super (class)";
756 break;
757 }
758}
759
760void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
761 if (auto *BoxingMethod = Node->getBoxingMethod()) {
762 OS << " selector=";
763 BoxingMethod->getSelector().print(OS);
764 }
765}
766
767void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
768 if (!Node->getCatchParamDecl())
769 OS << " catch all";
770}
771
772void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
773 dumpType(Node->getEncodedType());
774}
775
776void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
777 OS << " ";
778 Node->getSelector().print(OS);
779}
780
781void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
782 OS << ' ' << *Node->getProtocol();
783}
784
785void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
786 if (Node->isImplicitProperty()) {
787 OS << " Kind=MethodRef Getter=\"";
788 if (Node->getImplicitPropertyGetter())
789 Node->getImplicitPropertyGetter()->getSelector().print(OS);
790 else
791 OS << "(null)";
792
793 OS << "\" Setter=\"";
794 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
795 Setter->getSelector().print(OS);
796 else
797 OS << "(null)";
798 OS << "\"";
799 } else {
800 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
801 << '"';
802 }
803
804 if (Node->isSuperReceiver())
805 OS << " super";
806
807 OS << " Messaging=";
808 if (Node->isMessagingGetter() && Node->isMessagingSetter())
809 OS << "Getter&Setter";
810 else if (Node->isMessagingGetter())
811 OS << "Getter";
812 else if (Node->isMessagingSetter())
813 OS << "Setter";
814}
815
816void TextNodeDumper::VisitObjCSubscriptRefExpr(
817 const ObjCSubscriptRefExpr *Node) {
818 if (Node->isArraySubscriptRefExpr())
819 OS << " Kind=ArraySubscript GetterForArray=\"";
820 else
821 OS << " Kind=DictionarySubscript GetterForDictionary=\"";
822 if (Node->getAtIndexMethodDecl())
823 Node->getAtIndexMethodDecl()->getSelector().print(OS);
824 else
825 OS << "(null)";
826
827 if (Node->isArraySubscriptRefExpr())
828 OS << "\" SetterForArray=\"";
829 else
830 OS << "\" SetterForDictionary=\"";
831 if (Node->setAtIndexMethodDecl())
832 Node->setAtIndexMethodDecl()->getSelector().print(OS);
833 else
834 OS << "(null)";
835}
836
837void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
838 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
839}