blob: 27d8f253935368d72641ffa5ab99a260167770bc [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)
22 : OS(OS), ShowColors(ShowColors), SM(SM), PrintPolicy(PrintPolicy),
23 Traits(Traits) {}
24
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
44void TextNodeDumper::dumpPointer(const void *Ptr) {
45 ColorScope Color(OS, ShowColors, AddressColor);
46 OS << ' ' << Ptr;
47}
48
49void TextNodeDumper::dumpLocation(SourceLocation Loc) {
50 if (!SM)
51 return;
52
53 ColorScope Color(OS, ShowColors, LocationColor);
54 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
55
56 // The general format we print out is filename:line:col, but we drop pieces
57 // that haven't changed since the last loc printed.
58 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
59
60 if (PLoc.isInvalid()) {
61 OS << "<invalid sloc>";
62 return;
63 }
64
65 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
66 OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
67 << PLoc.getColumn();
68 LastLocFilename = PLoc.getFilename();
69 LastLocLine = PLoc.getLine();
70 } else if (PLoc.getLine() != LastLocLine) {
71 OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
72 LastLocLine = PLoc.getLine();
73 } else {
74 OS << "col" << ':' << PLoc.getColumn();
75 }
76}
77
78void TextNodeDumper::dumpSourceRange(SourceRange R) {
79 // Can't translate locations if a SourceManager isn't available.
80 if (!SM)
81 return;
82
83 OS << " <";
84 dumpLocation(R.getBegin());
85 if (R.getBegin() != R.getEnd()) {
86 OS << ", ";
87 dumpLocation(R.getEnd());
88 }
89 OS << ">";
90
91 // <t2.c:123:421[blah], t2.c:412:321>
92}
93
94void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
95 ColorScope Color(OS, ShowColors, TypeColor);
96
97 SplitQualType T_split = T.split();
98 OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'";
99
100 if (Desugar && !T.isNull()) {
101 // If the type is sugared, also dump a (shallow) desugared type.
102 SplitQualType D_split = T.getSplitDesugaredType();
103 if (T_split != D_split)
104 OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
105 }
106}
107
108void TextNodeDumper::dumpType(QualType T) {
109 OS << ' ';
110 dumpBareType(T);
111}
112
113void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
114 if (!D) {
115 ColorScope Color(OS, ShowColors, NullColor);
116 OS << "<<<NULL>>>";
117 return;
118 }
119
120 {
121 ColorScope Color(OS, ShowColors, DeclKindNameColor);
122 OS << D->getDeclKindName();
123 }
124 dumpPointer(D);
125
126 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
127 ColorScope Color(OS, ShowColors, DeclNameColor);
128 OS << " '" << ND->getDeclName() << '\'';
129 }
130
131 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
132 dumpType(VD->getType());
133}
134
135void TextNodeDumper::dumpName(const NamedDecl *ND) {
136 if (ND->getDeclName()) {
137 ColorScope Color(OS, ShowColors, DeclNameColor);
138 OS << ' ' << ND->getNameAsString();
139 }
140}
141
142void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
143 switch (AS) {
144 case AS_none:
145 break;
146 case AS_public:
147 OS << "public";
148 break;
149 case AS_protected:
150 OS << "protected";
151 break;
152 case AS_private:
153 OS << "private";
154 break;
155 }
156}
157
158void TextNodeDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
159 OS << "(CXXTemporary";
160 dumpPointer(Temporary);
161 OS << ")";
162}
Stephen Kellye26a88a2018-12-09 13:30:17 +0000163
164const char *TextNodeDumper::getCommandName(unsigned CommandID) {
165 if (Traits)
166 return Traits->getCommandInfo(CommandID)->Name;
167 const comments::CommandInfo *Info =
168 comments::CommandTraits::getBuiltinCommandInfo(CommandID);
169 if (Info)
170 return Info->Name;
171 return "<not a builtin command>";
172}
173
174void TextNodeDumper::visitTextComment(const comments::TextComment *C,
175 const comments::FullComment *) {
176 OS << " Text=\"" << C->getText() << "\"";
177}
178
179void TextNodeDumper::visitInlineCommandComment(
180 const comments::InlineCommandComment *C, const comments::FullComment *) {
181 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
182 switch (C->getRenderKind()) {
183 case comments::InlineCommandComment::RenderNormal:
184 OS << " RenderNormal";
185 break;
186 case comments::InlineCommandComment::RenderBold:
187 OS << " RenderBold";
188 break;
189 case comments::InlineCommandComment::RenderMonospaced:
190 OS << " RenderMonospaced";
191 break;
192 case comments::InlineCommandComment::RenderEmphasized:
193 OS << " RenderEmphasized";
194 break;
195 }
196
197 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
198 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
199}
200
201void TextNodeDumper::visitHTMLStartTagComment(
202 const comments::HTMLStartTagComment *C, const comments::FullComment *) {
203 OS << " Name=\"" << C->getTagName() << "\"";
204 if (C->getNumAttrs() != 0) {
205 OS << " Attrs: ";
206 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
207 const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
208 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
209 }
210 }
211 if (C->isSelfClosing())
212 OS << " SelfClosing";
213}
214
215void TextNodeDumper::visitHTMLEndTagComment(
216 const comments::HTMLEndTagComment *C, const comments::FullComment *) {
217 OS << " Name=\"" << C->getTagName() << "\"";
218}
219
220void TextNodeDumper::visitBlockCommandComment(
221 const comments::BlockCommandComment *C, const comments::FullComment *) {
222 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
223 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
224 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
225}
226
227void TextNodeDumper::visitParamCommandComment(
228 const comments::ParamCommandComment *C, const comments::FullComment *FC) {
229 OS << " "
230 << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
231
232 if (C->isDirectionExplicit())
233 OS << " explicitly";
234 else
235 OS << " implicitly";
236
237 if (C->hasParamName()) {
238 if (C->isParamIndexValid())
239 OS << " Param=\"" << C->getParamName(FC) << "\"";
240 else
241 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
242 }
243
244 if (C->isParamIndexValid() && !C->isVarArgParam())
245 OS << " ParamIndex=" << C->getParamIndex();
246}
247
248void TextNodeDumper::visitTParamCommandComment(
249 const comments::TParamCommandComment *C, const comments::FullComment *FC) {
250 if (C->hasParamName()) {
251 if (C->isPositionValid())
252 OS << " Param=\"" << C->getParamName(FC) << "\"";
253 else
254 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
255 }
256
257 if (C->isPositionValid()) {
258 OS << " Position=<";
259 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
260 OS << C->getIndex(i);
261 if (i != e - 1)
262 OS << ", ";
263 }
264 OS << ">";
265 }
266}
267
268void TextNodeDumper::visitVerbatimBlockComment(
269 const comments::VerbatimBlockComment *C, const comments::FullComment *) {
270 OS << " Name=\"" << getCommandName(C->getCommandID())
271 << "\""
272 " CloseName=\""
273 << C->getCloseName() << "\"";
274}
275
276void TextNodeDumper::visitVerbatimBlockLineComment(
277 const comments::VerbatimBlockLineComment *C,
278 const comments::FullComment *) {
279 OS << " Text=\"" << C->getText() << "\"";
280}
281
282void TextNodeDumper::visitVerbatimLineComment(
283 const comments::VerbatimLineComment *C, const comments::FullComment *) {
284 OS << " Text=\"" << C->getText() << "\"";
285}