]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/lib/AST/CommentDumper.cpp
MFC r244628:
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / lib / AST / CommentDumper.cpp
1 //===--- 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
13 namespace clang {
14 namespace comments {
15
16 namespace {
17 class CommentDumper: public comments::ConstCommentVisitor<CommentDumper> {
18   raw_ostream &OS;
19   const CommandTraits *Traits;
20   const SourceManager *SM;
21
22   /// The \c FullComment parent of the comment being dumped.
23   const FullComment *FC;
24
25   unsigned IndentLevel;
26
27 public:
28   CommentDumper(raw_ostream &OS,
29                 const CommandTraits *Traits,
30                 const SourceManager *SM,
31                 const FullComment *FC) :
32       OS(OS), Traits(Traits), SM(SM), FC(FC), IndentLevel(0)
33   { }
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);
54   void visitHTMLStartTagComment(const HTMLStartTagComment *C);
55   void visitHTMLEndTagComment(const HTMLEndTagComment *C);
56
57   // Block content.
58   void visitParagraphComment(const ParagraphComment *C);
59   void visitBlockCommandComment(const BlockCommandComment *C);
60   void visitParamCommandComment(const ParamCommandComment *C);
61   void visitTParamCommandComment(const TParamCommandComment *C);
62   void visitVerbatimBlockComment(const VerbatimBlockComment *C);
63   void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
64   void visitVerbatimLineComment(const VerbatimLineComment *C);
65
66   void visitFullComment(const FullComment *C);
67
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   }
76 };
77
78 void 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
93 void CommentDumper::dumpComment(const Comment *C) {
94   dumpIndent();
95   OS << "(" << C->getCommentKindName()
96      << " " << (const void *) C;
97   dumpSourceRange(C);
98 }
99
100 void 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
118 void CommentDumper::visitTextComment(const TextComment *C) {
119   dumpComment(C);
120
121   OS << " Text=\"" << C->getText() << "\"";
122 }
123
124 void CommentDumper::visitInlineCommandComment(const InlineCommandComment *C) {
125   dumpComment(C);
126
127   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
128   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
143   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
144     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
145 }
146
147 void CommentDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
148   dumpComment(C);
149
150   OS << " Name=\"" << C->getTagName() << "\"";
151   if (C->getNumAttrs() != 0) {
152     OS << " Attrs: ";
153     for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
154       const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
155       OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
156     }
157   }
158   if (C->isSelfClosing())
159     OS << " SelfClosing";
160 }
161
162 void CommentDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
163   dumpComment(C);
164
165   OS << " Name=\"" << C->getTagName() << "\"";
166 }
167
168 void CommentDumper::visitParagraphComment(const ParagraphComment *C) {
169   dumpComment(C);
170 }
171
172 void CommentDumper::visitBlockCommandComment(const BlockCommandComment *C) {
173   dumpComment(C);
174
175   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
176   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
177     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
178 }
179
180 void CommentDumper::visitParamCommandComment(const ParamCommandComment *C) {
181   dumpComment(C);
182
183   OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
184
185   if (C->isDirectionExplicit())
186     OS << " explicitly";
187   else
188     OS << " implicitly";
189
190   if (C->hasParamName()) {
191     if (C->isParamIndexValid())
192       OS << " Param=\"" << C->getParamName(FC) << "\"";
193     else
194       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
195   }
196
197   if (C->isParamIndexValid())
198     OS << " ParamIndex=" << C->getParamIndex();
199 }
200
201 void CommentDumper::visitTParamCommandComment(const TParamCommandComment *C) {
202   dumpComment(C);
203
204   if (C->hasParamName()) {
205     if (C->isPositionValid())
206       OS << " Param=\"" << C->getParamName(FC) << "\"";
207     else
208       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
209   }
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
222 void CommentDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
223   dumpComment(C);
224
225   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
226         " CloseName=\"" << C->getCloseName() << "\"";
227 }
228
229 void CommentDumper::visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C) {
230   dumpComment(C);
231
232   OS << " Text=\"" << C->getText() << "\"";
233 }
234
235 void CommentDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
236   dumpComment(C);
237
238   OS << " Text=\"" << C->getText() << "\"";
239 }
240
241 void CommentDumper::visitFullComment(const FullComment *C) {
242   dumpComment(C);
243 }
244
245 } // unnamed namespace
246
247 void Comment::dump(llvm::raw_ostream &OS, const CommandTraits *Traits,
248                    const SourceManager *SM) const {
249   const FullComment *FC = dyn_cast<FullComment>(this);
250   CommentDumper D(llvm::errs(), Traits, SM, FC);
251   D.dumpSubtree(this);
252   llvm::errs() << '\n';
253 }
254
255 } // end namespace comments
256 } // end namespace clang
257