blob: f6fb3b1baa8a36fda50c0fbce34f2c7c280e608f [file] [log] [blame]
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +00001//===--- CommentDumper.cpp - Dumping implementation for Comment ASTs ------===//
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#include "clang/AST/CommentVisitor.h"
11#include "llvm/Support/raw_ostream.h"
12
13namespace clang {
14namespace comments {
15
16namespace {
17class CommentDumper: public comments::ConstCommentVisitor<CommentDumper> {
18 raw_ostream &OS;
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +000019 const CommandTraits *Traits;
20 const SourceManager *SM;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000021 unsigned IndentLevel;
22
23public:
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +000024 CommentDumper(raw_ostream &OS,
25 const CommandTraits *Traits,
26 const SourceManager *SM) :
27 OS(OS), Traits(Traits), SM(SM), IndentLevel(0)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000028 { }
29
30 void dumpIndent() const {
31 for (unsigned i = 1, e = IndentLevel; i < e; ++i)
32 OS << " ";
33 }
34
35 void dumpLocation(SourceLocation Loc) {
36 if (SM)
37 Loc.print(OS, *SM);
38 }
39
40 void dumpSourceRange(const Comment *C);
41
42 void dumpComment(const Comment *C);
43
44 void dumpSubtree(const Comment *C);
45
46 // Inline content.
47 void visitTextComment(const TextComment *C);
48 void visitInlineCommandComment(const InlineCommandComment *C);
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +000049 void visitHTMLStartTagComment(const HTMLStartTagComment *C);
50 void visitHTMLEndTagComment(const HTMLEndTagComment *C);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000051
52 // Block content.
53 void visitParagraphComment(const ParagraphComment *C);
54 void visitBlockCommandComment(const BlockCommandComment *C);
55 void visitParamCommandComment(const ParamCommandComment *C);
Dmitri Gribenko96b09862012-07-31 22:37:06 +000056 void visitTParamCommandComment(const TParamCommandComment *C);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000057 void visitVerbatimBlockComment(const VerbatimBlockComment *C);
58 void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
59 void visitVerbatimLineComment(const VerbatimLineComment *C);
60
61 void visitFullComment(const FullComment *C);
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +000062
63 const char *getCommandName(unsigned CommandID) {
64 if (Traits)
65 return Traits->getCommandInfo(CommandID)->Name;
66 const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
67 if (Info)
68 return Info->Name;
69 return "<not a builtin command>";
70 }
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000071};
72
73void CommentDumper::dumpSourceRange(const Comment *C) {
74 if (!SM)
75 return;
76
77 SourceRange SR = C->getSourceRange();
78
79 OS << " <";
80 dumpLocation(SR.getBegin());
81 if (SR.getBegin() != SR.getEnd()) {
82 OS << ", ";
83 dumpLocation(SR.getEnd());
84 }
85 OS << ">";
86}
87
88void CommentDumper::dumpComment(const Comment *C) {
89 dumpIndent();
90 OS << "(" << C->getCommentKindName()
Dmitri Gribenkoc1093612012-07-30 17:52:50 +000091 << " " << (const void *) C;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000092 dumpSourceRange(C);
93}
94
95void CommentDumper::dumpSubtree(const Comment *C) {
96 ++IndentLevel;
97 if (C) {
98 visit(C);
99 for (Comment::child_iterator I = C->child_begin(),
100 E = C->child_end();
101 I != E; ++I) {
102 OS << '\n';
103 dumpSubtree(*I);
104 }
105 OS << ')';
106 } else {
107 dumpIndent();
108 OS << "<<<NULL>>>";
109 }
110 --IndentLevel;
111}
112
113void CommentDumper::visitTextComment(const TextComment *C) {
114 dumpComment(C);
115
116 OS << " Text=\"" << C->getText() << "\"";
117}
118
119void CommentDumper::visitInlineCommandComment(const InlineCommandComment *C) {
120 dumpComment(C);
121
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000122 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
Dmitri Gribenko2d66a502012-07-23 16:43:01 +0000123 switch (C->getRenderKind()) {
124 case InlineCommandComment::RenderNormal:
125 OS << " RenderNormal";
126 break;
127 case InlineCommandComment::RenderBold:
128 OS << " RenderBold";
129 break;
130 case InlineCommandComment::RenderMonospaced:
131 OS << " RenderMonospaced";
132 break;
133 case InlineCommandComment::RenderEmphasized:
134 OS << " RenderEmphasized";
135 break;
136 }
137
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000138 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000139 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
140}
141
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000142void CommentDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000143 dumpComment(C);
144
145 OS << " Name=\"" << C->getTagName() << "\"";
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000146 if (C->getNumAttrs() != 0) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000147 OS << " Attrs: ";
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000148 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000149 const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000150 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
151 }
152 }
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000153 if (C->isSelfClosing())
154 OS << " SelfClosing";
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000155}
156
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000157void CommentDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000158 dumpComment(C);
159
160 OS << " Name=\"" << C->getTagName() << "\"";
161}
162
163void CommentDumper::visitParagraphComment(const ParagraphComment *C) {
164 dumpComment(C);
165}
166
167void CommentDumper::visitBlockCommandComment(const BlockCommandComment *C) {
168 dumpComment(C);
169
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000170 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
Dmitri Gribenkoad29b2b2012-07-19 18:43:24 +0000171 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
172 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000173}
174
175void CommentDumper::visitParamCommandComment(const ParamCommandComment *C) {
176 dumpComment(C);
177
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000178 OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000179
180 if (C->isDirectionExplicit())
181 OS << " explicitly";
182 else
183 OS << " implicitly";
184
Dmitri Gribenko72b57cc2012-07-28 00:35:48 +0000185 if (C->hasParamName())
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000186 OS << " Param=\"" << C->getParamName() << "\"";
Dmitri Gribenko72b57cc2012-07-28 00:35:48 +0000187
188 if (C->isParamIndexValid())
189 OS << " ParamIndex=" << C->getParamIndex();
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000190}
191
Dmitri Gribenko96b09862012-07-31 22:37:06 +0000192void CommentDumper::visitTParamCommandComment(const TParamCommandComment *C) {
193 dumpComment(C);
194
195 if (C->hasParamName()) {
196 OS << " Param=\"" << C->getParamName() << "\"";
197 }
198
199 if (C->isPositionValid()) {
200 OS << " Position=<";
201 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
202 OS << C->getIndex(i);
203 if (i != e - 1)
204 OS << ", ";
205 }
206 OS << ">";
207 }
208}
209
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000210void CommentDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
211 dumpComment(C);
212
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000213 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000214 " CloseName=\"" << C->getCloseName() << "\"";
215}
216
217void CommentDumper::visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C) {
218 dumpComment(C);
219
220 OS << " Text=\"" << C->getText() << "\"";
221}
222
223void CommentDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
224 dumpComment(C);
225
226 OS << " Text=\"" << C->getText() << "\"";
227}
228
229void CommentDumper::visitFullComment(const FullComment *C) {
230 dumpComment(C);
231}
232
233} // unnamed namespace
234
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000235void Comment::dump(llvm::raw_ostream &OS, const CommandTraits *Traits,
236 const SourceManager *SM) const {
237 CommentDumper D(llvm::errs(), Traits, SM);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000238 D.dumpSubtree(this);
239 llvm::errs() << '\n';
240}
241
242} // end namespace comments
243} // end namespace clang
244