[clang-tools-extra] [clang-doc] Add a Mustache Markdown generator (PR #177221)
Erick Velez via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 2 18:03:22 PST 2026
https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/177221
>From 817ccd384a5a2ab255b58b078e5f3df7d6575b50 Mon Sep 17 00:00:00 2001
From: Erick Velez <erickvelez7 at gmail.com>
Date: Fri, 7 Nov 2025 21:56:12 -0800
Subject: [PATCH 1/2] fix the fix
---
clang-tools-extra/clang-doc/CMakeLists.txt | 1 +
clang-tools-extra/clang-doc/Generators.cpp | 10 +-
clang-tools-extra/clang-doc/Generators.h | 5 +
clang-tools-extra/clang-doc/JSONGenerator.cpp | 119 +++++++++++++---
.../clang-doc/MDMustacheGenerator.cpp | 115 ++++++++++++++++
.../clang-doc/Representation.cpp | 5 +-
clang-tools-extra/clang-doc/Representation.h | 4 +-
.../assets/md/all-files-template.mustache | 5 +
.../assets/md/class-template.mustache | 62 +++++++++
.../assets/md/comments-partial.mustache | 23 ++++
.../assets/md/index-template.mustache | 5 +
.../assets/md/namespace-template.mustache | 63 +++++++++
clang-tools-extra/clang-doc/support/Utils.cpp | 24 ++++
clang-tools-extra/clang-doc/support/Utils.h | 2 +
.../clang-doc/tool/CMakeLists.txt | 5 +
.../clang-doc/tool/ClangDocMain.cpp | 63 ++++++---
.../clang-doc/basic-project.mustache.test | 127 ++++++++++++++++++
.../test/clang-doc/builtin_types.cpp | 32 ++++-
.../test/clang-doc/comments-in-macros.cpp | 15 ++-
clang-tools-extra/test/clang-doc/enum.cpp | 52 +++++++
clang-tools-extra/test/clang-doc/index.cpp | 4 +
.../test/clang-doc/json/class.cpp | 3 +-
.../test/clang-doc/json/namespace.cpp | 1 -
.../test/clang-doc/namespace.cpp | 121 ++++++++++++++++-
.../test/clang-doc/templates.cpp | 24 ++++
.../unittests/clang-doc/ClangDocTest.cpp | 2 +-
.../unittests/clang-doc/HTMLGeneratorTest.cpp | 1 +
.../unittests/clang-doc/JSONGeneratorTest.cpp | 24 ++--
28 files changed, 846 insertions(+), 71 deletions(-)
create mode 100644 clang-tools-extra/clang-doc/MDMustacheGenerator.cpp
create mode 100644 clang-tools-extra/clang-doc/assets/md/all-files-template.mustache
create mode 100644 clang-tools-extra/clang-doc/assets/md/class-template.mustache
create mode 100644 clang-tools-extra/clang-doc/assets/md/comments-partial.mustache
create mode 100644 clang-tools-extra/clang-doc/assets/md/index-template.mustache
create mode 100644 clang-tools-extra/clang-doc/assets/md/namespace-template.mustache
diff --git a/clang-tools-extra/clang-doc/CMakeLists.txt b/clang-tools-extra/clang-doc/CMakeLists.txt
index 7a375d7cd0524..a64c086a98910 100644
--- a/clang-tools-extra/clang-doc/CMakeLists.txt
+++ b/clang-tools-extra/clang-doc/CMakeLists.txt
@@ -17,6 +17,7 @@ add_clang_library(clangDoc STATIC
Serialize.cpp
YAMLGenerator.cpp
JSONGenerator.cpp
+ MDMustacheGenerator.cpp
DEPENDS
omp_gen
diff --git a/clang-tools-extra/clang-doc/Generators.cpp b/clang-tools-extra/clang-doc/Generators.cpp
index eca1f288d5ba1..9fab97fc8825a 100644
--- a/clang-tools-extra/clang-doc/Generators.cpp
+++ b/clang-tools-extra/clang-doc/Generators.cpp
@@ -164,9 +164,11 @@ Error MustacheGenerator::generateDocumentation(
Expected<std::string> MustacheGenerator::getInfoTypeStr(Object *Info,
StringRef Filename) {
- // Checking for a USR ensures that only the special top-level index file is
- // caught here, since it is not an Info.
- if (Filename == "index" && !Info->get("USR"))
+ if (Filename == "all_files")
+ return "all_files";
+ // Checking for an InfoType ensures that only the special top-level index file
+ // is caught here, since it is not an Info.
+ if (Filename == "index" && !Info->get("InfoType"))
return "index";
auto StrValue = (*Info)["InfoType"];
if (StrValue.kind() != json::Value::Kind::String)
@@ -248,5 +250,7 @@ void Generator::addInfoToIndex(Index &Idx, const doc::Info *Info) {
[[maybe_unused]] static int MDGeneratorAnchorDest = MDGeneratorAnchorSource;
[[maybe_unused]] static int HTMLGeneratorAnchorDest = HTMLGeneratorAnchorSource;
[[maybe_unused]] static int JSONGeneratorAnchorDest = JSONGeneratorAnchorSource;
+[[maybe_unused]] static int MDMustacheGeneratorAnchorDest =
+ MDMustacheGeneratorAnchorSource;
} // namespace doc
} // namespace clang
diff --git a/clang-tools-extra/clang-doc/Generators.h b/clang-tools-extra/clang-doc/Generators.h
index ade0bb53eba7e..7ba66947a830a 100644
--- a/clang-tools-extra/clang-doc/Generators.h
+++ b/clang-tools-extra/clang-doc/Generators.h
@@ -87,6 +87,10 @@ class MustacheTemplateFile {
void render(llvm::json::Value &V, raw_ostream &OS) { T.render(V, OS); }
+ void setEscapeCharacters(const llvm::DenseMap<char, std::string> Characters) {
+ T.overrideEscapeCharacters(Characters);
+ }
+
MustacheTemplateFile(std::unique_ptr<llvm::MemoryBuffer> &&B)
: Saver(Allocator), Ctx(Allocator, Saver), T(B->getBuffer(), Ctx),
Buffer(std::move(B)) {}
@@ -138,6 +142,7 @@ extern volatile int YAMLGeneratorAnchorSource;
extern volatile int MDGeneratorAnchorSource;
extern volatile int HTMLGeneratorAnchorSource;
extern volatile int JSONGeneratorAnchorSource;
+extern volatile int MDMustacheGeneratorAnchorSource;
} // namespace doc
} // namespace clang
diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index 9a8f51b808cab..52bff22bf5822 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -14,6 +14,7 @@ namespace doc {
class JSONGenerator : public Generator {
public:
static const char *Format;
+ bool Markdown = false;
Error generateDocumentation(StringRef RootDir,
llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
@@ -358,7 +359,8 @@ serializeCommonAttributes(const Info &I, json::Object &Obj,
const std::optional<StringRef> RepositoryUrl,
const std::optional<StringRef> RepositoryLinePrefix) {
insertNonEmpty("Name", I.Name, Obj);
- Obj["USR"] = toHex(toStringRef(I.USR));
+ if (!(I.USR == GlobalNamespaceID))
+ Obj["USR"] = toHex(toStringRef(I.USR));
Obj["InfoType"] = infoTypeToString(I.IT);
// Conditionally insert fields.
// Empty properties are omitted because Mustache templates use existence
@@ -419,12 +421,25 @@ static void serializeReference(const Reference &Ref, Object &ReferenceObj) {
}
}
+static void serializeMDReference(const Reference &Ref, Object &ReferenceObj,
+ StringRef BasePath) {
+ serializeReference(Ref, ReferenceObj);
+ SmallString<64> Path = Ref.getRelativeFilePath(BasePath);
+ sys::path::native(Path, sys::path::Style::posix);
+ sys::path::append(Path, sys::path::Style::posix,
+ Ref.getFileBaseName() + ".md");
+ ReferenceObj["BasePath"] = Path;
+}
+
+typedef std::function<void(const Reference &, Object &)> ReferenceFunc;
+
// Although namespaces and records both have ScopeChildren, they serialize them
// differently. Only enums, records, and typedefs are handled here.
-static void
-serializeCommonChildren(const ScopeChildren &Children, json::Object &Obj,
- const std::optional<StringRef> RepositoryUrl,
- const std::optional<StringRef> RepositoryLinePrefix) {
+static void serializeCommonChildren(
+ const ScopeChildren &Children, json::Object &Obj,
+ const std::optional<StringRef> RepositoryUrl,
+ const std::optional<StringRef> RepositoryLinePrefix,
+ std::optional<ReferenceFunc> MDReferenceLambda = std::nullopt) {
static auto SerializeInfo =
[RepositoryUrl, RepositoryLinePrefix](const auto &Info, Object &Object) {
serializeInfo(Info, Object, RepositoryUrl, RepositoryLinePrefix);
@@ -441,7 +456,12 @@ serializeCommonChildren(const ScopeChildren &Children, json::Object &Obj,
}
if (!Children.Records.empty()) {
- serializeArray(Children.Records, Obj, "Records", SerializeReferenceLambda);
+ if (MDReferenceLambda)
+ serializeArray(Children.Records, Obj, "Records",
+ MDReferenceLambda.value());
+ else
+ serializeArray(Children.Records, Obj, "Records",
+ SerializeReferenceLambda);
Obj["HasRecords"] = true;
}
}
@@ -667,6 +687,7 @@ serializeInfo(const RecordInfo &I, json::Object &Obj,
}
if (!I.Members.empty()) {
+ Obj["HasMembers"] = true;
json::Value PublicMembersArray = Array();
json::Array &PubMembersArrayRef = *PublicMembersArray.getAsArray();
json::Value ProtectedMembersArray = Array();
@@ -740,17 +761,12 @@ serializeInfo(const VarInfo &I, json::Object &Obj,
static void serializeInfo(const NamespaceInfo &I, json::Object &Obj,
const std::optional<StringRef> RepositoryUrl,
- const std::optional<StringRef> RepositoryLinePrefix) {
+ const std::optional<StringRef> RepositoryLinePrefix,
+ bool Markdown) {
serializeCommonAttributes(I, Obj, RepositoryUrl, RepositoryLinePrefix);
if (I.USR == GlobalNamespaceID)
Obj["Name"] = "Global Namespace";
- if (!I.Children.Namespaces.empty()) {
- serializeArray(I.Children.Namespaces, Obj, "Namespaces",
- SerializeReferenceLambda);
- Obj["HasNamespaces"] = true;
- }
-
static auto SerializeInfo =
[RepositoryUrl, RepositoryLinePrefix](const auto &Info, Object &Object) {
serializeInfo(Info, Object, RepositoryUrl, RepositoryLinePrefix);
@@ -771,7 +787,31 @@ static void serializeInfo(const NamespaceInfo &I, json::Object &Obj,
Obj["HasVariables"] = true;
}
- serializeCommonChildren(I.Children, Obj, RepositoryUrl, RepositoryLinePrefix);
+ if (Markdown) {
+ SmallString<64> BasePath = I.getRelativeFilePath("");
+ // serializeCommonChildren doesn't accept Infos, so this lambda needs to be
+ // created here. To avoid making serializeCommonChildren a template, this
+ // lambda is an std::function
+ ReferenceFunc SerializeMDReferenceLambda =
+ [BasePath](const Reference &Ref, Object &Object) {
+ serializeMDReference(Ref, Object, BasePath);
+ };
+ serializeCommonChildren(I.Children, Obj, RepositoryUrl,
+ RepositoryLinePrefix, SerializeMDReferenceLambda);
+ if (!I.Children.Namespaces.empty()) {
+ serializeArray(I.Children.Namespaces, Obj, "Namespaces",
+ SerializeMDReferenceLambda);
+ Obj["HasNamespaces"] = true;
+ }
+ } else {
+ serializeCommonChildren(I.Children, Obj, RepositoryUrl,
+ RepositoryLinePrefix);
+ if (!I.Children.Namespaces.empty()) {
+ serializeArray(I.Children.Namespaces, Obj, "Namespaces",
+ SerializeReferenceLambda);
+ Obj["HasNamespaces"] = true;
+ }
+ }
}
static SmallString<16> determineFileName(Info *I, SmallString<128> &Path) {
@@ -787,10 +827,44 @@ static SmallString<16> determineFileName(Info *I, SmallString<128> &Path) {
return FileName;
}
+/// \param CDCtxIndex Passed by copy since clang-doc's context is passed to the
+/// generator as `const`
+static std::vector<Index> preprocessCDCtxIndex(Index CDCtxIndex) {
+ CDCtxIndex.sort();
+ std::vector<Index> Processed = CDCtxIndex.Children;
+ for (auto &Entry : Processed) {
+ auto NewPath = Entry.getRelativeFilePath("");
+ sys::path::native(NewPath, sys::path::Style::posix);
+ sys::path::append(NewPath, sys::path::Style::posix,
+ Entry.getFileBaseName() + ".md");
+ Entry.Path = NewPath;
+ }
+
+ return Processed;
+}
+
+/// Serialize ClangDocContext's Index for Markdown output
+static Error serializeAllFiles(const ClangDocContext &CDCtx,
+ StringRef RootDir) {
+ json::Value ObjVal = Object();
+ Object &Obj = *ObjVal.getAsObject();
+ std::vector<Index> IndexCopy = preprocessCDCtxIndex(CDCtx.Idx);
+ serializeArray(IndexCopy, Obj, "Index", SerializeReferenceLambda);
+ SmallString<128> Path;
+ sys::path::append(Path, RootDir.str(), "json", "all_files.json");
+ std::error_code FileErr;
+ raw_fd_ostream RootOS(Path, FileErr, sys::fs::OF_Text);
+ if (FileErr)
+ return createFileError("cannot open file " + Path, FileErr);
+ RootOS << llvm::formatv("{0:2}", ObjVal);
+ return Error::success();
+}
+
// Creates a JSON file above the global namespace directory.
// An index can be used to create the top-level HTML index page or the Markdown
// index file.
-static Error serializeIndex(const ClangDocContext &CDCtx, StringRef RootDir) {
+static Error serializeIndex(const ClangDocContext &CDCtx, StringRef RootDir,
+ bool Markdown) {
if (CDCtx.Idx.Children.empty())
return Error::success();
@@ -814,9 +888,12 @@ static Error serializeIndex(const ClangDocContext &CDCtx, StringRef RootDir) {
for (auto &Idx : IndexCopy.Children) {
if (Idx.Children.empty())
continue;
- std::string TypeStr = infoTypeToString(Idx.RefType);
json::Value IdxVal = Object();
auto &IdxObj = *IdxVal.getAsObject();
+ auto TypeStr = infoTypeToString(Idx.RefType);
+ if (Markdown)
+ TypeStr.at(0) = toUppercase(TypeStr.at(0));
+ IdxObj["Type"] = TypeStr;
serializeReference(Idx, IdxObj);
IndexArrayRef.push_back(IdxVal);
}
@@ -882,6 +959,12 @@ Error JSONGenerator::generateDocumentation(
Info->DocumentationFileName = FileName;
}
+ if (CDCtx.Format == "md_mustache") {
+ Markdown = true;
+ if (auto Err = serializeAllFiles(CDCtx, RootDir))
+ return Err;
+ }
+
for (const auto &Group : FileToInfos) {
std::error_code FileErr;
raw_fd_ostream InfoOS(Group.getKey(), FileErr, sys::fs::OF_Text);
@@ -896,7 +979,7 @@ Error JSONGenerator::generateDocumentation(
}
}
- return serializeIndex(CDCtx, RootDir);
+ return serializeIndex(CDCtx, RootDir, Markdown);
}
Error JSONGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
@@ -906,7 +989,7 @@ Error JSONGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
switch (I->IT) {
case InfoType::IT_namespace:
serializeInfo(*static_cast<NamespaceInfo *>(I), Obj, CDCtx.RepositoryUrl,
- CDCtx.RepositoryLinePrefix);
+ CDCtx.RepositoryLinePrefix, Markdown);
break;
case InfoType::IT_record:
serializeInfo(*static_cast<RecordInfo *>(I), Obj, CDCtx.RepositoryUrl,
diff --git a/clang-tools-extra/clang-doc/MDMustacheGenerator.cpp b/clang-tools-extra/clang-doc/MDMustacheGenerator.cpp
new file mode 100644
index 0000000000000..2b0b9a2f89fe1
--- /dev/null
+++ b/clang-tools-extra/clang-doc/MDMustacheGenerator.cpp
@@ -0,0 +1,115 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Contains the Markdown generator using Mustache template files.
+///
+//===----------------------------------------------------------------------===//
+
+#include "Generators.h"
+
+namespace clang {
+using namespace llvm;
+namespace doc {
+static std::unique_ptr<MustacheTemplateFile> RecordTemplate = nullptr;
+
+static std::unique_ptr<MustacheTemplateFile> NamespaceTemplate = nullptr;
+
+static std::unique_ptr<MustacheTemplateFile> AllFilesTemplate = nullptr;
+
+static std::unique_ptr<MustacheTemplateFile> IndexTemplate = nullptr;
+
+struct MDMustacheGenerator : public MustacheGenerator {
+ static const char *Format;
+ Error generateDocumentation(StringRef RootDir,
+ StringMap<std::unique_ptr<doc::Info>> Infos,
+ const ClangDocContext &CDCtx,
+ std::string DirName) override;
+ Error setupTemplateFiles(const ClangDocContext &CDCtx) override;
+ Error generateDocForJSON(json::Value &JSON, raw_fd_ostream &OS,
+ const ClangDocContext &CDCtx,
+ StringRef ObjectTypeStr,
+ StringRef RelativeRootPath) override;
+ // This generator doesn't need this function, but it inherits from the
+ // original generator interface.
+ Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
+ const ClangDocContext &CDCtx) override;
+};
+
+Error MDMustacheGenerator::setupTemplateFiles(const ClangDocContext &CDCtx) {
+ std::string ClassFilePath = CDCtx.MustacheTemplates.lookup("class-template");
+ std::string NamespaceFilePath =
+ CDCtx.MustacheTemplates.lookup("namespace-template");
+ std::string AllFilesPath = CDCtx.MustacheTemplates.lookup("all-files");
+ std::string IndexFilePath = CDCtx.MustacheTemplates.lookup("index");
+ std::string CommentsFilePath = CDCtx.MustacheTemplates.lookup("comments");
+ std::vector<std::pair<StringRef, StringRef>> Partials = {
+ {"Comments", CommentsFilePath}};
+
+ if (Error Err = setupTemplate(RecordTemplate, ClassFilePath, Partials))
+ return Err;
+ if (Error Err = setupTemplate(NamespaceTemplate, NamespaceFilePath, Partials))
+ return Err;
+ if (Error Err = setupTemplate(AllFilesTemplate, AllFilesPath, Partials))
+ return Err;
+ if (Error Err = setupTemplate(IndexTemplate, IndexFilePath, Partials))
+ return Err;
+
+ // Override the default HTML Mustache escape characters. We don't need to
+ // override `<` here.
+ static const DenseMap<char, std::string> EscapeChars;
+ RecordTemplate->setEscapeCharacters(EscapeChars);
+ NamespaceTemplate->setEscapeCharacters(EscapeChars);
+ AllFilesTemplate->setEscapeCharacters(EscapeChars);
+ IndexTemplate->setEscapeCharacters(EscapeChars);
+
+ return Error::success();
+}
+
+Error MDMustacheGenerator::generateDocumentation(
+ StringRef RootDir, StringMap<std::unique_ptr<doc::Info>> Infos,
+ const clang::doc::ClangDocContext &CDCtx, std::string Dirname) {
+ return MustacheGenerator::generateDocumentation(RootDir, std::move(Infos),
+ CDCtx, "md");
+}
+
+Error MDMustacheGenerator::generateDocForJSON(json::Value &JSON,
+ raw_fd_ostream &OS,
+ const ClangDocContext &CDCtx,
+ StringRef ObjTypeStr,
+ StringRef RelativeRootPath) {
+ if (ObjTypeStr == "record") {
+ assert(RecordTemplate && "RecordTemplate is nullptr.");
+ RecordTemplate->render(JSON, OS);
+ } else if (ObjTypeStr == "namespace") {
+ assert(NamespaceTemplate && "NamespaceTemplate is nullptr.");
+ NamespaceTemplate->render(JSON, OS);
+ } else if (ObjTypeStr == "all_files") {
+ assert(AllFilesTemplate && "AllFilesTemplate is nullptr.");
+ AllFilesTemplate->render(JSON, OS);
+ } else if (ObjTypeStr == "index") {
+ assert(IndexTemplate && "IndexTemplate is nullptr");
+ IndexTemplate->render(JSON, OS);
+ }
+ return Error::success();
+}
+
+Error MDMustacheGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
+ const ClangDocContext &CDCtx) {
+ return Error::success();
+}
+
+const char *MDMustacheGenerator::Format = "md_mustache";
+
+static GeneratorRegistry::Add<MDMustacheGenerator>
+ MDMustache(MDMustacheGenerator::Format,
+ "Generator for mustache Markdown output.");
+
+volatile int MDMustacheGeneratorAnchorSource = 0;
+} // namespace doc
+} // namespace clang
diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp
index a69129041516f..d60a24dc3e756 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -485,10 +485,11 @@ ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx,
StringRef RepositoryLinePrefix, StringRef Base,
std::vector<std::string> UserStylesheets,
clang::DiagnosticsEngine &Diags,
- bool FTimeTrace)
+ StringRef Format, bool FTimeTrace)
: ECtx(ECtx), ProjectName(ProjectName), OutDirectory(OutDirectory),
SourceRoot(std::string(SourceRoot)), UserStylesheets(UserStylesheets),
- Base(Base), Diags(Diags), PublicOnly(PublicOnly), FTimeTrace(FTimeTrace) {
+ Base(Base), Diags(Diags), Format(Format), PublicOnly(PublicOnly),
+ FTimeTrace(FTimeTrace) {
llvm::SmallString<128> SourceRootDir(SourceRoot);
if (SourceRoot.empty())
// If no SourceRoot was provided the current path is used as the default
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index 297e564ea7866..d066f36e74d0e 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -629,7 +629,8 @@ struct ClangDocContext {
bool PublicOnly, StringRef OutDirectory, StringRef SourceRoot,
StringRef RepositoryUrl, StringRef RepositoryCodeLinePrefix,
StringRef Base, std::vector<std::string> UserStylesheets,
- clang::DiagnosticsEngine &Diags, bool FTimeTrace = false);
+ clang::DiagnosticsEngine &Diags, StringRef Format,
+ bool FTimeTrace = false);
tooling::ExecutionContext *ECtx;
std::string ProjectName; // Name of project clang-doc is documenting.
std::string OutDirectory; // Directory for outputting generated files.
@@ -653,6 +654,7 @@ struct ClangDocContext {
// A pointer to a DiagnosticsEngine for error reporting.
clang::DiagnosticsEngine &Diags;
Index Idx;
+ std::string Format;
int Granularity; // Granularity of ftime trace
bool PublicOnly; // Indicates if only public declarations are documented.
bool FTimeTrace; // Indicates if ftime trace is turned on
diff --git a/clang-tools-extra/clang-doc/assets/md/all-files-template.mustache b/clang-tools-extra/clang-doc/assets/md/all-files-template.mustache
new file mode 100644
index 0000000000000..b1ab36aa199c1
--- /dev/null
+++ b/clang-tools-extra/clang-doc/assets/md/all-files-template.mustache
@@ -0,0 +1,5 @@
+# All Files
+
+{{#Index}}
+## [{{Name}}]({{Path}})
+{{/Index}}
diff --git a/clang-tools-extra/clang-doc/assets/md/class-template.mustache b/clang-tools-extra/clang-doc/assets/md/class-template.mustache
new file mode 100644
index 0000000000000..4b936df56f80e
--- /dev/null
+++ b/clang-tools-extra/clang-doc/assets/md/class-template.mustache
@@ -0,0 +1,62 @@
+# {{TagType}} {{Name}}
+
+*Defined at {{Location.Filename}}#{{Location.LineNumber}}*
+{{#Description}}
+
+{{>Comments}}
+{{/Description}}
+{{#HasParents}}
+Inherits from {{#Parents}}{{Name}}{{^End}}, {{/End}}{{/Parents}}{{#VParents}}{{Name}}{{^End}}, {{/End}}{{/VParents}}
+{{/HasParents}}
+{{#HasMembers}}
+## Members
+{{/HasMembers}}
+{{#PublicMembers}}
+public {{#IsStatic}}static {{/IsStatic}}{{Type}} {{Name}}
+
+{{/PublicMembers}}
+{{#PrivateMembers}}
+private {{#IsStatic}}static {{/IsStatic}}{{Type}} {{Name}}
+
+{{/PrivateMembers}}
+
+{{#HasPublicMethods}}
+## Functions
+
+{{#PublicMethods}}
+### {{Name}}
+
+*public {{#IsStatic}}static {{/IsStatic}}{{ReturnType.QualName}} {{Name}}({{#Params}}{{Type.QualName}} {{Name}}{{^End}}, {{/End}}{{/Params}})*
+{{#Location}}
+
+*Defined at {{Filename}}#{{LineNumber}}*
+{{/Location}}
+{{#Description}}
+
+{{>Comments}}
+{{/Description}}
+{{/PublicMethods}}
+{{/HasPublicMethods}}
+{{#HasEnums}}
+## Enums
+
+{{#Enums}}
+| enum {{Name}} |
+
+--
+
+{{#Members}}
+| {{ .Name }} |
+{{/Members}}
+{{#Location}}
+
+*Defined at {{Filename}}#{{LineNumber}}*
+{{/Location}}
+{{#Description}}
+
+{{>Comments}}
+{{/Description}}
+{{^End}}
+{{/End}}
+{{/Enums}}
+{{/HasEnums}}
diff --git a/clang-tools-extra/clang-doc/assets/md/comments-partial.mustache b/clang-tools-extra/clang-doc/assets/md/comments-partial.mustache
new file mode 100644
index 0000000000000..e0719d7a7baca
--- /dev/null
+++ b/clang-tools-extra/clang-doc/assets/md/comments-partial.mustache
@@ -0,0 +1,23 @@
+{{#HasBriefComments}}
+{{#BriefComments}}
+**brief**{{#.}}{{TextComment}}{{/.}}
+{{/BriefComments}}
+{{/HasBriefComments}}
+
+{{#ParagraphComments}}
+{{#.}}{{TextComment}}{{/.}}
+{{/ParagraphComments}}
+
+{{#HasParamComments}}
+{{#ParamComments}}
+**{{ParamName}}** {{#Children}}{{TextComment}}{{/Children}}
+{{/ParamComments}}
+{{/HasParamComments}}
+
+{{#ReturnComments}}
+**return** {{#.}}{{TextComment}}{{/.}}
+{{/ReturnComments}}
+
+{{#ThrowsComments}}
+**throw** {{#Children}}{{TextComment}}{{/Children}}
+{{/ThrowsComments}}
diff --git a/clang-tools-extra/clang-doc/assets/md/index-template.mustache b/clang-tools-extra/clang-doc/assets/md/index-template.mustache
new file mode 100644
index 0000000000000..867c9dc151dd2
--- /dev/null
+++ b/clang-tools-extra/clang-doc/assets/md/index-template.mustache
@@ -0,0 +1,5 @@
+# {{ProjectName}} C/C++ Reference
+
+{{#Index}}
+* {{Type}}: [{{Name}}]({{#Path}}{{Path}}/{{/Path}}{{Name}})
+{{/Index}}
diff --git a/clang-tools-extra/clang-doc/assets/md/namespace-template.mustache b/clang-tools-extra/clang-doc/assets/md/namespace-template.mustache
new file mode 100644
index 0000000000000..696c08148854b
--- /dev/null
+++ b/clang-tools-extra/clang-doc/assets/md/namespace-template.mustache
@@ -0,0 +1,63 @@
+# {{#USR}}namespace {{/USR}}{{Name}}
+
+{{#Description}}
+{{>Comments}}
+{{/Description}}
+
+{{#HasNamespaces}}
+## Namespaces
+
+{{#Namespaces}}
+* [{{Name}}]({{BasePath}})
+
+{{/Namespaces}}
+{{/HasNamespaces}}
+{{#HasRecords}}
+## Records
+
+{{#Records}}
+* [{{Name}}]({{BasePath}})
+
+{{/Records}}
+{{/HasRecords}}
+{{#HasFunctions}}
+## Functions
+
+{{#Functions}}
+### {{Name}}
+
+*{{#IsStatic}}static {{/IsStatic}}{{ReturnType.QualName}} {{Name}}({{#Params}}{{Type.QualName}} {{Name}}{{^End}}, {{/End}}{{/Params}})*
+{{#Location}}
+
+*Defined at {{Filename}}#{{LineNumber}}*
+{{/Location}}
+{{#Description}}
+
+{{>Comments}}
+{{/Description}}
+{{/Functions}}
+{{/HasFunctions}}
+{{#HasEnums}}
+## Enums
+
+{{#Enums}}
+| enum {{Name}} |
+
+--
+
+{{#Members}}
+| {{ .Name }} |
+{{/Members}}
+
+{{#Location}}
+*Defined at {{Filename}}#{{LineNumber}}*
+{{/Location}}
+
+{{#Description}}
+{{>Comments}}
+{{/Description}}
+{{^End}}
+
+{{/End}}
+{{/Enums}}
+{{/HasEnums}}
diff --git a/clang-tools-extra/clang-doc/support/Utils.cpp b/clang-tools-extra/clang-doc/support/Utils.cpp
index 1dce98f06d144..0691db06a06ca 100644
--- a/clang-tools-extra/clang-doc/support/Utils.cpp
+++ b/clang-tools-extra/clang-doc/support/Utils.cpp
@@ -77,3 +77,27 @@ void getHtmlFiles(StringRef AssetsPath, clang::doc::ClangDocContext &CDCtx) {
CDCtx.MustacheTemplates.insert({"index-template", IndexTemplate.c_str()});
CDCtx.MustacheTemplates.insert({"alias-template", AliasTemplate.c_str()});
}
+
+void getMdFiles(llvm::StringRef AssetsPath,
+ clang::doc::ClangDocContext &CDCtx) {
+ assert(!AssetsPath.empty());
+ assert(sys::fs::is_directory(AssetsPath));
+
+ SmallString<128> ClassTemplate =
+ appendPathPosix(AssetsPath, "class-template.mustache");
+ SmallString<128> NamespaceTemplate =
+ appendPathPosix(AssetsPath, "namespace-template.mustache");
+ SmallString<128> AllFilesTemplate =
+ appendPathPosix(AssetsPath, "all-files-template.mustache");
+ SmallString<128> IndexTemplate =
+ appendPathPosix(AssetsPath, "index-template.mustache");
+ SmallString<128> CommentsTemplate =
+ appendPathPosix(AssetsPath, "comments-partial.mustache");
+
+ CDCtx.MustacheTemplates.insert({"class-template", ClassTemplate.c_str()});
+ CDCtx.MustacheTemplates.insert(
+ {"namespace-template", NamespaceTemplate.c_str()});
+ CDCtx.MustacheTemplates.insert({"all-files", AllFilesTemplate.c_str()});
+ CDCtx.MustacheTemplates.insert({"index", IndexTemplate.c_str()});
+ CDCtx.MustacheTemplates.insert({"comments", CommentsTemplate.c_str()});
+}
diff --git a/clang-tools-extra/clang-doc/support/Utils.h b/clang-tools-extra/clang-doc/support/Utils.h
index f4ed9ec42dce4..d862f53c55b9a 100644
--- a/clang-tools-extra/clang-doc/support/Utils.h
+++ b/clang-tools-extra/clang-doc/support/Utils.h
@@ -23,4 +23,6 @@ llvm::SmallString<128> appendPathPosix(llvm::StringRef Base,
void getHtmlFiles(llvm::StringRef AssetsPath,
clang::doc::ClangDocContext &CDCtx);
+void getMdFiles(llvm::StringRef AssetsPath, clang::doc::ClangDocContext &CDCtx);
+
#endif
diff --git a/clang-tools-extra/clang-doc/tool/CMakeLists.txt b/clang-tools-extra/clang-doc/tool/CMakeLists.txt
index aef2acfde0ca3..8728a8275bed3 100644
--- a/clang-tools-extra/clang-doc/tool/CMakeLists.txt
+++ b/clang-tools-extra/clang-doc/tool/CMakeLists.txt
@@ -35,6 +35,11 @@ set(assets
navbar-template.mustache
index-template.mustache
alias-template.mustache
+ md/all-files-template.mustache
+ md/class-template.mustache
+ md/comments-partial.mustache
+ md/index-template.mustache
+ md/namespace-template.mustache
)
set(asset_dir "${CMAKE_CURRENT_SOURCE_DIR}/../assets")
diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index bc30f61264174..a6703d963aacb 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -111,20 +111,21 @@ Turn on time profiler. Generates clang-doc-tracing.json)"),
llvm::cl::init(false),
llvm::cl::cat(ClangDocCategory));
-enum OutputFormatTy { md, yaml, html, json };
-
-static llvm::cl::opt<OutputFormatTy>
- FormatEnum("format", llvm::cl::desc("Format for outputted docs."),
- llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
- "Documentation in YAML format."),
- clEnumValN(OutputFormatTy::md, "md",
- "Documentation in MD format."),
- clEnumValN(OutputFormatTy::html, "html",
- "Documentation in HTML format."),
- clEnumValN(OutputFormatTy::json, "json",
- "Documentation in JSON format")),
- llvm::cl::init(OutputFormatTy::yaml),
- llvm::cl::cat(ClangDocCategory));
+enum OutputFormatTy { md, yaml, html, json, md_mustache };
+
+static llvm::cl::opt<OutputFormatTy> FormatEnum(
+ "format", llvm::cl::desc("Format for outputted docs."),
+ llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
+ "Documentation in YAML format."),
+ clEnumValN(OutputFormatTy::md, "md",
+ "Documentation in MD format."),
+ clEnumValN(OutputFormatTy::html, "html",
+ "Documentation in HTML format."),
+ clEnumValN(OutputFormatTy::json, "json",
+ "Documentation in JSON format"),
+ clEnumValN(OutputFormatTy::md_mustache, "md_mustache",
+ "Documentation in MD format.")),
+ llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory));
static llvm::ExitOnError ExitOnErr;
@@ -138,6 +139,8 @@ static llvm::StringRef getFormatString() {
return "html";
case OutputFormatTy::json:
return "json";
+ case OutputFormatTy::md_mustache:
+ return "md_mustache";
}
llvm_unreachable("Unknown OutputFormatTy");
}
@@ -179,8 +182,10 @@ static llvm::Error getHtmlFiles(const char *Argv0,
llvm::outs() << "Asset path supply is not a directory: " << UserAssetPath
<< " falling back to default\n";
if (IsDir) {
- if (auto Err = getAssetFiles(CDCtx))
- return Err;
+ if (FormatEnum == OutputFormatTy::html) {
+ if (auto Err = getAssetFiles(CDCtx))
+ return Err;
+ }
}
void *MainAddr = (void *)(intptr_t)getExecutablePath;
std::string ClangDocPath = getExecutablePath(Argv0, MainAddr);
@@ -196,6 +201,27 @@ static llvm::Error getHtmlFiles(const char *Argv0,
return llvm::Error::success();
}
+static llvm::Error getMdFiles(const char *Argv0,
+ clang::doc::ClangDocContext &CDCtx) {
+ bool IsDir = llvm::sys::fs::is_directory(UserAssetPath);
+ if (!UserAssetPath.empty() && !IsDir)
+ llvm::outs() << "Asset path supply is not a directory: " << UserAssetPath
+ << " falling back to default\n";
+
+ void *MainAddr = (void *)(intptr_t)getExecutablePath;
+ std::string ClangDocPath = getExecutablePath(Argv0, MainAddr);
+ llvm::SmallString<128> NativeClangDocPath;
+ llvm::sys::path::native(ClangDocPath, NativeClangDocPath);
+
+ llvm::SmallString<128> AssetsPath;
+ AssetsPath = llvm::sys::path::parent_path(NativeClangDocPath);
+ llvm::sys::path::append(AssetsPath, "..", "share", "clang-doc", "md");
+
+ getMdFiles(AssetsPath, CDCtx);
+
+ return llvm::Error::success();
+}
+
/// Make the output of clang-doc deterministic by sorting the children of
/// namespaces and records.
static void
@@ -283,10 +309,13 @@ Example usage for a project using a compile commands database:
clang::doc::ClangDocContext CDCtx(
Executor->getExecutionContext(), ProjectName, PublicOnly, OutDirectory,
SourceRoot, RepositoryUrl, RepositoryCodeLinePrefix, BaseDirectory,
- {UserStylesheets.begin(), UserStylesheets.end()}, Diags, FTimeTrace);
+ {UserStylesheets.begin(), UserStylesheets.end()}, Diags,
+ getFormatString(), FTimeTrace);
if (Format == "html")
ExitOnErr(getHtmlFiles(argv[0], CDCtx));
+ else if (Format == "md_mustache")
+ ExitOnErr(getMdFiles(argv[0], CDCtx));
llvm::timeTraceProfilerBegin("Executor Launch", "total runtime");
// Mapping phase
diff --git a/clang-tools-extra/test/clang-doc/basic-project.mustache.test b/clang-tools-extra/test/clang-doc/basic-project.mustache.test
index d29bdaf8a05fd..6758638641d5b 100644
--- a/clang-tools-extra/test/clang-doc/basic-project.mustache.test
+++ b/clang-tools-extra/test/clang-doc/basic-project.mustache.test
@@ -7,6 +7,14 @@
// RUN: FileCheck %s -input-file=%t/docs/html/GlobalNamespace/_ZTV9Rectangle.html -check-prefix=HTML-RECTANGLE
// RUN: FileCheck %s -input-file=%t/docs/html/GlobalNamespace/_ZTV6Circle.html -check-prefix=HTML-CIRCLE
+// RUN: clang-doc --format=md_mustache --output=%t/docs --executor=all-TUs %t/build/compile_commands.json
+// RUN: FileCheck %s -input-file=%t/docs/md/all_files.md -check-prefixes=MD-ALL-FILES
+// RUN: FileCheck %s -input-file=%t/docs/md/index.md -check-prefixes=MD-INDEX
+// RUN: FileCheck %s -input-file=%t/docs/md/GlobalNamespace/_ZTV5Shape.md -check-prefixes=MD-SHAPE
+// RUN: FileCheck %s -input-file=%t/docs/md/GlobalNamespace/_ZTV10Calculator.md -check-prefixes=MD-CALC
+// RUN: FileCheck %s -input-file=%t/docs/md/GlobalNamespace/_ZTV9Rectangle.md -check-prefixes=MD-RECTANGLE
+// RUN: FileCheck %s -input-file=%t/docs/md/GlobalNamespace/_ZTV6Circle.md -check-prefixes=MD-CIRCLE
+
HTML-SHAPE-LABEL:<html lang="en-US">
HTML-SHAPE-NEXT: <head>
HTML-SHAPE: </head>
@@ -524,3 +532,122 @@ HTML-CIRCLE-NEXT: </div>
HTML-CIRCLE-NEXT: </main>
HTML-CIRCLE-NEXT: </body>
HTML-CIRCLE-NEXT: </html>
+
+MD-CALC: # class Calculator
+MD-CALC: *Defined at .{{[\/]}}include{{[\/]}}Calculator.h#8*
+MD-CALC: **brief** A simple calculator class.
+MD-CALC: Provides basic arithmetic operations.
+MD-CALC: ## Members
+MD-CALC: public int public_val
+MD-CALC: public static const int static_val
+MD-CALC: ## Functions
+MD-CALC: ### add
+MD-CALC: *public int add(int a, int b)*
+MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#3*
+MD-CALC: **brief** Adds two integers.
+MD-CALC: **a** First integer.
+MD-CALC: **b** Second integer.
+MD-CALC: **return** int The sum of a and b.
+MD-CALC: ### subtract
+MD-CALC: *public int subtract(int a, int b)*
+MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#7*
+MD-CALC: **brief** Subtracts the second integer from the first.
+MD-CALC: **a** First integer.
+MD-CALC: **b** Second integer.
+MD-CALC: **return** int The result of a - b.
+MD-CALC: ### multiply
+MD-CALC: *public int multiply(int a, int b)*
+MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#11*
+MD-CALC: **brief** Multiplies two integers.
+MD-CALC: **a** First integer.
+MD-CALC: **b** Second integer.
+MD-CALC: **return** int The product of a and b.
+MD-CALC: ### divide
+MD-CALC: *public double divide(int a, int b)*
+MD-CALC: *Defined at .{{[\/]}}src{{[\/]}}Calculator.cpp#15*
+MD-CALC: **brief** Divides the first integer by the second.
+MD-CALC: **a** First integer.
+MD-CALC: **b** Second integer.
+MD-CALC: **return** double The result of a / b.
+MD-CALC: **throw** if b is zero.
+MD-CALC: ### mod
+MD-CALC: *public static int mod(int a, int b)*
+MD-CALC: *Defined at ./include{{[\/]}}Calculator.h#54*
+MD-CALC: **brief** Performs the mod operation on integers.
+MD-CALC: **a** First integer.
+MD-CALC: **b** Second integer.
+MD-CALC: **return** The result of a % b.
+
+MD-CIRCLE: # class Circle
+MD-CIRCLE: *Defined at .{{[\/]}}include{{[\/]}}Circle.h#10*
+MD-CIRCLE: **brief** Circle class derived from Shape.
+MD-CIRCLE: Represents a circle with a given radius.
+MD-CIRCLE: Inherits from Shape
+MD-CIRCLE: ## Members
+MD-CIRCLE: private double radius_
+MD-CIRCLE: ## Functions
+MD-CIRCLE: ### Circle
+MD-CIRCLE: *public void Circle(double radius)*
+MD-CIRCLE: *Defined at .{{[\/]}}src{{[\/]}}Circle.cpp#3*
+MD-CIRCLE: **brief** Constructs a new Circle object.
+MD-CIRCLE: **radius** Radius of the circle.
+MD-CIRCLE: ### area
+MD-CIRCLE: *public double area()*
+MD-CIRCLE: *Defined at .{{[\/]}}src{{[\/]}}Circle.cpp#5*
+MD-CIRCLE: **brief** Calculates the area of the circle.
+MD-CIRCLE: **return** double The area of the circle.
+MD-CIRCLE: ### perimeter
+MD-CIRCLE: *public double perimeter()*
+MD-CIRCLE: *Defined at .{{[\/]}}src{{[\/]}}Circle.cpp#9*
+MD-CIRCLE: **brief** Calculates the perimeter of the circle.
+MD-CIRCLE: **return** double The perimeter of the circle.
+
+MD-RECTANGLE: # class Rectangle
+MD-RECTANGLE: *Defined at .{{[\/]}}include{{[\/]}}Rectangle.h#10*
+MD-RECTANGLE: **brief** Rectangle class derived from Shape.
+MD-RECTANGLE: Represents a rectangle with a given width and height.
+MD-RECTANGLE: Inherits from Shape
+MD-RECTANGLE: ## Members
+MD-RECTANGLE: private double width_
+MD-RECTANGLE: private double height_
+MD-RECTANGLE: ## Functions
+MD-RECTANGLE: ### Rectangle
+MD-RECTANGLE: *public void Rectangle(double width, double height)*
+MD-RECTANGLE: *Defined at .{{[\/]}}src{{[\/]}}Rectangle.cpp#3*
+MD-RECTANGLE: **brief** Constructs a new Rectangle object.
+MD-RECTANGLE: **width** Width of the rectangle.
+MD-RECTANGLE: **height** Height of the rectangle.
+MD-RECTANGLE: ### area
+MD-RECTANGLE: *public double area()*
+MD-RECTANGLE: *Defined at .{{[\/]}}src{{[\/]}}Rectangle.cpp#6*
+MD-RECTANGLE: **brief** Calculates the area of the rectangle.
+MD-RECTANGLE: **return** double The area of the rectangle.
+MD-RECTANGLE: ### perimeter
+MD-RECTANGLE: *public double perimeter()*
+MD-RECTANGLE: *Defined at .{{[\/]}}src{{[\/]}}Rectangle.cpp#10*
+MD-RECTANGLE: **brief** Calculates the perimeter of the rectangle.
+MD-RECTANGLE: **return** double The perimeter of the rectangle.
+
+MD-SHAPE: # class Shape
+MD-SHAPE: *Defined at .{{[\/]}}include{{[\/]}}Shape.h#8*
+MD-SHAPE: **brief** Abstract base class for shapes.
+MD-SHAPE: Provides a common interface for different types of shapes.
+MD-SHAPE: ## Functions
+MD-SHAPE: ### area
+MD-SHAPE: *public double area()*
+MD-SHAPE: **brief** Calculates the area of the shape.
+MD-SHAPE: **return** double The area of the shape.
+MD-SHAPE: ### perimeter
+MD-SHAPE: *public double perimeter()*
+MD-SHAPE: **brief** Calculates the perimeter of the shape.
+MD-SHAPE: **return** double The perimeter of the shape.
+MD-SHAPE: ### ~Shape
+MD-SHAPE: *public void ~Shape()*
+MD-SHAPE: *Defined at .{{[\/]}}include{{[\/]}}Shape.h#13*
+MD-SHAPE: **brief** Virtual destructor.
+
+MD-ALL-FILES: # All Files
+MD-ALL-FILES: ## [GlobalNamespace](GlobalNamespace{{[\/]}}index.md)
+
+MD-INDEX: # C/C++ Reference
+MD-INDEX: * Namespace: [GlobalNamespace](GlobalNamespace)
diff --git a/clang-tools-extra/test/clang-doc/builtin_types.cpp b/clang-tools-extra/test/clang-doc/builtin_types.cpp
index 6c1fc8a1d7879..3f416261ff7ea 100644
--- a/clang-tools-extra/test/clang-doc/builtin_types.cpp
+++ b/clang-tools-extra/test/clang-doc/builtin_types.cpp
@@ -1,5 +1,5 @@
// RUN: rm -rf %t
-// RUN: mkdir -p %t/yaml %t/md
+// RUN: mkdir -p %t/yaml %t/md %t/md_mustache
// RUN: clang-doc --doxygen --executor=standalone %s -output=%t/yaml
// RUN: FileCheck %s < %t/yaml/index.yaml --check-prefix=YAML
@@ -7,6 +7,9 @@
// RUN: clang-doc --doxygen --executor=standalone %s -output=%t/md --format=md
// RUN: FileCheck %s < %t/md/GlobalNamespace/index.md --check-prefix=MD
+// RUN: clang-doc --doxygen --executor=standalone %s -output=%t/md_mustache --format=md_mustache
+// RUN: FileCheck %s < %t/md/GlobalNamespace/index.md --check-prefix=MD-MUSTACHE
+
// YAML: ---
// YAML-NEXT: USR: '0000000000000000000000000000000000000000'
// YAML-NEXT: ChildFunctions:
@@ -14,6 +17,9 @@
// MD: # Global Namespace
// MD: ## Functions
+// MD-MUSTACHE: # Global Namespace
+// MD-MUSTACHE: ## Functions
+
extern bool b();
// YAML-NEXT: - USR: '88A104C263241E354ECF5B55B04AE8CEAD625B71'
@@ -29,6 +35,9 @@ extern bool b();
// MD: ### b
// MD: *bool b()*
+// MD-MUSTACHE: ### b
+// MD-MUSTACHE: *bool b()*
+
char c();
// YAML-NEXT: - USR: 'EA3287837B3F175C8DB154406B4DAD2924F479B5'
@@ -44,6 +53,9 @@ char c();
// MD: ### c
// MD: *char c()*
+// MD-MUSTACHE: ### c
+// MD-MUSTACHE: *char c()*
+
double d();
// YAML-NEXT: - USR: '60A47E4696CEFC411AB2E1EEFA2DD914E2A7E450'
@@ -59,6 +71,9 @@ double d();
// MD: ### d
// MD: *double d()*
+// MD-MUSTACHE: ### d
+// MD-MUSTACHE: *double d()*
+
float f();
// YAML-NEXT: - USR: 'B3A9EC6BECD5869CF3ACDFB25153CFE6BBDD5EAB'
@@ -74,6 +89,9 @@ float f();
// MD: ### f
// MD: *float f()*
+// MD-MUSTACHE: ### f
+// MD-MUSTACHE: *float f()*
+
int i();
// YAML-NEXT: - USR: '307041280A81EB46F949A94AD52587C659FD801C'
@@ -89,6 +107,9 @@ int i();
// MD: ### i
// MD: *int i()*
+// MD-MUSTACHE: ### i
+// MD-MUSTACHE: *int i()*
+
long l();
// YAML-NEXT: - USR: 'A1CE9AB0064C412F857592E01332C641C1A06F37'
@@ -104,6 +125,9 @@ long l();
// MD: ### l
// MD: *long l()*
+// MD-MUSTACHE: ### l
+// MD-MUSTACHE: *long l()*
+
long long ll();
// YAML-NEXT: - USR: '5C2C44ED4825C066EF6ED796863586F343C8BCA9'
@@ -119,6 +143,9 @@ long long ll();
// MD: ### ll
// MD: *long long ll()*
+// MD-MUSTACHE: ### ll
+// MD-MUSTACHE: *long long ll()*
+
short s();
// YAML-NEXT: - USR: '412341570FD3AD2C3A1E9A1DE7B3C01C07BEACFE'
@@ -134,3 +161,6 @@ short s();
// MD: ### s
// MD: *short s()*
+
+// MD-MUSTACHE: ### s
+// MD-MUSTACHE: *short s()*
diff --git a/clang-tools-extra/test/clang-doc/comments-in-macros.cpp b/clang-tools-extra/test/clang-doc/comments-in-macros.cpp
index 9e022314edaeb..20bbf4cd087c0 100644
--- a/clang-tools-extra/test/clang-doc/comments-in-macros.cpp
+++ b/clang-tools-extra/test/clang-doc/comments-in-macros.cpp
@@ -2,12 +2,14 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: clang-doc --format=md --doxygen --output=%t --executor=standalone %s
+// RUN: clang-doc --format=html --doxygen --output=%t --executor=standalone %s
+// RUN: clang-doc --format=md_mustache --doxygen --output=%t --executor=standalone %s
// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.md --check-prefix=MD-MYCLASS-LINE
// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.md --check-prefix=MD-MYCLASS
-
-// RUN: clang-doc --format=html --doxygen --output=%t --executor=standalone %s
// RUN: FileCheck %s < %t/html/GlobalNamespace/_ZTV7MyClass.html --check-prefix=HTML-MYCLASS-LINE
// RUN: FileCheck %s < %t/html/GlobalNamespace/_ZTV7MyClass.html --check-prefix=HTML-MYCLASS
+// RUN: FileCheck %s < %t/md/GlobalNamespace/_ZTV7MyClass.md --check-prefix=MD-MUSTACHE-MYCLASS-LINE
+// RUN: FileCheck %s < %t/md/GlobalNamespace/_ZTV7MyClass.md --check-prefix=MD-MUSTACHE-MYCLASS
#define DECLARE_METHODS \
/**
@@ -21,6 +23,9 @@
// MD-MYCLASS: *public int Add(int a, int b)*
// MD-MYCLASS: **brief** Declare a method to calculate the sum of two numbers
+// MD-MUSTACHE-MYCLASS: ### Add
+// MD-MUSTACHE-MYCLASS: *public int Add(int a, int b)*
+// MD-MUSTACHE-MYCLASS: **brief** Declare a method to calculate the sum of two numbers
// HTML-MYCLASS: <pre><code class="language-cpp code-clang-doc">int Add (int a, int b)</code></pre>
// HTML-MYCLASS: <div class="doc-card">
@@ -28,11 +33,11 @@
// HTML-MYCLASS: <p> Declare a method to calculate the sum of two numbers</p>
// HTML-MYCLASS: </div>
-
class MyClass {
public:
-// MD-MYCLASS-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}comments-in-macros.cpp#[[@LINE-2]]*
-// HTML-MYCLASS-LINE: <p>Defined at line [[@LINE-3]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}comments-in-macros.cpp</p>
+// MD-MYCLASS-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}comments-in-macros.cpp#[[@LINE+3]]*
+// HTML-MYCLASS-LINE: <p>Defined at line [[@LINE+2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}comments-in-macros.cpp</p>
+// MD-MUSTACHE-MYCLASS-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}comments-in-macros.cpp#[[@LINE+1]]*
DECLARE_METHODS
};
diff --git a/clang-tools-extra/test/clang-doc/enum.cpp b/clang-tools-extra/test/clang-doc/enum.cpp
index 00815ff468780..c9bf716fc001a 100644
--- a/clang-tools-extra/test/clang-doc/enum.cpp
+++ b/clang-tools-extra/test/clang-doc/enum.cpp
@@ -20,12 +20,21 @@
// COM: FIXME: Add enum value comments to template
+// RUN: clang-doc --format=md_mustache --doxygen --output=%t --executor=standalone %s
+// RUN: FileCheck %s < %t/md/GlobalNamespace/index.md --check-prefix=MD-MUSTACHE-INDEX-LINE
+// RUN: FileCheck %s < %t/md/GlobalNamespace/index.md --check-prefix=MD-MUSTACHE-INDEX
+// RUN: FileCheck %s < %t/md/GlobalNamespace/_ZTV7Animals.md --check-prefix=MD-MUSTACHE-ANIMAL-LINE
+// RUN: FileCheck %s < %t/md/GlobalNamespace/_ZTV7Animals.md --check-prefix=MD-MUSTACHE-ANIMAL
+// RUN: FileCheck %s < %t/md/Vehicles/index.md --check-prefix=MD-MUSTACHE-VEHICLES-LINE
+// RUN: FileCheck %s < %t/md/Vehicles/index.md --check-prefix=MD-MUSTACHE-VEHICLES
+
/**
* @brief For specifying RGB colors
*/
enum Color {
// MD-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+ // MD-MUSTACHE-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-3]]*
Red, ///< Comment 1
Green, ///< Comment 2
Blue ///< Comment 3
@@ -71,12 +80,21 @@ enum Color {
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-45]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
// HTML-INDEX-NEXT: </div>
+// MD-MUSTACHE-INDEX: ## Enums
+// MD-MUSTACHE-INDEX: | enum Color |
+// MD-MUSTACHE-INDEX: --
+// MD-MUSTACHE-INDEX: | Red |
+// MD-MUSTACHE-INDEX: | Green |
+// MD-MUSTACHE-INDEX: | Blue |
+// MD-MUSTACHE-INDEX: **brief** For specifying RGB colors
+
/**
* @brief Shape Types
*/
enum class Shapes {
// MD-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+ // MD-MUSTACHE-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-3]]*
/// Comment 1
Circle,
@@ -275,6 +293,7 @@ class FilePermissions {
class Animals {
// MD-ANIMAL-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-ANIMAL-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+ // MD-MUSTACHE-ANIMAL-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-3]]*
public:
/**
* @brief specify what animal the class is
@@ -282,6 +301,7 @@ class Animals {
enum AnimalType {
// MD-ANIMAL-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-ANIMAL-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+ // MD-MUSTACHE-ANIMAL-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-3]]*
Dog, ///< Man's best friend
Cat, ///< Man's other best friend
Iguana ///< A lizard
@@ -319,9 +339,15 @@ class Animals {
// HTML-ANIMAL-NEXT: <p> specify what animal the class is</p>
// HTML-ANIMAL-NEXT: </div>
// HTML-ANIMAL-NEXT: </div>
+<<<<<<< HEAD
// HTML-ANIMAL-NEXT: <p>Defined at line [[@LINE-40]] of file {{.*}}enum.cpp</p>
// HTML-ANIMAL-NEXT: </div>
// HTML-ANIMAL-NEXT: </section>
+=======
+// HTML-ANIMAL-NEXT: <p>Defined at line 135 of file {{.*}}enum.cpp</p>
+// HTML-ANIMAL-NEXT: </div>
+// HTML-ANIMAL-NEXT: </section>
+>>>>>>> ca036029f156 (fix the fix)
// MD-ANIMAL: # class Animals
// MD-ANIMAL: ## Enums
@@ -332,6 +358,15 @@ class Animals {
// MD-ANIMAL: | Iguana |
// MD-ANIMAL: **brief** specify what animal the class is
+// MD-MUSTACHE-ANIMAL: # class Animals
+// MD-MUSTACHE-ANIMAL: ## Enums
+// MD-MUSTACHE-ANIMAL: | enum AnimalType |
+// MD-MUSTACHE-ANIMAL: --
+// MD-MUSTACHE-ANIMAL: | Dog |
+// MD-MUSTACHE-ANIMAL: | Cat |
+// MD-MUSTACHE-ANIMAL: | Iguana |
+// MD-MUSTACHE-ANIMAL: **brief** specify what animal the class is
+
namespace Vehicles {
/**
* @brief specify type of car
@@ -339,6 +374,7 @@ namespace Vehicles {
enum Car {
// MD-VEHICLES-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-VEHICLES-LINE: Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp
+ // MD-MUSTACHE-VEHICLES-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-3]]*
Sedan, ///< Comment 1
SUV, ///< Comment 2
@@ -393,6 +429,16 @@ enum Car {
// HTML-VEHICLES-NEXT: <p>Defined at line [[@LINE-54]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
// HTML-VEHICLES-NEXT: </div>
+// MD-MUSTACHE-VEHICLES: # namespace Vehicles
+// MD-MUSTACHE-VEHICLES: ## Enums
+// MD-MUSTACHE-VEHICLES: | enum Car |
+// MD-MUSTACHE-VEHICLES: --
+// MD-MUSTACHE-VEHICLES: | Sedan |
+// MD-MUSTACHE-VEHICLES: | SUV |
+// MD-MUSTACHE-VEHICLES: | Pickup |
+// MD-MUSTACHE-VEHICLES: | Hatchback |
+// MD-MUSTACHE-VEHICLES: **brief** specify type of car
+
enum ColorUserSpecified {
RedUserSpecified = 'A',
GreenUserSpecified = 2,
@@ -431,3 +477,9 @@ enum ColorUserSpecified {
// HTML-INDEX-NEXT: </table>
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-36]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
// HTML-INDEX-NEXT: </div>
+
+// MD-MUSTACHE-INDEX: | enum ColorUserSpecified |
+// MD-MUSTACHE-INDEX: --
+// MD-MUSTACHE-INDEX: | RedUserSpecified |
+// MD-MUSTACHE-INDEX: | GreenUserSpecified |
+// MD-MUSTACHE-INDEX: | BlueUserSpecified |
diff --git a/clang-tools-extra/test/clang-doc/index.cpp b/clang-tools-extra/test/clang-doc/index.cpp
index af72720740fae..2004e6ae5659a 100644
--- a/clang-tools-extra/test/clang-doc/index.cpp
+++ b/clang-tools-extra/test/clang-doc/index.cpp
@@ -13,11 +13,13 @@ namespace inner {
// CHECK-JSON-NEXT: {
// CHECK-JSON-NEXT: "Name": "GlobalNamespace",
// CHECK-JSON-NEXT: "QualName": "GlobalNamespace",
+// CHECK-JSON-NEXT: "Type": "namespace",
// CHECK-JSON-NEXT: "USR": "0000000000000000000000000000000000000000"
// CHECK-JSON-NEXT: },
// CHECK-JSON-NEXT: {
// CHECK-JSON-NEXT: "Name": "inner",
// CHECK-JSON-NEXT: "QualName": "inner",
+// CHECK-JSON-NEXT: "Type": "namespace",
// CHECK-JSON-NEXT: "USR": "{{([0-9A-F]{40})}}"
// CHECK-JSON-NEXT: }
// CHECK-JSON-NEXT: ]
@@ -62,3 +64,5 @@ namespace inner {
// CHECK-HTML-NEXT: </div>
// CHECK-HTML-NEXT: </div>
// CHECK-HTML-NEXT: </main>
+
+// COM: TODO: Add Markdown index test
diff --git a/clang-tools-extra/test/clang-doc/json/class.cpp b/clang-tools-extra/test/clang-doc/json/class.cpp
index 6783e71a201db..3bb9f5e6ec6bb 100644
--- a/clang-tools-extra/test/clang-doc/json/class.cpp
+++ b/clang-tools-extra/test/clang-doc/json/class.cpp
@@ -142,7 +142,6 @@ struct MyClass {
// CHECK-NEXT: ],
// CHECK-NEXT: "VerticalDisplay": false
// CHECK-NEXT: }
-// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "Description": {
@@ -164,12 +163,12 @@ struct MyClass {
// CHECK-NEXT: "QualName": "Foo",
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}"
// CHECK-NEXT: }
-// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000"
// CHECK-NEXT: }
// CHECK-NEXT: ],
// CHECK-NEXT: "HasContexts": true,
// CHECK-NEXT: "HasEnums": true,
// CHECK-NEXT: "HasFriends": true,
+// CHECK-NEXT: "HasMembers": true,
// CHECK-NEXT: "HasPrivateMembers": true,
// CHECK-NEXT: "HasProtectedMembers": true,
// CHECK-NEXT: "HasProtectedMethods": true,
diff --git a/clang-tools-extra/test/clang-doc/json/namespace.cpp b/clang-tools-extra/test/clang-doc/json/namespace.cpp
index 59f6f5491cdc5..a801d86ffffdd 100644
--- a/clang-tools-extra/test/clang-doc/json/namespace.cpp
+++ b/clang-tools-extra/test/clang-doc/json/namespace.cpp
@@ -125,7 +125,6 @@ typedef int MyTypedef;
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: ],
-// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000"
// CHECK-NEXT: "Variables": [
// CHECK-NEXT: {
// CHECK-NEXT: "End": true,
diff --git a/clang-tools-extra/test/clang-doc/namespace.cpp b/clang-tools-extra/test/clang-doc/namespace.cpp
index 49e61dc61872e..1e868f8c78bf7 100644
--- a/clang-tools-extra/test/clang-doc/namespace.cpp
+++ b/clang-tools-extra/test/clang-doc/namespace.cpp
@@ -41,18 +41,43 @@
// COM: FIXME: Add global functions to the namespace template
// COM: FIXME: Add namespaces to the namespace template
+// RUN: clang-doc --format=md_mustache --output=%t --executor=standalone %s
+// RUN: FileCheck %s < %t/md/@nonymous_namespace/_ZTVN12_GLOBAL__N_19AnonClassE.md -check-prefix=MD-MUSTACHE-ANON-CLASS-LINE
+// RUN: FileCheck %s < %t/md/@nonymous_namespace/_ZTVN12_GLOBAL__N_19AnonClassE.md -check-prefix=MD-MUSTACHE-ANON-CLASS
+// RUN: FileCheck %s < %t/md/@nonymous_namespace/index.md -check-prefix=MD-MUSTACHE-ANON-INDEX-LINE
+// RUN: FileCheck %s < %t/md/@nonymous_namespace/index.md -check-prefix=MD-MUSTACHE-ANON-INDEX
+// RUN: FileCheck %s < %t/md/AnotherNamespace/_ZTVN16AnotherNamespace23ClassInAnotherNamespaceE.md -check-prefix=MD-MUSTACHE-ANOTHER-CLASS-LINE
+// RUN: FileCheck %s < %t/md/AnotherNamespace/_ZTVN16AnotherNamespace23ClassInAnotherNamespaceE.md -check-prefix=MD-MUSTACHE-ANOTHER-CLASS
+// RUN: FileCheck %s < %t/md/AnotherNamespace/index.md -check-prefix=MD-MUSTACHE-ANOTHER-INDEX-LINE
+// RUN: FileCheck %s < %t/md/AnotherNamespace/index.md -check-prefix=MD-MUSTACHE-ANOTHER-INDEX
+// RUN: FileCheck %s < %t/md/PrimaryNamespace/NestedNamespace/_ZTVN16PrimaryNamespace15NestedNamespace22ClassInNestedNamespaceE.md -check-prefix=MD-MUSTACHE-NESTED-CLASS-LINE
+// RUN: FileCheck %s < %t/md/PrimaryNamespace/NestedNamespace/_ZTVN16PrimaryNamespace15NestedNamespace22ClassInNestedNamespaceE.md -check-prefix=MD-MUSTACHE-NESTED-CLASS
+// RUN: FileCheck %s < %t/md/PrimaryNamespace/NestedNamespace/index.md -check-prefix=MD-MUSTACHE-NESTED-INDEX-LINE
+// RUN: FileCheck %s < %t/md/PrimaryNamespace/NestedNamespace/index.md -check-prefix=MD-MUSTACHE-NESTED-INDEX
+// RUN: FileCheck %s < %t/md/PrimaryNamespace/index.md -check-prefix=MD-MUSTACHE-PRIMARY-INDEX-LINE
+// RUN: FileCheck %s < %t/md/PrimaryNamespace/index.md -check-prefix=MD-MUSTACHE-PRIMARY-INDEX
+// RUN: FileCheck %s < %t/md/PrimaryNamespace/_ZTVN16PrimaryNamespace23ClassInPrimaryNamespaceE.md -check-prefix=MD-MUSTACHE-PRIMARY-CLASS-LINE
+// RUN: FileCheck %s < %t/md/PrimaryNamespace/_ZTVN16PrimaryNamespace23ClassInPrimaryNamespaceE.md -check-prefix=MD-MUSTACHE-PRIMARY-CLASS
+// RUN: FileCheck %s < %t/md/GlobalNamespace/index.md -check-prefix=MD-MUSTACHE-GLOBAL-INDEX
+// RUN: FileCheck %s < %t/md/all_files.md -check-prefix=MD-MUSTACHE-ALL-FILES
+// RUN: FileCheck %s < %t/md/index.md -check-prefix=MD-MUSTACHE-INDEX
+
// Anonymous Namespace
namespace {
void anonFunction() {}
// MD-ANON-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
-// HTML-ANON-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// MD-MUSTACHE-ANON-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-2]]*
+// HTML-ANON-INDEX-LINE: <p>Defined at line [[@LINE-3]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
class AnonClass {};
// MD-ANON-CLASS-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
-// HTML-ANON-CLASS-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// MD-MUSTACHE-ANON-CLASS-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-2]]*
+// HTML-ANON-CLASS-LINE: <p>Defined at line [[@LINE-3]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
// MD-ANON-CLASS: # class AnonClass
+// MD-MUSTACHE-ANON-CLASS: # class AnonClass
// HTML-ANON-CLASS: <h1 class="hero__title-large">class AnonClass</h1>
+// MUSTACHE-ANON-CLASS: <h1 class="hero__title-large">class AnonClass</h1>
} // namespace
// MD-ANON-INDEX: # namespace @nonymous_namespace
@@ -77,6 +102,14 @@ class AnonClass {};
// HTML-ANON-INDEX-NOT: <h2 id="Functions">Functions</h2>
// HTML-ANON-INDEX-NOT: <h3 id="{{([0-9A-F]{40})}}">anonFunction</h3>
// HTML-ANON-INDEX-NOT: <p>void anonFunction()</p>
+// MD-MUSTACHE-ANON-INDEX: # namespace @nonymous_namespace
+// MD-MUSTACHE-ANON-INDEX: Anonymous Namespace
+// MD-MUSTACHE-ANON-INDEX: ## Records
+// MD-MUSTACHE-ANON-INDEX: * [AnonClass](AnonClass.md)
+// MD-MUSTACHE-ANON-INDEX: ## Functions
+// MD-MUSTACHE-ANON-INDEX: ### anonFunction
+// MD-MUSTACHE-ANON-INDEX: *void anonFunction()*
+
// Primary Namespace
namespace PrimaryNamespace {
@@ -84,11 +117,13 @@ namespace PrimaryNamespace {
void functionInPrimaryNamespace() {}
// MD-PRIMARY-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
// HTML-PRIMARY-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// MD-MUSTACHE-PRIMARY-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-3]]*
// Class in PrimaryNamespace
class ClassInPrimaryNamespace {};
// MD-PRIMARY-CLASS-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
// HTML-PRIMARY-CLASS-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// MD-MUSTACHE-PRIMARY-CLASS-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-3]]*
// MD-PRIMARY-CLASS: # class ClassInPrimaryNamespace
// MD-PRIMARY-CLASS: Class in PrimaryNamespace
@@ -97,19 +132,27 @@ class ClassInPrimaryNamespace {};
// HTML-PRIMARY-CLASS: <a href="../GlobalNamespace/index.html"><div class="navbar-breadcrumb-item">Global Namespace</div></a>::
// HTML-PRIMARY-CLASS: <a href="./index.html"><div class="navbar-breadcrumb-item">PrimaryNamespace</div></a>
// HTML-PRIMARY-CLASS: </div>
+
+// MD-MUSTACHE-PRIMARY-CLASS: # class ClassInPrimaryNamespace
+// MD-MUSTACHE-PRIMARY-CLASS: Class in PrimaryNamespace
+
// HTML-PRIMARY-CLASS: <h1 class="hero__title-large">class ClassInPrimaryNamespace</h1>
+// MUSTACHE-PRIMARY-CLASS: <h1 class="hero__title-large">class ClassInPrimaryNamespace</h1>
+
// Nested namespace
namespace NestedNamespace {
// Function in NestedNamespace
void functionInNestedNamespace() {}
// MD-NESTED-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
// HTML-NESTED-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// MD-MUSTACHE-NESTED-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-3]]*
// Class in NestedNamespace
class ClassInNestedNamespace {};
// MD-NESTED-CLASS-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
// HTML-NESTED-CLASS-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// MD-MUSTACHE-NESTED-CLASS-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-3]]*
// MD-NESTED-CLASS: # class ClassInNestedNamespace
// MD-NESTED-CLASS: Class in NestedNamespace
@@ -119,7 +162,13 @@ class ClassInNestedNamespace {};
// HTML-NESTED-CLASS: <a href="../index.html"><div class="navbar-breadcrumb-item">PrimaryNamespace</div></a>::
// HTML-NESTED-CLASS: <a href="./index.html"><div class="navbar-breadcrumb-item">NestedNamespace</div></a>
// HTML-NESTED-CLASS: </div>
+
+// MD-MUSTACHE-NESTED-CLASS: # class ClassInNestedNamespace
+// MD-MUSTACHE-NESTED-CLASS: Class in NestedNamespace
+
// HTML-NESTED-CLASS: <h1 class="hero__title-large">class ClassInNestedNamespace</h1>
+
+// MUSTACHE-NESTED-CLASS: <h1 class="hero__title-large">class ClassInNestedNamespace</h1>
} // namespace NestedNamespace
// MD-NESTED-INDEX: # namespace NestedNamespace
@@ -150,8 +199,17 @@ class ClassInNestedNamespace {};
// HTML-NESTED-INDEX: <p> Function in NestedNamespace</p>
// HTML-NESTED-INDEX: </div>
// HTML-NESTED-INDEX: </div>
-// HTML-NESTED-INDEX: <p>Defined at line 105 of file {{.*}}namespace.cpp</p>
+// HTML-NESTED-INDEX: <p>Defined at line 146 of file {{.*}}namespace.cpp</p>
// HTML-NESTED-INDEX: </div>
+// MD-MUSTACHE-NESTED-INDEX: # namespace NestedNamespace
+// MD-MUSTACHE-NESTED-INDEX: Nested namespace
+// MD-MUSTACHE-NESTED-INDEX: ## Records
+// MD-MUSTACHE-NESTED-INDEX: * [ClassInNestedNamespace](ClassInNestedNamespace.md)
+// MD-MUSTACHE-NESTED-INDEX: ## Functions
+// MD-MUSTACHE-NESTED-INDEX: ### functionInNestedNamespace
+// MD-MUSTACHE-NESTED-INDEX: *void functionInNestedNamespace()*
+// MD-MUSTACHE-NESTED-INDEX: Function in NestedNamespace
+
} // namespace PrimaryNamespace
// MD-PRIMARY-INDEX: # namespace PrimaryNamespace
@@ -185,19 +243,40 @@ class ClassInNestedNamespace {};
// HTML-PRIMARY-INDEX: <p> Function in PrimaryNamespace</p>
// HTML-PRIMARY-INDEX: </div>
// HTML-PRIMARY-INDEX: </div>
-// HTML-PRIMARY-INDEX: <p>Defined at line 84 of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// HTML-PRIMARY-INDEX: <p>Defined at line 117 of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
// HTML-PRIMARY-INDEX: </div>
+// HTML-PRIMARY-INDEX <h2>Inner Classes</h2>
+// HTML-PRIMARY-INDEX <ul class="class-container">
+// HTML-PRIMARY-INDEX <li id="{{([0-9A-F]{40})}}" style="max-height: 40px;">
+// HTML-PRIMARY-INDEX <a href="_ZTVN16PrimaryNamespace23ClassInPrimaryNamespaceE.html">
+// HTML-PRIMARY-INDEX <pre><code class="language-cpp code-clang-doc">class ClassInPrimaryNamespace</code></pre>
+// HTML-PRIMARY-INDEX </a>
+// HTML-PRIMARY-INDEX </li>
+// HTML-PRIMARY-INDEX </ul>
+// MD-MUSTACHE-PRIMARY-INDEX: # namespace PrimaryNamespace
+// MD-MUSTACHE-PRIMARY-INDEX: Primary Namespace
+// MD-MUSTACHE-PRIMARY-INDEX: ## Namespaces
+// MD-MUSTACHE-PRIMARY-INDEX: * [NestedNamespace](NestedNamespace{{[\/]}}index.md)
+// MD-MUSTACHE-PRIMARY-INDEX: ## Records
+// MD-MUSTACHE-PRIMARY-INDEX: * [ClassInPrimaryNamespace](ClassInPrimaryNamespace.md)
+// MD-MUSTACHE-PRIMARY-INDEX: ## Functions
+// MD-MUSTACHE-PRIMARY-INDEX: ### functionInPrimaryNamespace
+// MD-MUSTACHE-PRIMARY-INDEX: *void functionInPrimaryNamespace()*
+// MD-MUSTACHE-PRIMARY-INDEX: Function in PrimaryNamespace
+
// AnotherNamespace
namespace AnotherNamespace {
// Function in AnotherNamespace
void functionInAnotherNamespace() {}
// MD-ANOTHER-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
// HTML-ANOTHER-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// MD-MUSTACHE-ANOTHER-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-3]]*
// Class in AnotherNamespace
class ClassInAnotherNamespace {};
// MD-ANOTHER-CLASS-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-1]]*
// HTML-ANOTHER-CLASS-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// MD-MUSTACHE-ANOTHER-CLASS-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp#[[@LINE-3]]*
// MD-ANOTHER-CLASS: # class ClassInAnotherNamespace
// MD-ANOTHER-CLASS: Class in AnotherNamespace
@@ -206,8 +285,14 @@ class ClassInAnotherNamespace {};
// HTML-ANOTHER-CLASS: <a href="../GlobalNamespace/index.html"><div class="navbar-breadcrumb-item">Global Namespace</div></a>::
// HTML-ANOTHER-CLASS: <a href="./index.html"><div class="navbar-breadcrumb-item">AnotherNamespace</div></a>
// HTML-ANOTHER-CLASS: </div>
+
+// MD-MUSTACHE-ANOTHER-CLASS: # class ClassInAnotherNamespace
+// MD-MUSTACHE-ANOTHER-CLASS: Class in AnotherNamespace
+
// HTML-ANOTHER-CLASS: <h1 class="hero__title-large">class ClassInAnotherNamespace</h1>
+// MUSTACHE-ANOTHER-CLASS: <h1 class="hero__title-large">class ClassInAnotherNamespace</h1>
+
} // namespace AnotherNamespace
// MD-ANOTHER-INDEX: # namespace AnotherNamespace
@@ -237,10 +322,19 @@ class ClassInAnotherNamespace {};
// HTML-ANOTHER-INDEX: <p> Function in AnotherNamespace</p>
// HTML-ANOTHER-INDEX: </div>
// HTML-ANOTHER-INDEX: </div>
-// HTML-ANOTHER-INDEX: <p>Defined at line 193 of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
+// HTML-ANOTHER-INDEX: <p>Defined at line 270 of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p>
// HTML-ANOTHER-INDEX: </div>
// HTML-ANOTHER-INDEX: </div>
+// MD-MUSTACHE-ANOTHER-INDEX: # namespace AnotherNamespace
+// MD-MUSTACHE-ANOTHER-INDEX: AnotherNamespace
+// MD-MUSTACHE-ANOTHER-INDEX: ## Records
+// MD-MUSTACHE-ANOTHER-INDEX: * [ClassInAnotherNamespace](ClassInAnotherNamespace.md)
+// MD-MUSTACHE-ANOTHER-INDEX: ## Functions
+// MD-MUSTACHE-ANOTHER-INDEX: ### functionInAnotherNamespace
+// MD-MUSTACHE-ANOTHER-INDEX: *void functionInAnotherNamespace()*
+// MD-MUSTACHE-ANOTHER-INDEX: Function in AnotherNamespace
+
// COM: FIXME: Add namespaces to namespace template
// HTML-GLOBAL-INDEX-NOT: <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
// HTML-GLOBAL-INDEX-NOT: <h1>Global Namespace</h1>
@@ -255,13 +349,30 @@ class ClassInAnotherNamespace {};
// MD-GLOBAL-INDEX: * [AnotherNamespace](..{{[\/]}}AnotherNamespace{{[\/]}}index.md)
// MD-GLOBAL-INDEX: * [PrimaryNamespace](..{{[\/]}}PrimaryNamespace{{[\/]}}index.md)
+// MD-MUSTACHE-GLOBAL-INDEX: # Global Namespace
+// MD-MUSTACHE-GLOBAL-INDEX: ## Namespaces
+// MD-MUSTACHE-GLOBAL-INDEX: * [@nonymous_namespace]({{.*}}{{[\/]}}@nonymous_namespace{{[\/]}}index.md)
+// MD-MUSTACHE-GLOBAL-INDEX: * [AnotherNamespace]({{.*}}{{[\/]}}AnotherNamespace{{[\/]}}index.md)
+// MD-MUSTACHE-GLOBAL-INDEX: * [PrimaryNamespace]({{.*}}{{[\/]}}PrimaryNamespace{{[\/]}}index.md)
+
// MD-ALL-FILES: # All Files
// MD-ALL-FILES: ## [@nonymous_namespace](@nonymous_namespace{{[\/]}}index.md)
// MD-ALL-FILES: ## [AnotherNamespace](AnotherNamespace{{[\/]}}index.md)
// MD-ALL-FILES: ## [GlobalNamespace](GlobalNamespace{{[\/]}}index.md)
// MD-ALL-FILES: ## [PrimaryNamespace](PrimaryNamespace{{[\/]}}index.md)
+// MD-MUSTACHE-ALL-FILES: # All Files
+// MD-MUSTACHE-ALL-FILES: ## [@nonymous_namespace](@nonymous_namespace{{[\/]}}index.md)
+// MD-MUSTACHE-ALL-FILES: ## [AnotherNamespace](AnotherNamespace{{[\/]}}index.md)
+// MD-MUSTACHE-ALL-FILES: ## [GlobalNamespace](GlobalNamespace{{[\/]}}index.md)
+// MD-MUSTACHE-ALL-FILES: ## [PrimaryNamespace](PrimaryNamespace{{[\/]}}index.md)
+
// MD-INDEX: # C/C++ Reference
// MD-INDEX: * Namespace: [@nonymous_namespace](@nonymous_namespace)
// MD-INDEX: * Namespace: [AnotherNamespace](AnotherNamespace)
// MD-INDEX: * Namespace: [PrimaryNamespace](PrimaryNamespace)
+
+// MD-MUSTACHE-INDEX: # C/C++ Reference
+// MD-MUSTACHE-INDEX: * Namespace: [@nonymous_namespace](@nonymous_namespace)
+// MD-MUSTACHE-INDEX: * Namespace: [AnotherNamespace](AnotherNamespace)
+// MD-MUSTACHE-INDEX: * Namespace: [PrimaryNamespace](PrimaryNamespace)
diff --git a/clang-tools-extra/test/clang-doc/templates.cpp b/clang-tools-extra/test/clang-doc/templates.cpp
index 870841e110dde..29d22d8dce388 100644
--- a/clang-tools-extra/test/clang-doc/templates.cpp
+++ b/clang-tools-extra/test/clang-doc/templates.cpp
@@ -12,6 +12,9 @@
// RUN: cat %t/docs/html/GlobalNamespace/_ZTV5tuple.html | FileCheck %s --check-prefix=HTML-STRUCT
// RUN: cat %t/docs/html/GlobalNamespace/index.html | FileCheck %s --check-prefix=HTML
+// RUN: clang-doc --doxygen --executor=standalone %s -output=%t/docs --format=md_mustache
+// RUN: cat %t/docs/md/GlobalNamespace/index.md | FileCheck %s --check-prefix=MD-MUSTACHE
+
// YAML: ---
// YAML-NEXT: USR: '{{([0-9A-F]{40})}}'
// YAML-NEXT: ChildRecords:
@@ -24,6 +27,9 @@
// MD: # Global Namespace
// MD: ## Functions
+// MD-MUSTACHE: # Global Namespace
+// MD-MUSTACHE: ## Functions
+
template <class... T>
void ParamPackFunction(T... args);
@@ -81,6 +87,9 @@ void ParamPackFunction(T... args);
// HTML: <pre><code class="language-cpp code-clang-doc">template <class... T</code><code class="language-cpp code-clang-doc">></code></pre>
// HTML-NEXT: <pre><code class="language-cpp code-clang-doc">void ParamPackFunction (T... args)</code></pre>
+// MD-MUSTACHE: ### ParamPackFunction
+// MD-MUSTACHE: *void ParamPackFunction(T... args)*
+
template <typename T, int U = 1>
void function(T x) {}
@@ -290,6 +299,10 @@ void longFunction(A a, B b, C c, D d, E e) {}
// HTML-NEXT: <p>Defined at line [[# @LINE - 142]] of file {{.*}}templates.cpp</p>
// HTML-NEXT: </div>
+// MD-MUSTACHE: ### function
+// MD-MUSTACHE: *void function(T x)*
+// MD-MUSTACHE: *Defined at {{.*}}templates.cpp#[[# @LINE - 64]]*
+
template <>
void function<bool, 0>(bool x) {}
@@ -358,6 +371,10 @@ void function<bool, 0>(bool x) {}
// HTML-NEXT: <p>Defined at line [[# @LINE - 65]] of file {{.*}}templates.cpp</p>
// HTML-NEXT: </div>
+// MD-MUSTACHE: ### function
+// MD-MUSTACHE: *void function(bool x)*
+// MD-MUSTACHE: *Defined at {{.*}}templates.cpp#[[# @LINE - 69]]*
+
/// A Tuple type
///
/// Does Tuple things.
@@ -465,3 +482,10 @@ tuple<int, int, bool> func_with_tuple_param(tuple<int, int, bool> t) { return t;
// HTML-NEXT: </div>
// HTML-NEXT: </div>
// HTML-NEXT: <p>Defined at line [[# @LINE - 81]] of file {{.*}}templates.cpp</p>
+// HTML-NEXT: </div>
+
+// MD-MUSTACHE: ### func_with_tuple_param
+// MD-MUSTACHE: *tuple<int, int, bool> func_with_tuple_param(tuple<int, int, bool> t)*
+// MD-MUSTACHE: *Defined at {{.*}}templates.cpp#[[# @LINE - 86]]*
+// MD-MUSTACHE: A function with a tuple parameter
+// MD-MUSTACHE: **t** The input to func_with_tuple_param
diff --git a/clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp b/clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp
index 73891abd53f99..66e63bdd79b63 100644
--- a/clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp
@@ -26,7 +26,7 @@ ClangDocContext ClangDocContextTest::getClangDocContext(
StringRef RepositoryLinePrefix, StringRef Base) {
return ClangDocContext(nullptr, "test-project", false, "", "", RepositoryUrl,
RepositoryLinePrefix, Base, UserStylesheets, Diags,
- false);
+ "test", false);
}
NamespaceInfo *InfoAsNamespace(Info *I) {
diff --git a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
index cf510afe214dd..daec8434b034a 100644
--- a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -46,6 +46,7 @@ class HTMLGeneratorTest : public ClangDocContextTest {
Base,
UserStylesheets,
Diags,
+ "html",
false};
CDCtx.UserStylesheets.insert(
CDCtx.UserStylesheets.begin(),
diff --git a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
index 7e880aa93b635..ae2a0e0f23f00 100644
--- a/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
+++ b/clang-tools-extra/unittests/clang-doc/JSONGeneratorTest.cpp
@@ -64,6 +64,7 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) {
{
"Access": "public",
"End": true,
+ "HasMembers": true,
"HasPublicMembers": true,
"HasPublicMethods": true,
"InfoType": "record",
@@ -91,12 +92,10 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) {
"Name": "",
"QualName": "",
"USR": "0000000000000000000000000000000000000000"
- },
- "USR": "0000000000000000000000000000000000000000"
+ }
}
],
- "TagType": "struct",
- "USR": "0000000000000000000000000000000000000000"
+ "TagType": "struct"
}
],
"Enums": [
@@ -111,11 +110,11 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) {
}
],
"Name": "Color",
- "Scoped": false,
- "USR": "0000000000000000000000000000000000000000"
+ "Scoped": false
}
],
"HasEnums": true,
+ "HasMembers": true,
"HasParents": true,
"HasProtectedMembers": true,
"HasPublicMethods": true,
@@ -159,8 +158,7 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) {
"Name": "",
"QualName": "",
"USR": "0000000000000000000000000000000000000000"
- },
- "USR": "0000000000000000000000000000000000000000"
+ }
}
],
"Records": [
@@ -182,7 +180,6 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) {
],
"VerticalDisplay": false
},
- "USR": "0000000000000000000000000000000000000000",
"VirtualParents": [
{
"End": true,
@@ -226,8 +223,7 @@ TEST_F(JSONGeneratorTest, emitNamespaceJSON) {
"End": true,
"InfoType": "enum",
"Name": "OneEnum",
- "Scoped": false,
- "USR": "0000000000000000000000000000000000000000"
+ "Scoped": false
}
],
"Functions": [
@@ -242,8 +238,7 @@ TEST_F(JSONGeneratorTest, emitNamespaceJSON) {
"Name": "",
"QualName": "",
"USR": "0000000000000000000000000000000000000000"
- },
- "USR": "0000000000000000000000000000000000000000"
+ }
}
],
"HasEnums": true,
@@ -273,8 +268,7 @@ TEST_F(JSONGeneratorTest, emitNamespaceJSON) {
"QualName": "path::to::A::Namespace::ChildStruct",
"USR": "0000000000000000000000000000000000000000"
}
- ],
- "USR": "0000000000000000000000000000000000000000"
+ ]
})raw";
EXPECT_EQ(Expected, Actual.str());
}
>From 99a6b3ea6c8daf452262324e8546fb98f44c5301 Mon Sep 17 00:00:00 2001
From: Erick Velez <erickvelez7 at gmail.com>
Date: Mon, 2 Mar 2026 18:01:52 -0800
Subject: [PATCH 2/2] fix conflicts and update tests
---
.../clang-doc/assets/md/class-template.mustache | 2 +-
.../assets/md/namespace-template.mustache | 2 +-
clang-tools-extra/test/clang-doc/enum.cpp | 14 ++++----------
clang-tools-extra/test/clang-doc/templates.cpp | 10 +++++-----
4 files changed, 11 insertions(+), 17 deletions(-)
diff --git a/clang-tools-extra/clang-doc/assets/md/class-template.mustache b/clang-tools-extra/clang-doc/assets/md/class-template.mustache
index 4b936df56f80e..c80fc1b24b2b6 100644
--- a/clang-tools-extra/clang-doc/assets/md/class-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/md/class-template.mustache
@@ -26,7 +26,7 @@ private {{#IsStatic}}static {{/IsStatic}}{{Type}} {{Name}}
{{#PublicMethods}}
### {{Name}}
-*public {{#IsStatic}}static {{/IsStatic}}{{ReturnType.QualName}} {{Name}}({{#Params}}{{Type.QualName}} {{Name}}{{^End}}, {{/End}}{{/Params}})*
+*public {{#IsStatic}}static {{/IsStatic}}{{ReturnType.QualName}} {{Name}}({{#Params}}{{Type.QualName}} {{Name}}{{^ParamEnd}}, {{/ParamEnd}}{{/Params}})*
{{#Location}}
*Defined at {{Filename}}#{{LineNumber}}*
diff --git a/clang-tools-extra/clang-doc/assets/md/namespace-template.mustache b/clang-tools-extra/clang-doc/assets/md/namespace-template.mustache
index 696c08148854b..aef80c0516fcb 100644
--- a/clang-tools-extra/clang-doc/assets/md/namespace-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/md/namespace-template.mustache
@@ -26,7 +26,7 @@
{{#Functions}}
### {{Name}}
-*{{#IsStatic}}static {{/IsStatic}}{{ReturnType.QualName}} {{Name}}({{#Params}}{{Type.QualName}} {{Name}}{{^End}}, {{/End}}{{/Params}})*
+*{{#IsStatic}}static {{/IsStatic}}{{ReturnType.QualName}} {{Name}}({{#Params}}{{Type.QualName}} {{Name}}{{^ParamEnd}}, {{/ParamEnd}}{{/Params}})*
{{#Location}}
*Defined at {{Filename}}#{{LineNumber}}*
diff --git a/clang-tools-extra/test/clang-doc/enum.cpp b/clang-tools-extra/test/clang-doc/enum.cpp
index c9bf716fc001a..b0c4257bb746e 100644
--- a/clang-tools-extra/test/clang-doc/enum.cpp
+++ b/clang-tools-extra/test/clang-doc/enum.cpp
@@ -77,7 +77,7 @@ enum Color {
// HTML-INDEX-NEXT: <p> For specifying RGB colors</p>
// HTML-INDEX-NEXT: </div>
// HTML-INDEX-NEXT: </div>
-// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-45]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-46]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
// HTML-INDEX-NEXT: </div>
// MD-MUSTACHE-INDEX: ## Enums
@@ -139,7 +139,7 @@ enum class Shapes {
// HTML-INDEX-NEXT: <p> Shape Types</p>
// HTML-INDEX-NEXT: </div>
// HTML-INDEX-NEXT: </div>
-// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-47]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-48]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
// HTML-INDEX-NEXT: </div>
typedef unsigned char uint8_t;
@@ -339,15 +339,9 @@ class Animals {
// HTML-ANIMAL-NEXT: <p> specify what animal the class is</p>
// HTML-ANIMAL-NEXT: </div>
// HTML-ANIMAL-NEXT: </div>
-<<<<<<< HEAD
-// HTML-ANIMAL-NEXT: <p>Defined at line [[@LINE-40]] of file {{.*}}enum.cpp</p>
+// HTML-ANIMAL-NEXT: <p>Defined at line [[@LINE-41]] of file {{.*}}enum.cpp</p>
// HTML-ANIMAL-NEXT: </div>
// HTML-ANIMAL-NEXT: </section>
-=======
-// HTML-ANIMAL-NEXT: <p>Defined at line 135 of file {{.*}}enum.cpp</p>
-// HTML-ANIMAL-NEXT: </div>
-// HTML-ANIMAL-NEXT: </section>
->>>>>>> ca036029f156 (fix the fix)
// MD-ANIMAL: # class Animals
// MD-ANIMAL: ## Enums
@@ -426,7 +420,7 @@ enum Car {
// HTML-VEHICLES-NEXT: <p> specify type of car</p>
// HTML-VEHICLES-NEXT: </div>
// HTML-VEHICLES-NEXT: </div>
-// HTML-VEHICLES-NEXT: <p>Defined at line [[@LINE-54]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
+// HTML-VEHICLES-NEXT: <p>Defined at line [[@LINE-55]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
// HTML-VEHICLES-NEXT: </div>
// MD-MUSTACHE-VEHICLES: # namespace Vehicles
diff --git a/clang-tools-extra/test/clang-doc/templates.cpp b/clang-tools-extra/test/clang-doc/templates.cpp
index 29d22d8dce388..e7b003670fbf6 100644
--- a/clang-tools-extra/test/clang-doc/templates.cpp
+++ b/clang-tools-extra/test/clang-doc/templates.cpp
@@ -153,6 +153,10 @@ void function(T x) {}
// HTML-NEXT: <p>Defined at line [[# @LINE - 59]] of file {{.*}}templates.cpp</p>
// HTML-NEXT: </div>
+// MD-MUSTACHE: ### function
+// MD-MUSTACHE: *void function(T x)*
+// MD-MUSTACHE: *Defined at {{.*}}templates.cpp#[[# @LINE - 64]]*
+
template <typename A, typename B, typename C, typename D, typename E>
void longFunction(A a, B b, C c, D d, E e) {}
@@ -299,10 +303,6 @@ void longFunction(A a, B b, C c, D d, E e) {}
// HTML-NEXT: <p>Defined at line [[# @LINE - 142]] of file {{.*}}templates.cpp</p>
// HTML-NEXT: </div>
-// MD-MUSTACHE: ### function
-// MD-MUSTACHE: *void function(T x)*
-// MD-MUSTACHE: *Defined at {{.*}}templates.cpp#[[# @LINE - 64]]*
-
template <>
void function<bool, 0>(bool x) {}
@@ -373,7 +373,7 @@ void function<bool, 0>(bool x) {}
// MD-MUSTACHE: ### function
// MD-MUSTACHE: *void function(bool x)*
-// MD-MUSTACHE: *Defined at {{.*}}templates.cpp#[[# @LINE - 69]]*
+// MD-MUSTACHE: *Defined at {{.*}}templates.cpp#[[# @LINE - 70]]*
/// A Tuple type
///
More information about the cfe-commits
mailing list