summaryrefslogtreecommitdiff
path: root/clang-tools-extra/clang-doc
diff options
context:
space:
mode:
authorPaul Kirth <paulkirth@google.com>2022-11-22 19:12:58 +0000
committerPaul Kirth <paulkirth@google.com>2022-11-22 19:14:54 +0000
commit48bb1471122d156bc0c4feaabc32de4487024ca5 (patch)
treebc7da0877c899d323b45f7eee42698c01f4a40fe /clang-tools-extra/clang-doc
parent1f515f30d0083ec0d74f0d9885e614f758f12687 (diff)
downloadllvm-48bb1471122d156bc0c4feaabc32de4487024ca5.tar.gz
Revert "[clang-doc] Move file layout to the generators."
This reverts commit f8a469fc572778d05b72f34a772082cf3abd3cda. The test in single-file-public.cpp breaks on Mac, due to an unknown regextype in the find command.
Diffstat (limited to 'clang-tools-extra/clang-doc')
-rw-r--r--clang-tools-extra/clang-doc/Generators.h14
-rw-r--r--clang-tools-extra/clang-doc/HTMLGenerator.cpp59
-rw-r--r--clang-tools-extra/clang-doc/MDGenerator.cpp53
-rw-r--r--clang-tools-extra/clang-doc/YAMLGenerator.cpp36
-rw-r--r--clang-tools-extra/clang-doc/tool/ClangDocMain.cpp101
5 files changed, 76 insertions, 187 deletions
diff --git a/clang-tools-extra/clang-doc/Generators.h b/clang-tools-extra/clang-doc/Generators.h
index ba0ef64d3d0f..89c6b34c4384 100644
--- a/clang-tools-extra/clang-doc/Generators.h
+++ b/clang-tools-extra/clang-doc/Generators.h
@@ -25,23 +25,15 @@ class Generator {
public:
virtual ~Generator() = default;
- // Write out the decl info for the objects in the given map in the specified
- // format.
- virtual llvm::Error
- generateDocs(StringRef RootDir,
- llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
- const ClangDocContext &CDCtx) = 0;
-
+ // Write out the decl info in the specified format.
+ virtual llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+ const ClangDocContext &CDCtx) = 0;
// This function writes a file with the index previously constructed.
// It can be overwritten by any of the inherited generators.
// If the override method wants to run this it should call
// Generator::createResources(CDCtx);
virtual llvm::Error createResources(ClangDocContext &CDCtx);
- // Write out one specific decl info to the destination stream.
- virtual llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
- const ClangDocContext &CDCtx) = 0;
-
static void addInfoToIndex(Index &Idx, const doc::Info *Info);
};
diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
index 11a78ba60e35..6f1d45551bc7 100644
--- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
@@ -11,7 +11,6 @@
#include "clang/Basic/Version.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSet.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/Path.h"
@@ -840,69 +839,13 @@ class HTMLGenerator : public Generator {
public:
static const char *Format;
- llvm::Error generateDocs(StringRef RootDir,
- llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
- const ClangDocContext &CDCtx) override;
- llvm::Error createResources(ClangDocContext &CDCtx) override;
llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
const ClangDocContext &CDCtx) override;
+ llvm::Error createResources(ClangDocContext &CDCtx) override;
};
const char *HTMLGenerator::Format = "html";
-llvm::Error
-HTMLGenerator::generateDocs(StringRef RootDir,
- llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
- const ClangDocContext &CDCtx) {
- // Track which directories we already tried to create.
- llvm::StringSet<> CreatedDirs;
-
- // Collect all output by file name and create the nexessary directories.
- llvm::StringMap<std::vector<doc::Info *>> FileToInfos;
- for (const auto &Group : Infos) {
- doc::Info *Info = Group.getValue().get();
-
- llvm::SmallString<128> Path;
- llvm::sys::path::native(RootDir, Path);
- llvm::sys::path::append(Path, Info->getRelativeFilePath(""));
- if (CreatedDirs.find(Path) == CreatedDirs.end()) {
- if (std::error_code Err = llvm::sys::fs::create_directories(Path);
- Err != std::error_code()) {
- return llvm::createStringError(Err, "Failed to create directory '%s'.",
- Path.c_str());
- }
- CreatedDirs.insert(Path);
- }
-
- llvm::sys::path::append(Path, Info->getFileBaseName() + ".html");
- FileToInfos[Path].push_back(Info);
- }
-
- for (const auto &Group : FileToInfos) {
- std::error_code FileErr;
- llvm::raw_fd_ostream InfoOS(Group.getKey(), FileErr,
- llvm::sys::fs::OF_None);
- if (FileErr) {
- return llvm::createStringError(FileErr, "Error opening file '%s'",
- Group.getKey().str().c_str());
- }
-
- // TODO: https://github.com/llvm/llvm-project/issues/59073
- // If there are multiple Infos for this file name (for example, template
- // specializations), this will generate multiple complete web pages (with
- // <DOCTYPE> and <title>, etc.) concatenated together. This generator needs
- // some refactoring to be able to output the headers separately from the
- // contents.
- for (const auto &Info : Group.getValue()) {
- if (llvm::Error Err = generateDocForInfo(Info, InfoOS, CDCtx)) {
- return Err;
- }
- }
- }
-
- return llvm::Error::success();
-}
-
llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
const ClangDocContext &CDCtx) {
std::string InfoTitle;
diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp
index 8261e14c3efb..0c5f16304598 100644
--- a/clang-tools-extra/clang-doc/MDGenerator.cpp
+++ b/clang-tools-extra/clang-doc/MDGenerator.cpp
@@ -356,69 +356,18 @@ static llvm::Error genIndex(ClangDocContext &CDCtx) {
}
return llvm::Error::success();
}
-
/// Generator for Markdown documentation.
class MDGenerator : public Generator {
public:
static const char *Format;
- llvm::Error generateDocs(StringRef RootDir,
- llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
- const ClangDocContext &CDCtx) override;
- llvm::Error createResources(ClangDocContext &CDCtx) override;
llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
const ClangDocContext &CDCtx) override;
+ llvm::Error createResources(ClangDocContext &CDCtx) override;
};
const char *MDGenerator::Format = "md";
-llvm::Error
-MDGenerator::generateDocs(StringRef RootDir,
- llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
- const ClangDocContext &CDCtx) {
- // Track which directories we already tried to create.
- llvm::StringSet<> CreatedDirs;
-
- // Collect all output by file name and create the necessary directories.
- llvm::StringMap<std::vector<doc::Info *>> FileToInfos;
- for (const auto &Group : Infos) {
- doc::Info *Info = Group.getValue().get();
-
- llvm::SmallString<128> Path;
- llvm::sys::path::native(RootDir, Path);
- llvm::sys::path::append(Path, Info->getRelativeFilePath(""));
- if (CreatedDirs.find(Path) == CreatedDirs.end()) {
- if (std::error_code Err = llvm::sys::fs::create_directories(Path);
- Err != std::error_code()) {
- return llvm::createStringError(Err, "Failed to create directory '%s'.",
- Path.c_str());
- }
- CreatedDirs.insert(Path);
- }
-
- llvm::sys::path::append(Path, Info->getFileBaseName() + ".md");
- FileToInfos[Path].push_back(Info);
- }
-
- for (const auto &Group : FileToInfos) {
- std::error_code FileErr;
- llvm::raw_fd_ostream InfoOS(Group.getKey(), FileErr,
- llvm::sys::fs::OF_None);
- if (FileErr) {
- return llvm::createStringError(FileErr, "Error opening file '%s'",
- Group.getKey().str().c_str());
- }
-
- for (const auto &Info : Group.getValue()) {
- if (llvm::Error Err = generateDocForInfo(Info, InfoOS, CDCtx)) {
- return Err;
- }
- }
- }
-
- return llvm::Error::success();
-}
-
llvm::Error MDGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
const ClangDocContext &CDCtx) {
switch (I->IT) {
diff --git a/clang-tools-extra/clang-doc/YAMLGenerator.cpp b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
index b54486102ccc..fcca0a60a944 100644
--- a/clang-tools-extra/clang-doc/YAMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
@@ -292,48 +292,12 @@ class YAMLGenerator : public Generator {
public:
static const char *Format;
- llvm::Error generateDocs(StringRef RootDir,
- llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
- const ClangDocContext &CDCtx) override;
llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
const ClangDocContext &CDCtx) override;
};
const char *YAMLGenerator::Format = "yaml";
-llvm::Error
-YAMLGenerator::generateDocs(StringRef RootDir,
- llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
- const ClangDocContext &CDCtx) {
- for (const auto &Group : Infos) {
- doc::Info *Info = Group.getValue().get();
-
- // Output file names according to the USR except the global namesapce.
- // Anonymous namespaces are taken care of in serialization, so here we can
- // safely assume an unnamed namespace is the global one.
- llvm::SmallString<128> Path;
- llvm::sys::path::native(RootDir, Path);
- if (Info->IT == InfoType::IT_namespace && Info->Name.empty()) {
- llvm::sys::path::append(Path, "index.yaml");
- } else {
- llvm::sys::path::append(Path, Group.getKey() + ".yaml");
- }
-
- std::error_code FileErr;
- llvm::raw_fd_ostream InfoOS(Path, FileErr, llvm::sys::fs::OF_None);
- if (FileErr) {
- return llvm::createStringError(FileErr, "Error opening file '%s'",
- Path.c_str());
- }
-
- if (llvm::Error Err = generateDocForInfo(Info, InfoOS, CDCtx)) {
- return Err;
- }
- }
-
- return llvm::Error::success();
-}
-
llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
const ClangDocContext &CDCtx) {
llvm::yaml::Output InfoYAML(OS);
diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 83bfea027bbc..7531f219a6a4 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -43,7 +43,6 @@
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/raw_ostream.h"
#include <atomic>
-#include <mutex>
#include <string>
using namespace clang::ast_matchers;
@@ -131,6 +130,54 @@ std::string GetExecutablePath(const char *Argv0, void *MainAddr) {
return llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
}
+bool CreateDirectory(const Twine &DirName, bool ClearDirectory = false) {
+ std::error_code OK;
+ llvm::SmallString<128> DocsRootPath;
+ if (ClearDirectory) {
+ std::error_code RemoveStatus = llvm::sys::fs::remove_directories(DirName);
+ if (RemoveStatus != OK) {
+ llvm::errs() << "Unable to remove existing documentation directory for "
+ << DirName << ".\n";
+ return true;
+ }
+ }
+ std::error_code DirectoryStatus = llvm::sys::fs::create_directories(DirName);
+ if (DirectoryStatus != OK) {
+ llvm::errs() << "Unable to create documentation directories.\n";
+ return true;
+ }
+ return false;
+}
+
+// A function to extract the appropriate file name for a given info's
+// documentation. The path returned is a composite of the output directory, the
+// info's relative path and name and the extension. The relative path should
+// have been constructed in the serialization phase.
+//
+// Example: Given the below, the <ext> path for class C will be
+// <root>/A/B/C.<ext>
+//
+// namespace A {
+// namespace B {
+//
+// class C {};
+//
+// }
+// }
+llvm::Expected<llvm::SmallString<128>> getInfoOutputFile(StringRef Root,
+ StringRef RelativePath,
+ StringRef Name,
+ StringRef Ext) {
+ llvm::SmallString<128> Path;
+ llvm::sys::path::native(Root, Path);
+ llvm::sys::path::append(Path, RelativePath);
+ if (CreateDirectory(Path))
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "failed to create directory");
+ llvm::sys::path::append(Path, Name + Ext);
+ return Path;
+}
+
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
std::error_code OK;
@@ -227,11 +274,6 @@ Example usage for a project using a compile commands database:
R.first->second.emplace_back(Value);
});
- // Collects all Infos according to their unique USR value. This map is added
- // to from the thread pool below and is protected by the USRToInfoMutex.
- llvm::sys::Mutex USRToInfoMutex;
- llvm::StringMap<std::unique_ptr<doc::Info>> USRToInfo;
-
// First reducing phase (reduce all decls into one info per decl).
llvm::outs() << "Reducing " << USRToBitcode.size() << " infos...\n";
std::atomic<bool> Error;
@@ -262,17 +304,31 @@ Example usage for a project using a compile commands database:
return;
}
- // Add a reference to this Info in the Index
- {
- std::lock_guard Guard(IndexMutex);
- clang::doc::Generator::addInfoToIndex(CDCtx.Idx, Reduced.get().get());
+ doc::Info *I = Reduced.get().get();
+ auto InfoPath =
+ getInfoOutputFile(OutDirectory, I->getRelativeFilePath(""),
+ I->getFileBaseName(), "." + Format);
+ if (!InfoPath) {
+ llvm::errs() << toString(InfoPath.takeError()) << "\n";
+ Error = true;
+ return;
}
-
- // Save in the result map (needs a lock due to threaded access).
- {
- std::lock_guard Guard(USRToInfoMutex);
- USRToInfo[Group.getKey()] = std::move(Reduced.get());
+ std::error_code FileErr;
+ llvm::raw_fd_ostream InfoOS(InfoPath.get(), FileErr,
+ llvm::sys::fs::OF_None);
+ if (FileErr) {
+ llvm::errs() << "Error opening info file " << InfoPath.get() << ": "
+ << FileErr.message() << "\n";
+ return;
}
+
+ IndexMutex.lock();
+ // Add a reference to this Info in the Index
+ clang::doc::Generator::addInfoToIndex(CDCtx.Idx, I);
+ IndexMutex.unlock();
+
+ if (auto Err = G->get()->generateDocForInfo(I, InfoOS, CDCtx))
+ llvm::errs() << toString(std::move(Err)) << "\n";
});
}
@@ -281,21 +337,6 @@ Example usage for a project using a compile commands database:
if (Error)
return 1;
- // Ensure the root output directory exists.
- if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory);
- Err != std::error_code()) {
- llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n";
- return 1;
- }
-
- // Run the generator.
- llvm::outs() << "Generating docs...\n";
- if (auto Err =
- G->get()->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)) {
- llvm::errs() << toString(std::move(Err)) << "\n";
- return 1;
- }
-
llvm::outs() << "Generating assets for docs...\n";
Err = G->get()->createResources(CDCtx);
if (Err) {