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 13namespace clang { 14namespace comments { 15 16namespace { 17class CommentDumper: public comments::ConstCommentVisitor<CommentDumper> { 18 raw_ostream &OS; 19 const CommandTraits *Traits; 20 const SourceManager *SM; 21 unsigned IndentLevel; 22 23public: 24 CommentDumper(raw_ostream &OS, 25 const CommandTraits *Traits, 26 const SourceManager *SM) : 27 OS(OS), Traits(Traits), SM(SM), IndentLevel(0) 28 { } 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); 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 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 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() 91 << " " << (const void *) C; 92 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 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 142void 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 157void CommentDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) { 158 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 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 175void 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 192void 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 210void CommentDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) { 211 dumpComment(C); 212 213 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"" 214 " 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 235void 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