• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   unsigned IndentLevel;
22 
23 public:
CommentDumper(raw_ostream & OS,const CommandTraits * Traits,const SourceManager * SM)24   CommentDumper(raw_ostream &OS,
25                 const CommandTraits *Traits,
26                 const SourceManager *SM) :
27       OS(OS), Traits(Traits), SM(SM), IndentLevel(0)
28   { }
29 
dumpIndent() const30   void dumpIndent() const {
31     for (unsigned i = 1, e = IndentLevel; i < e; ++i)
32       OS << "  ";
33   }
34 
dumpLocation(SourceLocation Loc)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);
49   void visitHTMLStartTagComment(const HTMLStartTagComment *C);
50   void visitHTMLEndTagComment(const HTMLEndTagComment *C);
51 
52   // Block content.
53   void visitParagraphComment(const ParagraphComment *C);
54   void visitBlockCommandComment(const BlockCommandComment *C);
55   void visitParamCommandComment(const ParamCommandComment *C);
56   void visitTParamCommandComment(const TParamCommandComment *C);
57   void visitVerbatimBlockComment(const VerbatimBlockComment *C);
58   void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
59   void visitVerbatimLineComment(const VerbatimLineComment *C);
60 
61   void visitFullComment(const FullComment *C);
62 
getCommandName(unsigned CommandID)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   }
71 };
72 
dumpSourceRange(const Comment * C)73 void 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 
dumpComment(const Comment * C)88 void CommentDumper::dumpComment(const Comment *C) {
89   dumpIndent();
90   OS << "(" << C->getCommentKindName()
91      << " " << (const void *) C;
92   dumpSourceRange(C);
93 }
94 
dumpSubtree(const Comment * C)95 void 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 
visitTextComment(const TextComment * C)113 void CommentDumper::visitTextComment(const TextComment *C) {
114   dumpComment(C);
115 
116   OS << " Text=\"" << C->getText() << "\"";
117 }
118 
visitInlineCommandComment(const InlineCommandComment * C)119 void CommentDumper::visitInlineCommandComment(const InlineCommandComment *C) {
120   dumpComment(C);
121 
122   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
123   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 
138   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
139     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
140 }
141 
visitHTMLStartTagComment(const HTMLStartTagComment * C)142 void CommentDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
143   dumpComment(C);
144 
145   OS << " Name=\"" << C->getTagName() << "\"";
146   if (C->getNumAttrs() != 0) {
147     OS << " Attrs: ";
148     for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
149       const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
150       OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
151     }
152   }
153   if (C->isSelfClosing())
154     OS << " SelfClosing";
155 }
156 
visitHTMLEndTagComment(const HTMLEndTagComment * C)157 void CommentDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
158   dumpComment(C);
159 
160   OS << " Name=\"" << C->getTagName() << "\"";
161 }
162 
visitParagraphComment(const ParagraphComment * C)163 void CommentDumper::visitParagraphComment(const ParagraphComment *C) {
164   dumpComment(C);
165 }
166 
visitBlockCommandComment(const BlockCommandComment * C)167 void CommentDumper::visitBlockCommandComment(const BlockCommandComment *C) {
168   dumpComment(C);
169 
170   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
171   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
172     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
173 }
174 
visitParamCommandComment(const ParamCommandComment * C)175 void CommentDumper::visitParamCommandComment(const ParamCommandComment *C) {
176   dumpComment(C);
177 
178   OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
179 
180   if (C->isDirectionExplicit())
181     OS << " explicitly";
182   else
183     OS << " implicitly";
184 
185   if (C->hasParamName())
186     OS << " Param=\"" << C->getParamName() << "\"";
187 
188   if (C->isParamIndexValid())
189     OS << " ParamIndex=" << C->getParamIndex();
190 }
191 
visitTParamCommandComment(const TParamCommandComment * C)192 void 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 
visitVerbatimBlockComment(const VerbatimBlockComment * C)210 void CommentDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
211   dumpComment(C);
212 
213   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
214         " CloseName=\"" << C->getCloseName() << "\"";
215 }
216 
visitVerbatimBlockLineComment(const VerbatimBlockLineComment * C)217 void CommentDumper::visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C) {
218   dumpComment(C);
219 
220   OS << " Text=\"" << C->getText() << "\"";
221 }
222 
visitVerbatimLineComment(const VerbatimLineComment * C)223 void CommentDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
224   dumpComment(C);
225 
226   OS << " Text=\"" << C->getText() << "\"";
227 }
228 
visitFullComment(const FullComment * C)229 void CommentDumper::visitFullComment(const FullComment *C) {
230   dumpComment(C);
231 }
232 
233 } // unnamed namespace
234 
dump(llvm::raw_ostream & OS,const CommandTraits * Traits,const SourceManager * SM) const235 void Comment::dump(llvm::raw_ostream &OS, const CommandTraits *Traits,
236                    const SourceManager *SM) const {
237   CommentDumper D(llvm::errs(), Traits, SM);
238   D.dumpSubtree(this);
239   llvm::errs() << '\n';
240 }
241 
242 } // end namespace comments
243 } // end namespace clang
244 
245