blob: 19d24b2f3a0329fffe9b07910c0132aa118c4bf5 [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 Gribenko3304c432012-10-25 18:16:02 +000021
22 /// The \c FullComment parent of the comment being dumped.
Fariborz Jahanian71793ef2012-10-12 17:28:36 +000023 const FullComment *FC;
Dmitri Gribenko3304c432012-10-25 18:16:02 +000024
25 unsigned IndentLevel;
26
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000027public:
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +000028 CommentDumper(raw_ostream &OS,
29 const CommandTraits *Traits,
Fariborz Jahanian71793ef2012-10-12 17:28:36 +000030 const SourceManager *SM,
Dmitri Gribenko3304c432012-10-25 18:16:02 +000031 const FullComment *FC) :
32 OS(OS), Traits(Traits), SM(SM), FC(FC), IndentLevel(0)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000033 { }
34
35 void dumpIndent() const {
36 for (unsigned i = 1, e = IndentLevel; i < e; ++i)
37 OS << " ";
38 }
39
40 void dumpLocation(SourceLocation Loc) {
41 if (SM)
42 Loc.print(OS, *SM);
43 }
44
45 void dumpSourceRange(const Comment *C);
46
47 void dumpComment(const Comment *C);
48
49 void dumpSubtree(const Comment *C);
50
51 // Inline content.
52 void visitTextComment(const TextComment *C);
53 void visitInlineCommandComment(const InlineCommandComment *C);
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +000054 void visitHTMLStartTagComment(const HTMLStartTagComment *C);
55 void visitHTMLEndTagComment(const HTMLEndTagComment *C);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000056
57 // Block content.
58 void visitParagraphComment(const ParagraphComment *C);
59 void visitBlockCommandComment(const BlockCommandComment *C);
60 void visitParamCommandComment(const ParamCommandComment *C);
Dmitri Gribenko96b09862012-07-31 22:37:06 +000061 void visitTParamCommandComment(const TParamCommandComment *C);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000062 void visitVerbatimBlockComment(const VerbatimBlockComment *C);
63 void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
64 void visitVerbatimLineComment(const VerbatimLineComment *C);
65
66 void visitFullComment(const FullComment *C);
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +000067
68 const char *getCommandName(unsigned CommandID) {
69 if (Traits)
70 return Traits->getCommandInfo(CommandID)->Name;
71 const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
72 if (Info)
73 return Info->Name;
74 return "<not a builtin command>";
75 }
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000076};
77
78void CommentDumper::dumpSourceRange(const Comment *C) {
79 if (!SM)
80 return;
81
82 SourceRange SR = C->getSourceRange();
83
84 OS << " <";
85 dumpLocation(SR.getBegin());
86 if (SR.getBegin() != SR.getEnd()) {
87 OS << ", ";
88 dumpLocation(SR.getEnd());
89 }
90 OS << ">";
91}
92
93void CommentDumper::dumpComment(const Comment *C) {
94 dumpIndent();
95 OS << "(" << C->getCommentKindName()
Dmitri Gribenkoc1093612012-07-30 17:52:50 +000096 << " " << (const void *) C;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000097 dumpSourceRange(C);
98}
99
100void CommentDumper::dumpSubtree(const Comment *C) {
101 ++IndentLevel;
102 if (C) {
103 visit(C);
104 for (Comment::child_iterator I = C->child_begin(),
105 E = C->child_end();
106 I != E; ++I) {
107 OS << '\n';
108 dumpSubtree(*I);
109 }
110 OS << ')';
111 } else {
112 dumpIndent();
113 OS << "<<<NULL>>>";
114 }
115 --IndentLevel;
116}
117
118void CommentDumper::visitTextComment(const TextComment *C) {
119 dumpComment(C);
120
121 OS << " Text=\"" << C->getText() << "\"";
122}
123
124void CommentDumper::visitInlineCommandComment(const InlineCommandComment *C) {
125 dumpComment(C);
126
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000127 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
Dmitri Gribenko2d66a502012-07-23 16:43:01 +0000128 switch (C->getRenderKind()) {
129 case InlineCommandComment::RenderNormal:
130 OS << " RenderNormal";
131 break;
132 case InlineCommandComment::RenderBold:
133 OS << " RenderBold";
134 break;
135 case InlineCommandComment::RenderMonospaced:
136 OS << " RenderMonospaced";
137 break;
138 case InlineCommandComment::RenderEmphasized:
139 OS << " RenderEmphasized";
140 break;
141 }
142
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000143 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000144 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
145}
146
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000147void CommentDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000148 dumpComment(C);
149
150 OS << " Name=\"" << C->getTagName() << "\"";
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000151 if (C->getNumAttrs() != 0) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000152 OS << " Attrs: ";
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000153 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000154 const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000155 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
156 }
157 }
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000158 if (C->isSelfClosing())
159 OS << " SelfClosing";
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000160}
161
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000162void CommentDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000163 dumpComment(C);
164
165 OS << " Name=\"" << C->getTagName() << "\"";
166}
167
168void CommentDumper::visitParagraphComment(const ParagraphComment *C) {
169 dumpComment(C);
170}
171
172void CommentDumper::visitBlockCommandComment(const BlockCommandComment *C) {
173 dumpComment(C);
174
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000175 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
Dmitri Gribenkoad29b2b2012-07-19 18:43:24 +0000176 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
177 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000178}
179
180void CommentDumper::visitParamCommandComment(const ParamCommandComment *C) {
181 dumpComment(C);
182
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000183 OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000184
185 if (C->isDirectionExplicit())
186 OS << " explicitly";
187 else
188 OS << " implicitly";
189
Fariborz Jahanian262e60c2012-10-18 21:42:42 +0000190 if (C->hasParamName()) {
191 if (C->isParamIndexValid())
Dmitri Gribenko8cfabf22012-10-19 16:51:38 +0000192 OS << " Param=\"" << C->getParamName(FC) << "\"";
Fariborz Jahanian262e60c2012-10-18 21:42:42 +0000193 else
194 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
195 }
Dmitri Gribenko72b57cc2012-07-28 00:35:48 +0000196
197 if (C->isParamIndexValid())
198 OS << " ParamIndex=" << C->getParamIndex();
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000199}
200
Dmitri Gribenko96b09862012-07-31 22:37:06 +0000201void CommentDumper::visitTParamCommandComment(const TParamCommandComment *C) {
202 dumpComment(C);
203
204 if (C->hasParamName()) {
Fariborz Jahanian262e60c2012-10-18 21:42:42 +0000205 if (C->isPositionValid())
Dmitri Gribenko8cfabf22012-10-19 16:51:38 +0000206 OS << " Param=\"" << C->getParamName(FC) << "\"";
Fariborz Jahanian262e60c2012-10-18 21:42:42 +0000207 else
208 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
Dmitri Gribenko96b09862012-07-31 22:37:06 +0000209 }
210
211 if (C->isPositionValid()) {
212 OS << " Position=<";
213 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
214 OS << C->getIndex(i);
215 if (i != e - 1)
216 OS << ", ";
217 }
218 OS << ">";
219 }
220}
221
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000222void CommentDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
223 dumpComment(C);
224
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000225 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000226 " CloseName=\"" << C->getCloseName() << "\"";
227}
228
229void CommentDumper::visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C) {
230 dumpComment(C);
231
232 OS << " Text=\"" << C->getText() << "\"";
233}
234
235void CommentDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
236 dumpComment(C);
237
238 OS << " Text=\"" << C->getText() << "\"";
239}
240
241void CommentDumper::visitFullComment(const FullComment *C) {
242 dumpComment(C);
243}
244
245} // unnamed namespace
246
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000247void Comment::dump(llvm::raw_ostream &OS, const CommandTraits *Traits,
248 const SourceManager *SM) const {
Fariborz Jahanian71793ef2012-10-12 17:28:36 +0000249 const FullComment *FC = dyn_cast<FullComment>(this);
250 CommentDumper D(llvm::errs(), Traits, SM, FC);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000251 D.dumpSubtree(this);
252 llvm::errs() << '\n';
253}
254
255} // end namespace comments
256} // end namespace clang
257