| //===--- CommentDumper.cpp - Dumping implementation for Comment ASTs ------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "clang/AST/CommentVisitor.h" |
| #include "llvm/Support/raw_ostream.h" |
| |
| namespace clang { |
| namespace comments { |
| |
| namespace { |
| class CommentDumper: public comments::ConstCommentVisitor<CommentDumper> { |
| raw_ostream &OS; |
| const CommandTraits *Traits; |
| const SourceManager *SM; |
| unsigned IndentLevel; |
| |
| public: |
| CommentDumper(raw_ostream &OS, |
| const CommandTraits *Traits, |
| const SourceManager *SM) : |
| OS(OS), Traits(Traits), SM(SM), IndentLevel(0) |
| { } |
| |
| void dumpIndent() const { |
| for (unsigned i = 1, e = IndentLevel; i < e; ++i) |
| OS << " "; |
| } |
| |
| void dumpLocation(SourceLocation Loc) { |
| if (SM) |
| Loc.print(OS, *SM); |
| } |
| |
| void dumpSourceRange(const Comment *C); |
| |
| void dumpComment(const Comment *C); |
| |
| void dumpSubtree(const Comment *C); |
| |
| // Inline content. |
| void visitTextComment(const TextComment *C); |
| void visitInlineCommandComment(const InlineCommandComment *C); |
| void visitHTMLStartTagComment(const HTMLStartTagComment *C); |
| void visitHTMLEndTagComment(const HTMLEndTagComment *C); |
| |
| // Block content. |
| void visitParagraphComment(const ParagraphComment *C); |
| void visitBlockCommandComment(const BlockCommandComment *C); |
| void visitParamCommandComment(const ParamCommandComment *C); |
| void visitTParamCommandComment(const TParamCommandComment *C); |
| void visitVerbatimBlockComment(const VerbatimBlockComment *C); |
| void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C); |
| void visitVerbatimLineComment(const VerbatimLineComment *C); |
| |
| void visitFullComment(const FullComment *C); |
| |
| const char *getCommandName(unsigned CommandID) { |
| if (Traits) |
| return Traits->getCommandInfo(CommandID)->Name; |
| const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID); |
| if (Info) |
| return Info->Name; |
| return "<not a builtin command>"; |
| } |
| }; |
| |
| void CommentDumper::dumpSourceRange(const Comment *C) { |
| if (!SM) |
| return; |
| |
| SourceRange SR = C->getSourceRange(); |
| |
| OS << " <"; |
| dumpLocation(SR.getBegin()); |
| if (SR.getBegin() != SR.getEnd()) { |
| OS << ", "; |
| dumpLocation(SR.getEnd()); |
| } |
| OS << ">"; |
| } |
| |
| void CommentDumper::dumpComment(const Comment *C) { |
| dumpIndent(); |
| OS << "(" << C->getCommentKindName() |
| << " " << (const void *) C; |
| dumpSourceRange(C); |
| } |
| |
| void CommentDumper::dumpSubtree(const Comment *C) { |
| ++IndentLevel; |
| if (C) { |
| visit(C); |
| for (Comment::child_iterator I = C->child_begin(), |
| E = C->child_end(); |
| I != E; ++I) { |
| OS << '\n'; |
| dumpSubtree(*I); |
| } |
| OS << ')'; |
| } else { |
| dumpIndent(); |
| OS << "<<<NULL>>>"; |
| } |
| --IndentLevel; |
| } |
| |
| void CommentDumper::visitTextComment(const TextComment *C) { |
| dumpComment(C); |
| |
| OS << " Text=\"" << C->getText() << "\""; |
| } |
| |
| void CommentDumper::visitInlineCommandComment(const InlineCommandComment *C) { |
| dumpComment(C); |
| |
| OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; |
| switch (C->getRenderKind()) { |
| case InlineCommandComment::RenderNormal: |
| OS << " RenderNormal"; |
| break; |
| case InlineCommandComment::RenderBold: |
| OS << " RenderBold"; |
| break; |
| case InlineCommandComment::RenderMonospaced: |
| OS << " RenderMonospaced"; |
| break; |
| case InlineCommandComment::RenderEmphasized: |
| OS << " RenderEmphasized"; |
| break; |
| } |
| |
| for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) |
| OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; |
| } |
| |
| void CommentDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) { |
| dumpComment(C); |
| |
| OS << " Name=\"" << C->getTagName() << "\""; |
| if (C->getNumAttrs() != 0) { |
| OS << " Attrs: "; |
| for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { |
| const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); |
| OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; |
| } |
| } |
| if (C->isSelfClosing()) |
| OS << " SelfClosing"; |
| } |
| |
| void CommentDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) { |
| dumpComment(C); |
| |
| OS << " Name=\"" << C->getTagName() << "\""; |
| } |
| |
| void CommentDumper::visitParagraphComment(const ParagraphComment *C) { |
| dumpComment(C); |
| } |
| |
| void CommentDumper::visitBlockCommandComment(const BlockCommandComment *C) { |
| dumpComment(C); |
| |
| OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; |
| for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) |
| OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; |
| } |
| |
| void CommentDumper::visitParamCommandComment(const ParamCommandComment *C) { |
| dumpComment(C); |
| |
| OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection()); |
| |
| if (C->isDirectionExplicit()) |
| OS << " explicitly"; |
| else |
| OS << " implicitly"; |
| |
| if (C->hasParamName()) |
| OS << " Param=\"" << C->getParamName() << "\""; |
| |
| if (C->isParamIndexValid()) |
| OS << " ParamIndex=" << C->getParamIndex(); |
| } |
| |
| void CommentDumper::visitTParamCommandComment(const TParamCommandComment *C) { |
| dumpComment(C); |
| |
| if (C->hasParamName()) { |
| OS << " Param=\"" << C->getParamName() << "\""; |
| } |
| |
| if (C->isPositionValid()) { |
| OS << " Position=<"; |
| for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { |
| OS << C->getIndex(i); |
| if (i != e - 1) |
| OS << ", "; |
| } |
| OS << ">"; |
| } |
| } |
| |
| void CommentDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) { |
| dumpComment(C); |
| |
| OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"" |
| " CloseName=\"" << C->getCloseName() << "\""; |
| } |
| |
| void CommentDumper::visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C) { |
| dumpComment(C); |
| |
| OS << " Text=\"" << C->getText() << "\""; |
| } |
| |
| void CommentDumper::visitVerbatimLineComment(const VerbatimLineComment *C) { |
| dumpComment(C); |
| |
| OS << " Text=\"" << C->getText() << "\""; |
| } |
| |
| void CommentDumper::visitFullComment(const FullComment *C) { |
| dumpComment(C); |
| } |
| |
| } // unnamed namespace |
| |
| void Comment::dump(llvm::raw_ostream &OS, const CommandTraits *Traits, |
| const SourceManager *SM) const { |
| CommentDumper D(llvm::errs(), Traits, SM); |
| D.dumpSubtree(this); |
| llvm::errs() << '\n'; |
| } |
| |
| } // end namespace comments |
| } // end namespace clang |
| |