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