https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/177221
>From 7b2ea93457ab252f8f34d516eb29705fadc92326 Mon Sep 17 00:00:00 2001 From: Erick Velez <[email protected]> Date: Fri, 7 Nov 2025 21:56:12 -0800 Subject: [PATCH] fix test, formatting, and license header --- 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 | 120 +++++++++++++--- .../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 | 132 ++++++++++++++++++ .../test/clang-doc/builtin_types.cpp | 32 ++++- .../test/clang-doc/comments-in-macros.cpp | 15 +- clang-tools-extra/test/clang-doc/enum.cpp | 48 ++++++- 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, 847 insertions(+), 72 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 fafe41eebb779..882247dc80931 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 a50f1ac25eda9..02be1f683900d 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 5051e7e6e690d..5c81bbde27fc0 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, @@ -353,7 +354,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 @@ -414,12 +416,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); @@ -436,7 +451,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; } } @@ -656,6 +676,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(); @@ -729,17 +750,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); @@ -760,7 +776,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 + static 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) { @@ -776,10 +816,45 @@ 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(); @@ -803,9 +878,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); } @@ -871,6 +949,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); @@ -885,7 +969,7 @@ Error JSONGenerator::generateDocumentation( } } - return serializeIndex(CDCtx, RootDir); + return serializeIndex(CDCtx, RootDir, Markdown); } Error JSONGenerator::generateDocForInfo(Info *I, raw_ostream &OS, @@ -895,7 +979,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 ee4c449718871..264b71a915de6 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 std::string 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 4c882ef2e8384..422233220b305 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: <html lang="en-US"> HTML-SHAPE: <head> HTML-SHAPE: <meta charset="utf-8"/> @@ -562,3 +570,127 @@ HTML-CIRCLE: </div> HTML-CIRCLE: </div> HTML-CIRCLE: </div> HTML-CIRCLE: </section> +HTML-CIRCLE: </div> +HTML-CIRCLE: </div> +HTML-CIRCLE: </main> +HTML-CIRCLE: </body> +HTML-CIRCLE: </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 6e11bbf065f25..3a0968c3ffa84 100644 --- a/clang-tools-extra/test/clang-doc/enum.cpp +++ b/clang-tools-extra/test/clang-doc/enum.cpp @@ -16,12 +16,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 @@ -35,6 +44,14 @@ enum Color { // MD-INDEX: | Blue | // MD-INDEX: **brief** For specifying RGB colors +// 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 + // HTML-INDEX: <div> // HTML-INDEX: <pre><code class="language-cpp code-clang-doc">enum Color</code></pre> // HTML-INDEX: </div> @@ -65,6 +82,7 @@ enum Color { 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, @@ -109,6 +127,7 @@ enum class Shapes { 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 @@ -116,6 +135,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 @@ -153,7 +173,7 @@ class Animals { // HTML-ANIMAL-NEXT: <p> specify what animal the class is</p> // HTML-ANIMAL-NEXT: </div> // HTML-ANIMAL-NEXT: </div> -// HTML-ANIMAL-NEXT: <p>Defined at line 116 of file {{.*}}enum.cpp</p> +// HTML-ANIMAL-NEXT: <p>Defined at line 135 of file {{.*}}enum.cpp</p> // HTML-ANIMAL-NEXT: </div> // HTML-ANIMAL-NEXT: </section> @@ -166,6 +186,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 @@ -173,6 +202,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 @@ -191,6 +221,16 @@ enum Car { // MD-VEHICLES: | Hatchback | // MD-VEHICLES: **brief** specify type of car +// 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 + // HTML-VEHICLES: <div> // HTML-VEHICLES: <pre><code class="language-cpp code-clang-doc">enum Car</code></pre> // HTML-VEHICLES: </div> @@ -231,6 +271,12 @@ enum ColorUserSpecified { // MD-INDEX: | GreenUserSpecified | // MD-INDEX: | BlueUserSpecified | +// MD-MUSTACHE-INDEX: | enum ColorUserSpecified | +// MD-MUSTACHE-INDEX: -- +// MD-MUSTACHE-INDEX: | RedUserSpecified | +// MD-MUSTACHE-INDEX: | GreenUserSpecified | +// MD-MUSTACHE-INDEX: | BlueUserSpecified | + // HTML-INDEX: <div> // HTML-INDEX: <pre><code class="language-cpp code-clang-doc">enum ColorUserSpecified</code></pre> // HTML-INDEX: </div> 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 d9ea023bf6827..f1a1ae1296af1 100644 --- a/clang-tools-extra/test/clang-doc/json/class.cpp +++ b/clang-tools-extra/test/clang-doc/json/class.cpp @@ -141,7 +141,6 @@ struct MyClass { // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } -// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "Description": { @@ -163,12 +162,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 8681c15bf1048..b9143dd77b83d 100644 --- a/clang-tools-extra/test/clang-doc/json/namespace.cpp +++ b/clang-tools-extra/test/clang-doc/json/namespace.cpp @@ -124,7 +124,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..8a92a4d48b4ef 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](../PrimaryNamespace/NestedNamespace/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](../AnotherNamespace/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 8c9b0b53a8b3d..82d9cd71ece7b 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); @@ -80,6 +86,9 @@ void ParamPackFunction(T... args); // HTML: <pre><code class="language-cpp code-clang-doc">template <class... T></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) {} @@ -143,6 +152,10 @@ void function(T x) {} // 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) {} @@ -210,6 +223,10 @@ void function<bool, 0>(bool x) {} // HTML-NEXT: <p>Defined at line [[# @LINE - 64]] 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. @@ -317,3 +334,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 021748895b208..fdeb9827148e0 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": [ @@ -181,7 +179,6 @@ TEST_F(JSONGeneratorTest, emitRecordJSON) { } ] }, - "USR": "0000000000000000000000000000000000000000", "VirtualParents": [ { "End": true, @@ -225,8 +222,7 @@ TEST_F(JSONGeneratorTest, emitNamespaceJSON) { "End": true, "InfoType": "enum", "Name": "OneEnum", - "Scoped": false, - "USR": "0000000000000000000000000000000000000000" + "Scoped": false } ], "Functions": [ @@ -241,8 +237,7 @@ TEST_F(JSONGeneratorTest, emitNamespaceJSON) { "Name": "", "QualName": "", "USR": "0000000000000000000000000000000000000000" - }, - "USR": "0000000000000000000000000000000000000000" + } } ], "HasEnums": true, @@ -272,8 +267,7 @@ TEST_F(JSONGeneratorTest, emitNamespaceJSON) { "QualName": "path::to::A::Namespace::ChildStruct", "USR": "0000000000000000000000000000000000000000" } - ], - "USR": "0000000000000000000000000000000000000000" + ] })raw"; EXPECT_EQ(Expected, Actual.str()); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
