summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra')
-rw-r--r--clang-tools-extra/clang-doc/Generators.h3
-rw-r--r--clang-tools-extra/clang-doc/HTMLGenerator.cpp62
-rw-r--r--clang-tools-extra/clang-doc/MDGenerator.cpp6
-rw-r--r--clang-tools-extra/clang-doc/Representation.h2
-rw-r--r--clang-tools-extra/clang-doc/YAMLGenerator.cpp6
-rw-r--r--clang-tools-extra/clang-doc/tool/ClangDocMain.cpp29
-rw-r--r--clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp26
-rw-r--r--clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp10
-rw-r--r--clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp10
9 files changed, 104 insertions, 50 deletions
diff --git a/clang-tools-extra/clang-doc/Generators.h b/clang-tools-extra/clang-doc/Generators.h
index 5e6d02901a3..978cabad3a3 100644
--- a/clang-tools-extra/clang-doc/Generators.h
+++ b/clang-tools-extra/clang-doc/Generators.h
@@ -26,7 +26,8 @@ public:
virtual ~Generator() = default;
// Write out the decl info in the specified format.
- virtual llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) = 0;
+ virtual llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+ const ClangDocContext &CDCtx) = 0;
virtual bool createResources(ClangDocContext CDCtx) = 0;
};
diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
index 819fce2abc6..56ed9769a18 100644
--- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
@@ -222,6 +222,21 @@ static SmallString<128> computeRelativePath(StringRef FilePath,
// HTML generation
+std::vector<std::unique_ptr<TagNode>>
+genStylesheetsHTML(StringRef InfoPath, const ClangDocContext &CDCtx) {
+ std::vector<std::unique_ptr<TagNode>> Out;
+ for (const auto &FilePath : CDCtx.UserStylesheets) {
+ auto LinkNode = llvm::make_unique<TagNode>(HTMLTag::TAG_LINK);
+ LinkNode->Attributes.try_emplace("rel", "stylesheet");
+ SmallString<128> StylesheetPath = computeRelativePath("", InfoPath);
+ llvm::sys::path::append(StylesheetPath,
+ llvm::sys::path::filename(FilePath));
+ LinkNode->Attributes.try_emplace("href", StylesheetPath);
+ Out.emplace_back(std::move(LinkNode));
+ }
+ return Out;
+}
+
static std::unique_ptr<TagNode> genLink(const Twine &Text, const Twine &Link) {
auto LinkNode = llvm::make_unique<TagNode>(HTMLTag::TAG_A, Text);
LinkNode->Attributes.try_emplace("href", Link.str());
@@ -529,13 +544,15 @@ class HTMLGenerator : public Generator {
public:
static const char *Format;
- llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override;
+ llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+ const ClangDocContext &CDCtx) override;
bool createResources(ClangDocContext CDCtx) override;
};
const char *HTMLGenerator::Format = "html";
-llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
+llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+ const ClangDocContext &CDCtx) {
HTMLFile F;
auto MetaNode = llvm::make_unique<TagNode>(HTMLTag::TAG_META);
@@ -577,12 +594,9 @@ llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
F.Children.emplace_back(
llvm::make_unique<TagNode>(HTMLTag::TAG_TITLE, InfoTitle));
- auto LinkNode = llvm::make_unique<TagNode>(HTMLTag::TAG_LINK);
- LinkNode->Attributes.try_emplace("rel", "stylesheet");
- SmallString<128> StylesheetPath = computeRelativePath("", I->Path);
- llvm::sys::path::append(StylesheetPath, "clang-doc-default-stylesheet.css");
- LinkNode->Attributes.try_emplace("href", StylesheetPath);
- F.Children.emplace_back(std::move(LinkNode));
+ std::vector<std::unique_ptr<TagNode>> StylesheetsNodes =
+ genStylesheetsHTML(I->Path, CDCtx);
+ AppendVector(std::move(StylesheetsNodes), F.Children);
F.Children.emplace_back(std::move(MainContentNode));
F.Render(OS);
@@ -591,22 +605,22 @@ llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
bool HTMLGenerator::createResources(ClangDocContext CDCtx) {
llvm::outs() << "Generating stylesheet for docs...\n";
- llvm::SmallString<128> StylesheetPathWrite;
- llvm::sys::path::native(CDCtx.OutDirectory, StylesheetPathWrite);
- llvm::sys::path::append(StylesheetPathWrite,
- "clang-doc-default-stylesheet.css");
- llvm::SmallString<128> StylesheetPathRead;
- llvm::sys::path::native(CDCtx.ClangDocPath, StylesheetPathRead);
- StylesheetPathRead = llvm::sys::path::parent_path(StylesheetPathRead);
- llvm::sys::path::append(StylesheetPathRead, "..", "share", "clang",
- "clang-doc-default-stylesheet.css");
- std::error_code OK;
- std::error_code FileErr =
- llvm::sys::fs::copy_file(StylesheetPathRead, StylesheetPathWrite);
- if (FileErr != OK) {
- llvm::errs() << "Error creating stylesheet file: " << FileErr.message()
- << "\n";
- return false;
+ for (const auto &FilePath : CDCtx.UserStylesheets) {
+ llvm::SmallString<128> StylesheetPathWrite;
+ llvm::sys::path::native(CDCtx.OutDirectory, StylesheetPathWrite);
+ llvm::sys::path::append(StylesheetPathWrite,
+ llvm::sys::path::filename(FilePath));
+ llvm::SmallString<128> StylesheetPathRead;
+ llvm::sys::path::native(FilePath, StylesheetPathRead);
+ std::error_code OK;
+ std::error_code FileErr =
+ llvm::sys::fs::copy_file(StylesheetPathRead, StylesheetPathWrite);
+ if (FileErr != OK) {
+ llvm::errs() << "Error creating stylesheet file "
+ << llvm::sys::path::filename(FilePath) << ": "
+ << FileErr.message() << "\n";
+ return false;
+ }
}
return true;
}
diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp
index c1f89ff3b11..5334dfb0a1a 100644
--- a/clang-tools-extra/clang-doc/MDGenerator.cpp
+++ b/clang-tools-extra/clang-doc/MDGenerator.cpp
@@ -250,13 +250,15 @@ class MDGenerator : public Generator {
public:
static const char *Format;
- llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override;
+ llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+ const ClangDocContext &CDCtx) override;
bool createResources(ClangDocContext CDCtx) override { return true; }
};
const char *MDGenerator::Format = "md";
-llvm::Error MDGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
+llvm::Error MDGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+ const ClangDocContext &CDCtx) {
switch (I->IT) {
case InfoType::IT_namespace:
genMarkdown(*static_cast<clang::doc::NamespaceInfo *>(I), OS);
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index 0dc694f7cd9..6abccf8e56b 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -350,7 +350,7 @@ struct ClangDocContext {
tooling::ExecutionContext *ECtx;
bool PublicOnly;
std::string OutDirectory;
- std::string ClangDocPath;
+ std::vector<std::string> UserStylesheets;
};
} // namespace doc
diff --git a/clang-tools-extra/clang-doc/YAMLGenerator.cpp b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
index 4da649345cf..9a388b99ba1 100644
--- a/clang-tools-extra/clang-doc/YAMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
@@ -243,13 +243,15 @@ class YAMLGenerator : public Generator {
public:
static const char *Format;
- llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override;
+ llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+ const ClangDocContext &CDCtx) override;
bool createResources(ClangDocContext CDCtx) override { return true; }
};
const char *YAMLGenerator::Format = "yaml";
-llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
+llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+ const ClangDocContext &CDCtx) {
llvm::yaml::Output InfoYAML(OS);
switch (I->IT) {
case InfoType::IT_namespace:
diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 89918701dc5..0e910f3506c 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -62,6 +62,11 @@ static llvm::cl::opt<bool> DoxygenOnly(
llvm::cl::desc("Use only doxygen-style comments to generate docs."),
llvm::cl::init(false), llvm::cl::cat(ClangDocCategory));
+static llvm::cl::list<std::string> UserStylesheets(
+ "stylesheets", llvm::cl::CommaSeparated,
+ llvm::cl::desc("CSS stylesheets to extend the default styles."),
+ llvm::cl::cat(ClangDocCategory));
+
enum OutputFormatTy {
md,
yaml,
@@ -201,12 +206,26 @@ int main(int argc, const char **argv) {
tooling::ArgumentInsertPosition::END),
ArgAdjuster);
+ clang::doc::ClangDocContext CDCtx = {
+ Exec->get()->getExecutionContext(),
+ PublicOnly,
+ OutDirectory,
+ {UserStylesheets.begin(), UserStylesheets.end()}};
+
+ if (Format == "html") {
+ void *MainAddr = (void *)(intptr_t)GetExecutablePath;
+ std::string ClangDocPath = GetExecutablePath(argv[0], MainAddr);
+ llvm::SmallString<128> DefaultStylesheet;
+ llvm::sys::path::native(ClangDocPath, DefaultStylesheet);
+ DefaultStylesheet = llvm::sys::path::parent_path(DefaultStylesheet);
+ llvm::sys::path::append(DefaultStylesheet,
+ "../share/clang/clang-doc-default-stylesheet.css");
+ CDCtx.UserStylesheets.insert(CDCtx.UserStylesheets.begin(),
+ DefaultStylesheet.str());
+ }
+
// Mapping phase
llvm::outs() << "Mapping decls...\n";
- void *MainAddr = (void *)(intptr_t)GetExecutablePath;
- std::string ClangDocPath = GetExecutablePath(argv[0], MainAddr);
- clang::doc::ClangDocContext CDCtx = {Exec->get()->getExecutionContext(),
- PublicOnly, OutDirectory, ClangDocPath};
auto Err =
Exec->get()->execute(doc::newMapperActionFactory(CDCtx), ArgAdjuster);
if (Err) {
@@ -245,7 +264,7 @@ int main(int argc, const char **argv) {
continue;
}
- if (auto Err = G->get()->generateDocForInfo(I, InfoOS))
+ if (auto Err = G->get()->generateDocForInfo(I, InfoOS, CDCtx))
llvm::errs() << toString(std::move(Err)) << "\n";
}
diff --git a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
index 39de9a4f976..445a2ef6024 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -21,6 +21,16 @@ std::unique_ptr<Generator> getHTMLGenerator() {
return std::move(G.get());
}
+ClangDocContext
+getClangDocContext(std::vector<std::string> UserStylesheets = {}) {
+ ClangDocContext CDCtx;
+ CDCtx.UserStylesheets = {UserStylesheets.begin(), UserStylesheets.end()};
+ CDCtx.UserStylesheets.insert(
+ CDCtx.UserStylesheets.begin(),
+ "../share/clang/clang-doc-default-stylesheet.css");
+ return CDCtx;
+}
+
TEST(HTMLGeneratorTest, emitNamespaceHTML) {
NamespaceInfo I;
I.Name = "Namespace";
@@ -38,12 +48,14 @@ TEST(HTMLGeneratorTest, emitNamespaceHTML) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ ClangDocContext CDCtx = getClangDocContext({"user-provided-stylesheet.css"});
+ auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
assert(!Err);
std::string Expected = R"raw(<!DOCTYPE html>
<meta charset="utf-8"/>
<title>namespace Namespace</title>
<link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>
+<link rel="stylesheet" href="user-provided-stylesheet.css"/>
<div>
<h1>namespace Namespace</h1>
<h2>Namespaces</h2>
@@ -95,7 +107,8 @@ TEST(HTMLGeneratorTest, emitRecordHTML) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ ClangDocContext CDCtx = getClangDocContext();
+ auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
assert(!Err);
SmallString<16> PathToF;
llvm::sys::path::native("../../../path/to/F.html", PathToF);
@@ -161,7 +174,8 @@ TEST(HTMLGeneratorTest, emitFunctionHTML) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ ClangDocContext CDCtx = getClangDocContext();
+ auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
assert(!Err);
SmallString<16> PathToFloat;
llvm::sys::path::native("path/to/float.html", PathToFloat);
@@ -203,7 +217,8 @@ TEST(HTMLGeneratorTest, emitEnumHTML) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ ClangDocContext CDCtx = getClangDocContext();
+ auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
assert(!Err);
std::string Expected = R"raw(<!DOCTYPE html>
<meta charset="utf-8"/>
@@ -271,7 +286,8 @@ TEST(HTMLGeneratorTest, emitCommentHTML) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ ClangDocContext CDCtx = getClangDocContext();
+ auto Err = G->generateDocForInfo(&I, Actual, CDCtx);
assert(!Err);
std::string Expected = R"raw(<!DOCTYPE html>
<meta charset="utf-8"/>
diff --git a/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp
index 233ec6ecc10..3a35108fadf 100644
--- a/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp
@@ -38,7 +38,7 @@ TEST(MDGeneratorTest, emitNamespaceMD) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
assert(!Err);
std::string Expected = R"raw(# namespace Namespace
@@ -101,7 +101,7 @@ TEST(MDGeneratorTest, emitRecordMD) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
assert(!Err);
std::string Expected = R"raw(# class r
@@ -162,7 +162,7 @@ TEST(MDGeneratorTest, emitFunctionMD) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
assert(!Err);
std::string Expected = R"raw(### f
@@ -190,7 +190,7 @@ TEST(MDGeneratorTest, emitEnumMD) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
assert(!Err);
std::string Expected = R"raw(| enum class e |
@@ -320,7 +320,7 @@ TEST(MDGeneratorTest, emitCommentMD) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
assert(!Err);
std::string Expected =
R"raw(### f
diff --git a/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp
index e2295525bdd..26379d20efd 100644
--- a/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp
@@ -40,7 +40,7 @@ TEST(YAMLGeneratorTest, emitNamespaceYAML) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
assert(!Err);
std::string Expected =
R"raw(---
@@ -94,7 +94,7 @@ TEST(YAMLGeneratorTest, emitRecordYAML) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
assert(!Err);
std::string Expected =
R"raw(---
@@ -158,7 +158,7 @@ TEST(YAMLGeneratorTest, emitFunctionYAML) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
assert(!Err);
std::string Expected =
R"raw(---
@@ -206,7 +206,7 @@ TEST(YAMLGeneratorTest, emitEnumYAML) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
assert(!Err);
std::string Expected =
R"raw(---
@@ -343,7 +343,7 @@ TEST(YAMLGeneratorTest, emitCommentYAML) {
assert(G);
std::string Buffer;
llvm::raw_string_ostream Actual(Buffer);
- auto Err = G->generateDocForInfo(&I, Actual);
+ auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext());
assert(!Err);
std::string Expected =
R"raw(---
OpenPOWER on IntegriCloud