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