juliehockett updated this revision to Diff 127053.
juliehockett marked 8 inline comments as done.
https://reviews.llvm.org/D41102
Files:
tools/CMakeLists.txt
tools/clang-doc/CMakeLists.txt
tools/clang-doc/ClangDoc.cpp
tools/clang-doc/ClangDoc.h
tools/clang-doc/ClangDocReporter.cpp
tools/clang-doc/ClangDocReporter.h
tools/clang-doc/tool/CMakeLists.txt
tools/clang-doc/tool/ClangDocMain.cpp
Index: tools/clang-doc/tool/ClangDocMain.cpp
===================================================================
--- /dev/null
+++ tools/clang-doc/tool/ClangDocMain.cpp
@@ -0,0 +1,68 @@
+//===-- ClangDocMain.cpp - Clangdoc -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangDoc.h"
+#include "clang/Driver/Options.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Tooling/CommonOptionsParser.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
+#include <string>
+
+using namespace clang;
+using namespace llvm;
+
+namespace {
+
+cl::OptionCategory ClangDocCategory("clang-doc options");
+
+cl::opt<bool>
+ EmitLLVM("emit-llvm",
+ cl::desc("Output in LLVM bitstream format (default is YAML)."),
+ cl::init(false), cl::cat(ClangDocCategory));
+
+cl::opt<bool>
+ DoxygenOnly("doxygen",
+ cl::desc("Use only doxygen-style comments to generate docs."),
+ cl::init(false), cl::cat(ClangDocCategory));
+
+} // namespace
+
+int main(int argc, const char **argv) {
+ sys::PrintStackTraceOnErrorSignal(argv[0]);
+ tooling::CommonOptionsParser OptionsParser(argc, argv, ClangDocCategory);
+
+ clang::doc::OutFormat EmitFormat = EmitLLVM ? clang::doc::OutFormat::LLVM
+ : clang::doc::OutFormat::YAML;
+
+ // TODO: Update the source path list to only consider changed files for
+ // incremental doc updates.
+ doc::ClangDocReporter Reporter(OptionsParser.getSourcePathList());
+ doc::ClangDocContext Context{EmitFormat};
+
+ tooling::ClangTool Tool(OptionsParser.getCompilations(),
+ OptionsParser.getSourcePathList());
+
+ if (!DoxygenOnly)
+ Tool.appendArgumentsAdjuster(tooling::getInsertArgumentAdjuster(
+ "-fparse-all-comments", tooling::ArgumentInsertPosition::BEGIN));
+
+ doc::ClangDocActionFactory Factory(Context, Reporter);
+
+ outs() << "Parsing codebase...\n";
+ int Status = Tool.run(&Factory);
+ if (Status)
+ return Status;
+
+ outs() << "Writing docs...\n";
+ Reporter.serialize(EmitFormat, outs());
+
+ return 0;
+}
Index: tools/clang-doc/tool/CMakeLists.txt
===================================================================
--- /dev/null
+++ tools/clang-doc/tool/CMakeLists.txt
@@ -0,0 +1,18 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..)
+
+add_clang_executable(clang-doc
+ ClangDocMain.cpp
+ )
+
+target_link_libraries(clang-doc
+ PRIVATE
+ clangAST
+ clangASTMatchers
+ clangBasic
+ clangFormat
+ clangFrontend
+ clangDoc
+ clangRewrite
+ clangTooling
+ clangToolingCore
+ )
Index: tools/clang-doc/ClangDocReporter.h
===================================================================
--- /dev/null
+++ tools/clang-doc/ClangDocReporter.h
@@ -0,0 +1,117 @@
+//===-- Doc.cpp - ClangDoc --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_CLANG_DOC_REPORTER_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_CLANG_DOC_REPORTER_H
+
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CommentVisitor.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/raw_ostream.h"
+#include <iterator>
+#include <set>
+#include <string>
+#include <vector>
+
+using namespace clang::comments;
+
+namespace clang {
+namespace doc {
+
+enum class OutFormat { YAML, LLVM };
+
+struct StringPair {
+ std::string Key;
+ std::string Value;
+};
+
+struct CommentInfo {
+ std::string Kind;
+ std::string Text;
+ std::string Name;
+ std::string Direction;
+ std::string ParamName;
+ std::string CloseName;
+ bool SelfClosing = false;
+ bool Explicit = false;
+ llvm::StringMap<std::string> Attrs;
+ llvm::SmallVector<std::string, 8> Args;
+ llvm::SmallVector<int, 8> Position;
+ std::vector<CommentInfo> Children;
+};
+
+// TODO: collect declarations of the same object, comment is preferentially:
+// 1) docstring on definition, 2) combined docstring from non-def decls, or
+// 3) comment on definition, 4) no comment.
+struct DeclInfo {
+ const Decl *D;
+ std::string QualifiedName;
+ CommentInfo Comment;
+};
+
+struct FileRecord {
+ std::string Filename;
+ std::vector<DeclInfo> Decls;
+ std::vector<CommentInfo> UnattachedComments;
+};
+
+class ClangDocReporter : public ConstCommentVisitor<ClangDocReporter> {
+public:
+ ClangDocReporter(const std::vector<std::string> &SourcePathList);
+
+ void addComment(StringRef Filename, const CommentInfo &CI);
+ void addDecl(StringRef Filename, const DeclInfo &D);
+ void addFile(StringRef Filename);
+ void addFileInTU(StringRef Filename) { FilesInThisTU.insert(Filename); }
+ void addFileSeen(StringRef Filename) { FilesSeen.insert(Filename); }
+ void clearFilesInThisTU() { FilesInThisTU.clear(); };
+
+ void visitTextComment(const TextComment *C);
+ void visitInlineCommandComment(const InlineCommandComment *C);
+ void visitHTMLStartTagComment(const HTMLStartTagComment *C);
+ void visitHTMLEndTagComment(const HTMLEndTagComment *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);
+
+ CommentInfo parseFullComment(const comments::FullComment *Comment);
+
+ const std::set<std::string> &getFilesInThisTU() const {
+ return FilesInThisTU;
+ }
+ bool hasFile(StringRef Filename) const;
+ bool hasSeenFile(StringRef Filename) const;
+ void serialize(clang::doc::OutFormat Format, llvm::raw_ostream &OS) const;
+
+private:
+ void parseComment(CommentInfo *CI, const comments::Comment *C);
+ void serializeYAML(llvm::raw_ostream &OS) const;
+ void serializeLLVM(llvm::raw_ostream &OS) const;
+ const char *getCommandName(unsigned CommandID);
+ bool isWhitespaceOnly(StringRef S);
+
+ CommentInfo *CurrentCI;
+ llvm::StringMap<FileRecord> FileRecords;
+ std::set<std::string> FilesInThisTU;
+ std::set<std::string> FilesSeen;
+};
+
+} // namespace doc
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_CLANG_DOC_REPORTER_H
Index: tools/clang-doc/ClangDocReporter.cpp
===================================================================
--- /dev/null
+++ tools/clang-doc/ClangDocReporter.cpp
@@ -0,0 +1,261 @@
+//===-- Doc.cpp - ClangDoc --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangDocReporter.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CommentVisitor.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::tooling;
+using namespace llvm;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::doc::DeclInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::doc::CommentInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(clang::doc::StringPair)
+
+namespace llvm {
+namespace yaml {
+
+template <> struct MappingTraits<clang::doc::StringPair> {
+ static void mapping(IO &IO, clang::doc::StringPair &Pair) {
+ IO.mapRequired("Key", Pair.Key);
+ IO.mapRequired("Value", Pair.Value);
+ }
+};
+
+template <> struct MappingTraits<clang::doc::FileRecord> {
+ static void mapping(IO &IO, clang::doc::FileRecord &Info) {
+ IO.mapRequired("Filename", Info.Filename);
+ IO.mapRequired("Decls", Info.Decls);
+ IO.mapRequired("UnattachedComments", Info.UnattachedComments);
+ }
+};
+
+template <> struct MappingTraits<clang::doc::DeclInfo> {
+ static void mapping(IO &IO, clang::doc::DeclInfo &Info) {
+ IO.mapRequired("Name", Info.QualifiedName);
+ IO.mapRequired("Comment", Info.Comment);
+ }
+};
+
+template <> struct MappingTraits<clang::doc::CommentInfo> {
+
+ struct NormalizedStringMap {
+ NormalizedStringMap(IO &) {}
+ NormalizedStringMap(IO &, const StringMap<std::string> &Map) {
+ for (const auto &Entry : Map) {
+ clang::doc::StringPair Pair{Entry.getKeyData(), Entry.getValue()};
+ VectorMap.push_back(Pair);
+ }
+ }
+
+ StringMap<std::string> denormalize(IO &) {
+ StringMap<std::string> Map;
+ for (const auto &Pair : VectorMap)
+ Map[Pair.Key] = Pair.Value;
+ return Map;
+ }
+
+ std::vector<clang::doc::StringPair> VectorMap;
+ };
+
+ static void mapping(IO &IO, clang::doc::CommentInfo &Info) {
+ MappingNormalization<NormalizedStringMap, StringMap<std::string>>
+ keys(IO, Info.Attrs);
+
+ IO.mapRequired("Kind", Info.Kind);
+ if (!Info.Text.empty())
+ IO.mapOptional("Text", Info.Text);
+ if (!Info.Name.empty())
+ IO.mapOptional("Text", Info.Name);
+ if (!Info.Direction.empty())
+ IO.mapOptional("Direction", Info.Direction);
+ if (!Info.ParamName.empty())
+ IO.mapOptional("ParamName", Info.ParamName);
+ if (!Info.CloseName.empty())
+ IO.mapOptional("CloseName", Info.CloseName);
+ if (Info.SelfClosing)
+ IO.mapOptional("SelfClosing", Info.SelfClosing);
+ if (Info.Explicit)
+ IO.mapOptional("Explicit", Info.Explicit);
+ if (Info.Args.size() > 0)
+ IO.mapOptional("Args", Info.Args);
+ if (Info.Attrs.size() > 0)
+ IO.mapOptional("Attrs", keys->VectorMap);
+ if (Info.Position.size() > 0)
+ IO.mapOptional("Position", Info.Position);
+ if (Info.Children.size() > 0)
+ IO.mapOptional("Children", Info.Children);
+ }
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+namespace clang {
+namespace doc {
+
+ClangDocReporter::ClangDocReporter(
+ const std::vector<std::string> &SourcePathList) {
+ for (const std::string &Path : SourcePathList)
+ addFile(Path);
+}
+
+void ClangDocReporter::addComment(StringRef Filename, const CommentInfo &CI) {
+ FileRecords[Filename].UnattachedComments.push_back(CI);
+}
+
+void ClangDocReporter::addDecl(StringRef Filename, const DeclInfo &DI) {
+ FileRecords[Filename].Decls.push_back(DI);
+}
+
+void ClangDocReporter::addFile(StringRef Filename) {
+ FileRecord FI;
+ FI.Filename = Filename;
+ FileRecords.insert(std::make_pair(Filename, FI));
+}
+
+CommentInfo
+ClangDocReporter::parseFullComment(const comments::FullComment *Comment) {
+ CommentInfo CI;
+ parseComment(&CI, Comment);
+ return CI;
+}
+
+void ClangDocReporter::visitTextComment(const TextComment *C) {
+ if (!isWhitespaceOnly(C->getText()))
+ CurrentCI->Text = C->getText();
+}
+
+void ClangDocReporter::visitInlineCommandComment(
+ const InlineCommandComment *C) {
+ CurrentCI->Name = getCommandName(C->getCommandID());
+ for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
+ CurrentCI->Args.push_back(C->getArgText(i));
+}
+
+void ClangDocReporter::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
+ CurrentCI->Name = C->getTagName();
+ CurrentCI->SelfClosing = C->isSelfClosing();
+ for (unsigned i = 0, e = C->getNumAttrs(); i < e; ++i) {
+ const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
+ CurrentCI->Attrs.insert(std::make_pair(Attr.Name, Attr.Value));
+ }
+}
+
+void ClangDocReporter::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
+ CurrentCI->Name = C->getTagName();
+ CurrentCI->SelfClosing = true;
+}
+
+void ClangDocReporter::visitBlockCommandComment(const BlockCommandComment *C) {
+ CurrentCI->Name = getCommandName(C->getCommandID());
+ for (unsigned i = 0, e = C->getNumArgs(); i < e; ++i)
+ CurrentCI->Args.push_back(C->getArgText(i));
+}
+
+void ClangDocReporter::visitParamCommandComment(const ParamCommandComment *C) {
+ CurrentCI->Direction =
+ ParamCommandComment::getDirectionAsString(C->getDirection());
+ CurrentCI->Explicit = C->isDirectionExplicit();
+ if (C->hasParamName() && C->isParamIndexValid())
+ CurrentCI->ParamName = C->getParamNameAsWritten();
+}
+
+void ClangDocReporter::visitTParamCommandComment(
+ const TParamCommandComment *C) {
+ if (C->hasParamName() && C->isPositionValid())
+ CurrentCI->ParamName = C->getParamNameAsWritten();
+
+ if (C->isPositionValid()) {
+ for (unsigned i = 0, e = C->getDepth(); i < e; ++i)
+ CurrentCI->Position.push_back(C->getIndex(i));
+ }
+}
+
+void ClangDocReporter::visitVerbatimBlockComment(
+ const VerbatimBlockComment *C) {
+ CurrentCI->Name = getCommandName(C->getCommandID());
+ CurrentCI->CloseName = C->getCloseName();
+}
+
+void ClangDocReporter::visitVerbatimBlockLineComment(
+ const VerbatimBlockLineComment *C) {
+ if (!isWhitespaceOnly(C->getText()))
+ CurrentCI->Text = C->getText();
+}
+
+void ClangDocReporter::visitVerbatimLineComment(const VerbatimLineComment *C) {
+ if (!isWhitespaceOnly(C->getText()))
+ CurrentCI->Text = C->getText();
+}
+
+bool ClangDocReporter::hasFile(StringRef Filename) const {
+ return FileRecords.find(Filename) != FileRecords.end();
+}
+
+bool ClangDocReporter::hasSeenFile(StringRef Filename) const {
+ return FilesSeen.find(Filename) != FilesSeen.end();
+}
+
+void ClangDocReporter::serialize(clang::doc::OutFormat Format,
+ raw_ostream &OS) const {
+ Format == clang::doc::OutFormat::LLVM ? serializeLLVM(OS) : serializeYAML(OS);
+}
+
+void ClangDocReporter::parseComment(CommentInfo *CI,
+ const comments::Comment *C) {
+ CurrentCI = CI;
+ CI->Kind = C->getCommentKindName();
+ ConstCommentVisitor<ClangDocReporter>::visit(C);
+ for (comments::Comment *Child :
+ make_range(C->child_begin(), C->child_end())) {
+ CommentInfo ChildCI;
+ parseComment(&ChildCI, Child);
+ CI->Children.push_back(ChildCI);
+ }
+}
+
+void ClangDocReporter::serializeYAML(raw_ostream &OS) const {
+ yaml::Output Output(OS);
+ for (const auto &F : FileRecords) {
+ FileRecord NonConstValue = F.second;
+ Output << NonConstValue;
+ }
+}
+
+void ClangDocReporter::serializeLLVM(raw_ostream &OS) const {
+ // TODO: Implement.
+ OS << "Not yet implemented.\n";
+}
+
+const char *ClangDocReporter::getCommandName(unsigned CommandID) {
+ const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
+ if (Info)
+ return Info->Name;
+ // TODO: Add parsing for \file command.
+ return "<not a builtin command>";
+}
+
+bool ClangDocReporter::isWhitespaceOnly(StringRef S) {
+ return S.find_first_not_of(" \t\n\v\f\r") == std::string::npos || S.empty();
+}
+
+} // namespace doc
+} // namespace clang
Index: tools/clang-doc/ClangDoc.h
===================================================================
--- /dev/null
+++ tools/clang-doc/ClangDoc.h
@@ -0,0 +1,90 @@
+//===-- ClangDoc.cpp - ClangDoc ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_CLANGDOC_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_CLANGDOC_H
+
+#include "ClangDocReporter.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Tooling/Tooling.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace doc {
+
+// A Context which contains extra options which are used in ClangMoveTool.
+struct ClangDocContext {
+ // Which format to emit representation in.
+ OutFormat EmitFormat;
+};
+
+class ClangDocVisitor : public RecursiveASTVisitor<ClangDocVisitor> {
+public:
+ explicit ClangDocVisitor(ASTContext *Context, ClangDocReporter &Reporter)
+ : Context(Context), Reporter(Reporter) {}
+
+ bool VisitNamedDecl(const NamedDecl *D);
+
+ void parseUnattachedComments();
+ bool parseNewDecl(const NamedDecl *D);
+ bool isNewComment(SourceLocation Loc, const SourceManager &Manager) const;
+
+private:
+ ASTContext *Context;
+ ClangDocReporter &Reporter;
+};
+
+class ClangDocConsumer : public clang::ASTConsumer {
+public:
+ explicit ClangDocConsumer(ASTContext *Context, ClangDocReporter &Reporter)
+ : Visitor(Context, Reporter), Reporter(Reporter) {}
+
+ virtual void HandleTranslationUnit(clang::ASTContext &Context);
+
+private:
+ ClangDocVisitor Visitor;
+ ClangDocReporter &Reporter;
+};
+
+class ClangDocAction : public clang::ASTFrontendAction {
+public:
+ ClangDocAction(ClangDocReporter &Reporter) : Reporter(Reporter) {}
+
+ virtual std::unique_ptr<clang::ASTConsumer>
+ CreateASTConsumer(clang::CompilerInstance &Compiler, llvm::StringRef InFile);
+ virtual void EndSourceFileAction();
+
+private:
+ ClangDocReporter &Reporter;
+};
+
+class ClangDocActionFactory : public tooling::FrontendActionFactory {
+public:
+ ClangDocActionFactory(ClangDocContext &Context, ClangDocReporter &Reporter)
+ : Context(Context), Reporter(Reporter) {}
+
+ clang::FrontendAction *create() override {
+ return new ClangDocAction(Reporter);
+ }
+
+private:
+ ClangDocContext &Context;
+ ClangDocReporter &Reporter;
+};
+
+} // namespace doc
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_CLANGDOC_H
Index: tools/clang-doc/ClangDoc.cpp
===================================================================
--- /dev/null
+++ tools/clang-doc/ClangDoc.cpp
@@ -0,0 +1,97 @@
+//===-- ClangDoc.cpp - ClangDoc ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangDoc.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Comment.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Tooling/Tooling.h"
+
+using namespace clang;
+using namespace clang::tooling;
+using namespace llvm;
+
+namespace clang {
+namespace doc {
+
+// TODO: limit to functions/objects/namespaces/etc?
+bool ClangDocVisitor::VisitNamedDecl(const NamedDecl *D) {
+ return parseNewDecl(D);
+}
+
+void ClangDocVisitor::parseUnattachedComments() {
+ const SourceManager &Manager = Context->getSourceManager();
+ for (RawComment *Comment : Context->getRawCommentList().getComments()) {
+ if (!isNewComment(Comment->getLocStart(), Manager) || Comment->isAttached())
+ continue;
+ CommentInfo CI =
+ Reporter.parseFullComment(Comment->parse(*Context, nullptr, nullptr));
+ Reporter.addComment(Manager.getFilename(Comment->getLocStart()), CI);
+ }
+}
+
+bool ClangDocVisitor::parseNewDecl(const NamedDecl *D) {
+ const SourceManager &Manager = Context->getSourceManager();
+ if (!isNewComment(D->getLocation(), Manager))
+ return true;
+
+ DeclInfo DI;
+ DI.D = D;
+ DI.QualifiedName = D->getQualifiedNameAsString();
+ RawComment *Comment = Context->getRawCommentForDeclNoCache(D);
+
+ // TODO: Move setAttached to the initial comment parsing.
+ if (Comment) {
+ Comment->setAttached();
+ DI.Comment =
+ Reporter.parseFullComment(Comment->parse(*Context, nullptr, D));
+ }
+ Reporter.addDecl(Manager.getFilename(D->getLocation()), DI);
+ return true;
+}
+
+bool ClangDocVisitor::isNewComment(SourceLocation Loc,
+ const SourceManager &Manager) const {
+ if (!Loc.isValid())
+ return false;
+ const std::string &Filename = Manager.getFilename(Loc);
+ if (!Reporter.hasFile(Filename) || Reporter.hasSeenFile(Filename))
+ return false;
+ if (Manager.isInSystemHeader(Loc) || Manager.isInExternCSystemHeader(Loc))
+ return false;
+ Reporter.addFileInTU(Filename);
+ return true;
+}
+
+void ClangDocConsumer::HandleTranslationUnit(ASTContext &Context) {
+ Visitor.TraverseDecl(Context.getTranslationUnitDecl());
+ Visitor.parseUnattachedComments();
+}
+
+std::unique_ptr<ASTConsumer>
+ClangDocAction::CreateASTConsumer(CompilerInstance &Compiler,
+ StringRef InFile) {
+ return make_unique<ClangDocConsumer>(&Compiler.getASTContext(),
+ Reporter);
+}
+
+void ClangDocAction::EndSourceFileAction() {
+ for (const auto &Filename : Reporter.getFilesInThisTU()) {
+ Reporter.addFileSeen(Filename);
+ }
+ Reporter.clearFilesInThisTU();
+}
+
+} // namespace doc
+} // namespace clang
Index: tools/clang-doc/CMakeLists.txt
===================================================================
--- /dev/null
+++ tools/clang-doc/CMakeLists.txt
@@ -0,0 +1,21 @@
+set(LLVM_LINK_COMPONENTS
+ support
+ )
+
+add_clang_library(clangDoc
+ ClangDoc.cpp
+ ClangDocReporter.cpp
+
+ LINK_LIBS
+ clangAnalysis
+ clangAST
+ clangASTMatchers
+ clangBasic
+ clangFormat
+ clangFrontend
+ clangLex
+ clangTooling
+ clangToolingCore
+ )
+
+add_subdirectory(tool)
Index: tools/CMakeLists.txt
===================================================================
--- tools/CMakeLists.txt
+++ tools/CMakeLists.txt
@@ -3,6 +3,7 @@
add_clang_subdirectory(diagtool)
add_clang_subdirectory(driver)
add_clang_subdirectory(clang-diff)
+add_clang_subdirectory(clang-doc)
add_clang_subdirectory(clang-format)
add_clang_subdirectory(clang-format-vs)
add_clang_subdirectory(clang-fuzzer)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits