blob: 18d3406217bf2d372411811f6bcfe061fbbedaf8 [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;
Fariborz Jahanian71793ef2012-10-12 17:28:36 +000022 const FullComment *FC;
23
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000024public:
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +000025 CommentDumper(raw_ostream &OS,
26 const CommandTraits *Traits,
Fariborz Jahanian71793ef2012-10-12 17:28:36 +000027 const SourceManager *SM,
28 const FullComment * FC) :
29 OS(OS), Traits(Traits), SM(SM), IndentLevel(0),
30 FC(FC)
31
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000032 { }
33
34 void dumpIndent() const {
35 for (unsigned i = 1, e = IndentLevel; i < e; ++i)
36 OS << " ";
37 }
38
39 void dumpLocation(SourceLocation Loc) {
40 if (SM)
41 Loc.print(OS, *SM);
42 }
43
44 void dumpSourceRange(const Comment *C);
45
46 void dumpComment(const Comment *C);
47
48 void dumpSubtree(const Comment *C);
49
50 // Inline content.
51 void visitTextComment(const TextComment *C);
52 void visitInlineCommandComment(const InlineCommandComment *C);
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +000053 void visitHTMLStartTagComment(const HTMLStartTagComment *C);
54 void visitHTMLEndTagComment(const HTMLEndTagComment *C);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000055
56 // Block content.
57 void visitParagraphComment(const ParagraphComment *C);
58 void visitBlockCommandComment(const BlockCommandComment *C);
59 void visitParamCommandComment(const ParamCommandComment *C);
Dmitri Gribenko96b09862012-07-31 22:37:06 +000060 void visitTParamCommandComment(const TParamCommandComment *C);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000061 void visitVerbatimBlockComment(const VerbatimBlockComment *C);
62 void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
63 void visitVerbatimLineComment(const VerbatimLineComment *C);
64
65 void visitFullComment(const FullComment *C);
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +000066
67 const char *getCommandName(unsigned CommandID) {
68 if (Traits)
69 return Traits->getCommandInfo(CommandID)->Name;
70 const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
71 if (Info)
72 return Info->Name;
73 return "<not a builtin command>";
74 }
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000075};
76
77void CommentDumper::dumpSourceRange(const Comment *C) {
78 if (!SM)
79 return;
80
81 SourceRange SR = C->getSourceRange();
82
83 OS << " <";
84 dumpLocation(SR.getBegin());
85 if (SR.getBegin() != SR.getEnd()) {
86 OS << ", ";
87 dumpLocation(SR.getEnd());
88 }
89 OS << ">";
90}
91
92void CommentDumper::dumpComment(const Comment *C) {
93 dumpIndent();
94 OS << "(" << C->getCommentKindName()
Dmitri Gribenkoc1093612012-07-30 17:52:50 +000095 << " " << (const void *) C;
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +000096 dumpSourceRange(C);
97}
98
99void CommentDumper::dumpSubtree(const Comment *C) {
100 ++IndentLevel;
101 if (C) {
102 visit(C);
103 for (Comment::child_iterator I = C->child_begin(),
104 E = C->child_end();
105 I != E; ++I) {
106 OS << '\n';
107 dumpSubtree(*I);
108 }
109 OS << ')';
110 } else {
111 dumpIndent();
112 OS << "<<<NULL>>>";
113 }
114 --IndentLevel;
115}
116
117void CommentDumper::visitTextComment(const TextComment *C) {
118 dumpComment(C);
119
120 OS << " Text=\"" << C->getText() << "\"";
121}
122
123void CommentDumper::visitInlineCommandComment(const InlineCommandComment *C) {
124 dumpComment(C);
125
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000126 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
Dmitri Gribenko2d66a502012-07-23 16:43:01 +0000127 switch (C->getRenderKind()) {
128 case InlineCommandComment::RenderNormal:
129 OS << " RenderNormal";
130 break;
131 case InlineCommandComment::RenderBold:
132 OS << " RenderBold";
133 break;
134 case InlineCommandComment::RenderMonospaced:
135 OS << " RenderMonospaced";
136 break;
137 case InlineCommandComment::RenderEmphasized:
138 OS << " RenderEmphasized";
139 break;
140 }
141
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000142 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000143 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
144}
145
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000146void CommentDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000147 dumpComment(C);
148
149 OS << " Name=\"" << C->getTagName() << "\"";
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000150 if (C->getNumAttrs() != 0) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000151 OS << " Attrs: ";
Dmitri Gribenko0eaf69d2012-07-13 19:02:42 +0000152 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000153 const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000154 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
155 }
156 }
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000157 if (C->isSelfClosing())
158 OS << " SelfClosing";
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000159}
160
Dmitri Gribenko3f38bf22012-07-13 00:44:24 +0000161void CommentDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000162 dumpComment(C);
163
164 OS << " Name=\"" << C->getTagName() << "\"";
165}
166
167void CommentDumper::visitParagraphComment(const ParagraphComment *C) {
168 dumpComment(C);
169}
170
171void CommentDumper::visitBlockCommandComment(const BlockCommandComment *C) {
172 dumpComment(C);
173
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000174 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
Dmitri Gribenkoad29b2b2012-07-19 18:43:24 +0000175 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
176 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000177}
178
179void CommentDumper::visitParamCommandComment(const ParamCommandComment *C) {
180 dumpComment(C);
181
Dmitri Gribenkoa5ef44f2012-07-11 21:38:39 +0000182 OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000183
184 if (C->isDirectionExplicit())
185 OS << " explicitly";
186 else
187 OS << " implicitly";
188
Fariborz Jahanian262e60c2012-10-18 21:42:42 +0000189 if (C->hasParamName()) {
190 if (C->isParamIndexValid())
Dmitri Gribenko8cfabf22012-10-19 16:51:38 +0000191 OS << " Param=\"" << C->getParamName(FC) << "\"";
Fariborz Jahanian262e60c2012-10-18 21:42:42 +0000192 else
193 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
194 }
Dmitri Gribenko72b57cc2012-07-28 00:35:48 +0000195
196 if (C->isParamIndexValid())
197 OS << " ParamIndex=" << C->getParamIndex();
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000198}
199
Dmitri Gribenko96b09862012-07-31 22:37:06 +0000200void CommentDumper::visitTParamCommandComment(const TParamCommandComment *C) {
201 dumpComment(C);
202
203 if (C->hasParamName()) {
Fariborz Jahanian262e60c2012-10-18 21:42:42 +0000204 if (C->isPositionValid())
Dmitri Gribenko8cfabf22012-10-19 16:51:38 +0000205 OS << " Param=\"" << C->getParamName(FC) << "\"";
Fariborz Jahanian262e60c2012-10-18 21:42:42 +0000206 else
207 OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
Dmitri Gribenko96b09862012-07-31 22:37:06 +0000208 }
209
210 if (C->isPositionValid()) {
211 OS << " Position=<";
212 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
213 OS << C->getIndex(i);
214 if (i != e - 1)
215 OS << ", ";
216 }
217 OS << ">";
218 }
219}
220
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000221void CommentDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
222 dumpComment(C);
223
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000224 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000225 " CloseName=\"" << C->getCloseName() << "\"";
226}
227
228void CommentDumper::visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C) {
229 dumpComment(C);
230
231 OS << " Text=\"" << C->getText() << "\"";
232}
233
234void CommentDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
235 dumpComment(C);
236
237 OS << " Text=\"" << C->getText() << "\"";
238}
239
240void CommentDumper::visitFullComment(const FullComment *C) {
241 dumpComment(C);
242}
243
244} // unnamed namespace
245
Dmitri Gribenkoe4330a32012-09-10 20:32:42 +0000246void Comment::dump(llvm::raw_ostream &OS, const CommandTraits *Traits,
247 const SourceManager *SM) const {
Fariborz Jahanian71793ef2012-10-12 17:28:36 +0000248 const FullComment *FC = dyn_cast<FullComment>(this);
249 CommentDumper D(llvm::errs(), Traits, SM, FC);
Dmitri Gribenko8d3ba232012-07-06 00:28:32 +0000250 D.dumpSubtree(this);
251 llvm::errs() << '\n';
252}
253
254} // end namespace comments
255} // end namespace clang
256