-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[clang-doc] Adds a mustache backend #133161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
You can test this locally with the following command:git-clang-format --diff 2d1517d257fcbd0c9bce14badc7646e94d81ea2b 9dbd1b84d501db2619b716a029e612bca60eef5f --extensions h,cpp -- clang-tools-extra/clang-doc/FileHelpersClangDoc.cpp clang-tools-extra/clang-doc/FileHelpersClangDoc.h clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp llvm/tools/mustache/mustache.cpp clang-tools-extra/clang-doc/Generators.cpp clang-tools-extra/clang-doc/HTMLGenerator.cpp clang-tools-extra/clang-doc/Representation.cpp clang-tools-extra/clang-doc/Representation.h clang-tools-extra/clang-doc/Serialize.cpp clang-tools-extra/clang-doc/Serialize.h clang-tools-extra/clang-doc/tool/ClangDocMain.cpp clang-tools-extra/test/clang-doc/Inputs/basic-project/include/Shape.h View the diff from clang-format here.diff --git a/clang-tools-extra/clang-doc/FileHelpersClangDoc.cpp b/clang-tools-extra/clang-doc/FileHelpersClangDoc.cpp
index 50209cfac1..704adcf689 100644
--- a/clang-tools-extra/clang-doc/FileHelpersClangDoc.cpp
+++ b/clang-tools-extra/clang-doc/FileHelpersClangDoc.cpp
@@ -12,8 +12,7 @@
namespace clang {
namespace doc {
-llvm::Error
-copyFile(llvm::StringRef FilePath, llvm::StringRef OutDirectory) {
+llvm::Error copyFile(llvm::StringRef FilePath, llvm::StringRef OutDirectory) {
llvm::SmallString<128> PathWrite;
llvm::sys::path::native(OutDirectory, PathWrite);
llvm::sys::path::append(PathWrite, llvm::sys::path::filename(FilePath));
@@ -30,14 +29,13 @@ copyFile(llvm::StringRef FilePath, llvm::StringRef OutDirectory) {
return llvm::Error::success();
}
-
llvm::SmallString<128> computeRelativePath(llvm::StringRef Destination,
- llvm::StringRef Origin) {
+ llvm::StringRef Origin) {
// If Origin is empty, the relative path to the Destination is its complete
// path.
if (Origin.empty())
return Destination;
-
+
// The relative path is an empty path if both directories are the same.
if (Destination == Origin)
return {};
diff --git a/clang-tools-extra/clang-doc/FileHelpersClangDoc.h b/clang-tools-extra/clang-doc/FileHelpersClangDoc.h
index 9072a7bd08..997bbea63d 100644
--- a/clang-tools-extra/clang-doc/FileHelpersClangDoc.h
+++ b/clang-tools-extra/clang-doc/FileHelpersClangDoc.h
@@ -14,11 +14,10 @@
namespace clang {
namespace doc {
-llvm::Error
-copyFile(llvm::StringRef FilePath, llvm::StringRef OutDirectory);
+llvm::Error copyFile(llvm::StringRef FilePath, llvm::StringRef OutDirectory);
-llvm::SmallString<128>
-computeRelativePath(llvm::StringRef Destination,llvm::StringRef Origin);
+llvm::SmallString<128> computeRelativePath(llvm::StringRef Destination,
+ llvm::StringRef Origin);
} // namespace doc
} // namespace clang
diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
index 6b0efc9d4f..1f9b53b0c7 100644
--- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
@@ -512,8 +512,8 @@ writeFileDefinition(const Location &L,
llvm::sys::path::Style::windows));
auto Node = std::make_unique<TagNode>(HTMLTag::TAG_P);
Node->Children.emplace_back(std::make_unique<TextNode>("Defined at line "));
- auto LocNumberNode =
- std::make_unique<TagNode>(HTMLTag::TAG_A, std::to_string(L.StartLineNumber));
+ auto LocNumberNode = std::make_unique<TagNode>(
+ HTMLTag::TAG_A, std::to_string(L.StartLineNumber));
// The links to a specific line in the source code use the github /
// googlesource notation so it won't work for all hosting pages.
// FIXME: we probably should have a configuration setting for line number
@@ -1146,8 +1146,7 @@ static llvm::Error genIndex(const ClangDocContext &CDCtx) {
return llvm::Error::success();
}
-static llvm::Error
-copyFile(StringRef FilePath, StringRef OutDirectory) {
+static llvm::Error copyFile(StringRef FilePath, StringRef OutDirectory) {
llvm::SmallString<128> PathWrite;
llvm::sys::path::native(OutDirectory, PathWrite);
llvm::sys::path::append(PathWrite, llvm::sys::path::filename(FilePath));
diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 1f96202f1f..67f37a2bbe 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -5,9 +5,9 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+#include "FileHelpersClangDoc.h"
#include "Generators.h"
#include "Representation.h"
-#include "FileHelpersClangDoc.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mustache.h"
@@ -18,7 +18,6 @@ using namespace llvm::mustache;
namespace clang {
namespace doc {
-
class MustacheHTMLGenerator : public Generator {
public:
static const char *Format;
@@ -28,16 +27,15 @@ public:
llvm::Error createResources(ClangDocContext &CDCtx) override;
llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
const ClangDocContext &CDCtx) override;
-
};
class MustacheTemplateFile : public Template {
public:
- static ErrorOr<std::unique_ptr<MustacheTemplateFile>> createMustacheFile
- (StringRef FileName) {
+ static ErrorOr<std::unique_ptr<MustacheTemplateFile>>
+ createMustacheFile(StringRef FileName) {
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrError =
MemoryBuffer::getFile(FileName);
-
+
if (auto EC = BufferOrError.getError()) {
return EC;
}
@@ -45,7 +43,7 @@ public:
llvm::StringRef FileContent = Buffer->getBuffer();
return std::make_unique<MustacheTemplateFile>(FileContent);
}
-
+
Error registerPartialFile(StringRef Name, StringRef FileName) {
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrError =
MemoryBuffer::getFile(FileName);
@@ -64,11 +62,10 @@ static std::unique_ptr<MustacheTemplateFile> NamespaceTemplate = nullptr;
static std::unique_ptr<MustacheTemplateFile> RecordTemplate = nullptr;
-
-llvm::Error setupTemplate(
- std::unique_ptr<MustacheTemplateFile> &Template,
- StringRef TemplatePath,
- std::vector<std::pair<StringRef, StringRef>> Partials) {
+llvm::Error
+setupTemplate(std::unique_ptr<MustacheTemplateFile> &Template,
+ StringRef TemplatePath,
+ std::vector<std::pair<StringRef, StringRef>> Partials) {
auto T = MustacheTemplateFile::createMustacheFile(TemplatePath);
if (auto EC = T.getError())
return llvm::createFileError("cannot open file", EC);
@@ -81,8 +78,7 @@ llvm::Error setupTemplate(
return llvm::Error::success();
}
-llvm::Error
-setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) {
+llvm::Error setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) {
auto NamespaceFilePath = CDCtx.MustacheTemplates.lookup("namespace-template");
auto ClassFilePath = CDCtx.MustacheTemplates.lookup("class-template");
auto CommentFilePath = CDCtx.MustacheTemplates.lookup("comments-template");
@@ -91,26 +87,23 @@ setupTemplateFiles(const clang::doc::ClangDocContext &CDCtx) {
std::vector<std::pair<StringRef, StringRef>> Partials = {
{"Comments", CommentFilePath},
{"FunctionPartial", FunctionFilePath},
- {"EnumPartial", EnumFilePath}
- };
-
+ {"EnumPartial", EnumFilePath}};
+
auto Err = setupTemplate(NamespaceTemplate, NamespaceFilePath, Partials);
if (Err)
return Err;
-
+
Err = setupTemplate(RecordTemplate, ClassFilePath, Partials);
-
+
if (Err)
return Err;
-
+
return llvm::Error::success();
}
-
-llvm::Error
-MustacheHTMLGenerator::generateDocs(llvm::StringRef RootDir,
- llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
- const clang::doc::ClangDocContext &CDCtx) {
+llvm::Error MustacheHTMLGenerator::generateDocs(
+ llvm::StringRef RootDir, llvm::StringMap<std::unique_ptr<doc::Info>> Infos,
+ const clang::doc::ClangDocContext &CDCtx) {
if (auto Err = setupTemplateFiles(CDCtx))
return Err;
// Track which directories we already tried to create.
@@ -119,7 +112,7 @@ MustacheHTMLGenerator::generateDocs(llvm::StringRef RootDir,
llvm::StringMap<std::vector<doc::Info *>> FileToInfos;
for (const auto &Group : Infos) {
doc::Info *Info = Group.getValue().get();
-
+
llvm::SmallString<128> Path;
llvm::sys::path::native(RootDir, Path);
llvm::sys::path::append(Path, Info->getRelativeFilePath(""));
@@ -134,7 +127,7 @@ MustacheHTMLGenerator::generateDocs(llvm::StringRef RootDir,
llvm::sys::path::append(Path, Info->getFileBaseName() + ".html");
FileToInfos[Path].push_back(Info);
}
-
+
for (const auto &Group : FileToInfos) {
std::error_code FileErr;
llvm::raw_fd_ostream InfoOS(Group.getKey(), FileErr,
@@ -142,7 +135,7 @@ MustacheHTMLGenerator::generateDocs(llvm::StringRef RootDir,
if (FileErr)
return llvm::createStringError(FileErr, "Error opening file '%s'",
Group.getKey().str().c_str());
-
+
for (const auto &Info : Group.getValue()) {
if (llvm::Error Err = generateDocForInfo(Info, InfoOS, CDCtx))
return Err;
@@ -151,12 +144,12 @@ MustacheHTMLGenerator::generateDocs(llvm::StringRef RootDir,
return llvm::Error::success();
}
-Value extractValue(const Location &L,
+Value extractValue(const Location &L,
std::optional<StringRef> RepositoryUrl = std::nullopt) {
Object Obj = Object();
Obj.insert({"LineNumber", L.LineNumber});
Obj.insert({"Filename", L.Filename});
-
+
if (!L.IsFileInRootDir || !RepositoryUrl) {
return Obj;
}
@@ -164,7 +157,7 @@ Value extractValue(const Location &L,
llvm::sys::path::append(FileURL, llvm::sys::path::Style::posix, L.Filename);
FileURL += "#" + std::to_string(L.LineNumber);
Obj.insert({"FileURL", FileURL});
-
+
return Obj;
}
@@ -180,7 +173,6 @@ Value extractValue(const Reference &I, StringRef CurrentDirectory) {
return Obj;
}
-
Value extractValue(const TypedefInfo &I) {
// Not Supported
return nullptr;
@@ -189,17 +181,17 @@ Value extractValue(const TypedefInfo &I) {
Value extractValue(const CommentInfo &I) {
Object Obj = Object();
Value Child = Object();
-
+
if (I.Kind == "FullComment") {
Value ChildArr = Array();
- for (const auto& C: I.Children)
+ for (const auto &C : I.Children)
ChildArr.getAsArray()->emplace_back(extractValue(*C));
Child.getAsObject()->insert({"Children", ChildArr});
Obj.insert({"FullComment", Child});
}
if (I.Kind == "ParagraphComment") {
Value ChildArr = Array();
- for (const auto& C: I.Children)
+ for (const auto &C : I.Children)
ChildArr.getAsArray()->emplace_back(extractValue(*C));
Child.getAsObject()->insert({"Children", ChildArr});
Obj.insert({"ParagraphComment", Child});
@@ -207,14 +199,14 @@ Value extractValue(const CommentInfo &I) {
if (I.Kind == "BlockCommandComment") {
Child.getAsObject()->insert({"Command", I.Name});
Value ChildArr = Array();
- for (const auto& C: I.Children)
+ for (const auto &C : I.Children)
ChildArr.getAsArray()->emplace_back(extractValue(*C));
Child.getAsObject()->insert({"Children", ChildArr});
Obj.insert({"BlockCommandComment", Child});
}
if (I.Kind == "TextComment")
Obj.insert({"TextComment", I.Text});
-
+
return Obj;
}
@@ -225,30 +217,30 @@ Value extractValue(const FunctionInfo &I, StringRef ParentInfoDir,
Obj.insert({"ID", llvm::toHex(llvm::toStringRef(I.USR))});
Obj.insert({"Access", getAccessSpelling(I.Access).str()});
Obj.insert({"ReturnType", extractValue(I.ReturnType.Type, ParentInfoDir)});
-
+
Value ParamArr = Array();
for (const auto Val : llvm::enumerate(I.Params)) {
Value V = Object();
V.getAsObject()->insert({"Name", Val.value().Name});
V.getAsObject()->insert({"Type", Val.value().Type.Name});
- V.getAsObject()->insert({"End", Val.index() + 1 == I.Params.size()});
+ V.getAsObject()->insert({"End", Val.index() + 1 == I.Params.size()});
ParamArr.getAsArray()->emplace_back(V);
}
Obj.insert({"Params", ParamArr});
-
+
if (!I.Description.empty()) {
Value ArrDesc = Array();
- for (const CommentInfo& Child : I.Description)
+ for (const CommentInfo &Child : I.Description)
ArrDesc.getAsArray()->emplace_back(extractValue(Child));
Obj.insert({"FunctionComments", ArrDesc});
}
if (I.DefLoc.has_value()) {
Location L = *I.DefLoc;
if (CDCtx.RepositoryUrl.has_value())
- Obj.insert({"Location", extractValue(L,
- StringRef{*CDCtx.RepositoryUrl})});
+ Obj.insert(
+ {"Location", extractValue(L, StringRef{*CDCtx.RepositoryUrl})});
else
- Obj.insert({"Location", extractValue(L)});
+ Obj.insert({"Location", extractValue(L)});
}
return Obj;
}
@@ -264,66 +256,66 @@ Value extractValue(const EnumInfo &I, const ClangDocContext &CDCtx) {
Obj.insert({"HasComment", HasComment});
Obj.insert({"ID", llvm::toHex(llvm::toStringRef(I.USR))});
Value Arr = Array();
- for (const EnumValueInfo& M: I.Members) {
+ for (const EnumValueInfo &M : I.Members) {
Value EnumValue = Object();
EnumValue.getAsObject()->insert({"Name", M.Name});
if (!M.ValueExpr.empty())
EnumValue.getAsObject()->insert({"ValueExpr", M.ValueExpr});
else
EnumValue.getAsObject()->insert({"Value", M.Value});
-
+
if (!M.Description.empty()) {
Value ArrDesc = Array();
- for (const CommentInfo& Child : M.Description)
+ for (const CommentInfo &Child : M.Description)
ArrDesc.getAsArray()->emplace_back(extractValue(Child));
EnumValue.getAsObject()->insert({"EnumValueComments", ArrDesc});
}
Arr.getAsArray()->emplace_back(EnumValue);
}
Obj.insert({"EnumValues", Arr});
-
+
if (!I.Description.empty()) {
Value ArrDesc = Array();
- for (const CommentInfo& Child : I.Description)
+ for (const CommentInfo &Child : I.Description)
ArrDesc.getAsArray()->emplace_back(extractValue(Child));
Obj.insert({"EnumComments", ArrDesc});
}
-
+
if (I.DefLoc.has_value()) {
Location L = *I.DefLoc;
if (CDCtx.RepositoryUrl.has_value())
- Obj.insert({"Location", extractValue(L,
- StringRef{*CDCtx.RepositoryUrl})});
+ Obj.insert(
+ {"Location", extractValue(L, StringRef{*CDCtx.RepositoryUrl})});
else
- Obj.insert({"Location", extractValue(L)});
+ Obj.insert({"Location", extractValue(L)});
}
-
+
return Obj;
}
-void extractScopeChildren(const ScopeChildren &S, Object &Obj,
+void extractScopeChildren(const ScopeChildren &S, Object &Obj,
StringRef ParentInfoDir,
const ClangDocContext &CDCtx) {
Value ArrNamespace = Array();
- for (const Reference& Child : S.Namespaces)
+ for (const Reference &Child : S.Namespaces)
ArrNamespace.getAsArray()->emplace_back(extractValue(Child, ParentInfoDir));
-
+
if (!ArrNamespace.getAsArray()->empty())
Obj.insert({"Namespace", Object{{"Links", ArrNamespace}}});
-
+
Value ArrRecord = Array();
- for (const Reference& Child : S.Records)
+ for (const Reference &Child : S.Records)
ArrRecord.getAsArray()->emplace_back(extractValue(Child, ParentInfoDir));
-
+
if (!ArrRecord.getAsArray()->empty())
Obj.insert({"Record", Object{{"Links", ArrRecord}}});
-
+
Value ArrFunction = Array();
Value PublicFunction = Array();
Value ProtectedFunction = Array();
Value PrivateFunction = Array();
-
- for (const FunctionInfo& Child : S.Functions) {
+
+ for (const FunctionInfo &Child : S.Functions) {
Value F = extractValue(Child, ParentInfoDir, CDCtx);
AccessSpecifier Access = Child.Access;
if (Access == AccessSpecifier::AS_public)
@@ -332,30 +324,29 @@ void extractScopeChildren(const ScopeChildren &S, Object &Obj,
ProtectedFunction.getAsArray()->emplace_back(F);
else
ArrFunction.getAsArray()->emplace_back(F);
- }
+ }
if (!ArrFunction.getAsArray()->empty())
Obj.insert({"Function", Object{{"Obj", ArrFunction}}});
-
+
if (!PublicFunction.getAsArray()->empty())
Obj.insert({"PublicFunction", Object{{"Obj", PublicFunction}}});
-
+
if (!ProtectedFunction.getAsArray()->empty())
Obj.insert({"ProtectedFunction", Object{{"Obj", ProtectedFunction}}});
-
-
+
Value ArrEnum = Array();
- for (const EnumInfo& Child : S.Enums)
+ for (const EnumInfo &Child : S.Enums)
ArrEnum.getAsArray()->emplace_back(extractValue(Child, CDCtx));
-
+
if (!ArrEnum.getAsArray()->empty())
- Obj.insert({"Enums", Object{{"Obj", ArrEnum }}});
-
+ Obj.insert({"Enums", Object{{"Obj", ArrEnum}}});
+
Value ArrTypedefs = Array();
- for (const TypedefInfo& Child : S.Typedefs)
+ for (const TypedefInfo &Child : S.Typedefs)
ArrTypedefs.getAsArray()->emplace_back(extractValue(Child));
-
+
if (!ArrTypedefs.getAsArray()->empty())
- Obj.insert({"Typedefs", Object{{"Obj", ArrTypedefs }}});
+ Obj.insert({"Typedefs", Object{{"Obj", ArrTypedefs}}});
}
Value extractValue(const NamespaceInfo &I, const ClangDocContext &CDCtx) {
@@ -364,17 +355,17 @@ Value extractValue(const NamespaceInfo &I, const ClangDocContext &CDCtx) {
if (I.Name.str() == "")
InfoTitle = "Global Namespace";
else
- InfoTitle = ("namespace " + I.Name).str();
-
+ InfoTitle = ("namespace " + I.Name).str();
+
StringRef BasePath = I.getRelativeFilePath("");
NamespaceValue.insert({"NamespaceTitle", InfoTitle});
NamespaceValue.insert({"NamespacePath", I.getRelativeFilePath("")});
-
+
if (!I.Description.empty()) {
Value ArrDesc = Array();
- for (const CommentInfo& Child : I.Description)
+ for (const CommentInfo &Child : I.Description)
ArrDesc.getAsArray()->emplace_back(extractValue(Child));
- NamespaceValue.insert({"NamespaceComments", ArrDesc });
+ NamespaceValue.insert({"NamespaceComments", ArrDesc});
}
extractScopeChildren(I.Children, NamespaceValue, BasePath, CDCtx);
return NamespaceValue;
@@ -382,42 +373,42 @@ Value extractValue(const NamespaceInfo &I, const ClangDocContext &CDCtx) {
Value extractValue(const RecordInfo &I, const ClangDocContext &CDCtx) {
Object RecordValue = Object();
-
+
if (!I.Description.empty()) {
Value ArrDesc = Array();
- for (const CommentInfo& Child : I.Description)
+ for (const CommentInfo &Child : I.Description)
ArrDesc.getAsArray()->emplace_back(extractValue(Child));
- RecordValue.insert({"RecordComments", ArrDesc });
+ RecordValue.insert({"RecordComments", ArrDesc});
}
RecordValue.insert({"Name", I.Name});
RecordValue.insert({"FullName", I.FullName});
RecordValue.insert({"RecordType", getTagType(I.TagType)});
-
+
if (I.DefLoc.has_value()) {
Location L = *I.DefLoc;
if (CDCtx.RepositoryUrl.has_value())
- RecordValue.insert({"Location", extractValue(L,
- StringRef{*CDCtx.RepositoryUrl})});
+ RecordValue.insert(
+ {"Location", extractValue(L, StringRef{*CDCtx.RepositoryUrl})});
else
- RecordValue.insert({"Location", extractValue(L)});
+ RecordValue.insert({"Location", extractValue(L)});
}
-
+
StringRef BasePath = I.getRelativeFilePath("");
extractScopeChildren(I.Children, RecordValue, BasePath, CDCtx);
Value PublicMembers = Array();
Value ProtectedMembers = Array();
Value PrivateMembers = Array();
- for (const MemberTypeInfo &Member : I.Members ) {
+ for (const MemberTypeInfo &Member : I.Members) {
Value MemberValue = Object();
MemberValue.getAsObject()->insert({"Name", Member.Name});
MemberValue.getAsObject()->insert({"Type", Member.Type.Name});
if (!Member.Description.empty()) {
Value ArrDesc = Array();
- for (const CommentInfo& Child : Member.Description)
+ for (const CommentInfo &Child : Member.Description)
ArrDesc.getAsArray()->emplace_back(extractValue(Child));
- MemberValue.getAsObject()->insert({"MemberComments", ArrDesc });
+ MemberValue.getAsObject()->insert({"MemberComments", ArrDesc});
}
-
+
if (Member.Access == AccessSpecifier::AS_public)
PublicMembers.getAsArray()->emplace_back(MemberValue);
else if (Member.Access == AccessSpecifier::AS_protected)
@@ -431,7 +422,7 @@ Value extractValue(const RecordInfo &I, const ClangDocContext &CDCtx) {
RecordValue.insert({"ProtectedMembers", Object{{"Obj", ProtectedMembers}}});
if (!PrivateMembers.getAsArray()->empty())
RecordValue.insert({"PrivateMembers", Object{{"Obj", PrivateMembers}}});
-
+
return RecordValue;
}
@@ -440,7 +431,7 @@ void setupTemplateValue(const ClangDocContext &CDCtx, Value &V, Info *I) {
Value StylesheetArr = Array();
auto InfoPath = I->getRelativeFilePath("");
SmallString<128> RelativePath = computeRelativePath("", InfoPath);
- for (const auto &FilePath : CDCtx.UserStylesheets) {
+ for (const auto &FilePath : CDCtx.UserStylesheets) {
SmallString<128> StylesheetPath = RelativePath;
llvm::sys::path::append(StylesheetPath,
llvm::sys::path::filename(FilePath));
@@ -448,7 +439,7 @@ void setupTemplateValue(const ClangDocContext &CDCtx, Value &V, Info *I) {
StylesheetArr.getAsArray()->emplace_back(StylesheetPath);
}
V.getAsObject()->insert({"Stylesheets", StylesheetArr});
-
+
Value ScriptArr = Array();
for (auto Script : CDCtx.JsScripts) {
SmallString<128> JsPath = RelativePath;
@@ -457,7 +448,6 @@ void setupTemplateValue(const ClangDocContext &CDCtx, Value &V, Info *I) {
}
V.getAsObject()->insert({"Scripts", ScriptArr});
}
-
llvm::Error
MustacheHTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
@@ -474,10 +464,10 @@ MustacheHTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
setupTemplateValue(CDCtx, V, I);
// Serialize the JSON value to the output stream in a readable format.
llvm::outs() << "Visit: " << I->Name << "\n";
- //llvm::outs() << llvm::formatv("{0:2}", V) << "\n";
+ // llvm::outs() << llvm::formatv("{0:2}", V) << "\n";
llvm::outs() << RecordTemplate->render(V);
break;
- }
+ }
case InfoType::IT_enum:
llvm::outs() << "IT_enum\n";
break;
@@ -511,9 +501,8 @@ llvm::Error MustacheHTMLGenerator::createResources(ClangDocContext &CDCtx) {
const char *MustacheHTMLGenerator::Format = "mhtml";
-
-static GeneratorRegistry::Add<MustacheHTMLGenerator> MHTML(MustacheHTMLGenerator::Format,
- "Generator for mustache HTML output.");
+static GeneratorRegistry::Add<MustacheHTMLGenerator>
+ MHTML(MustacheHTMLGenerator::Format, "Generator for mustache HTML output.");
// This anchor is used to force the linker to link in the generated object
// file and thus register the generator.
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index 84a647cbe8..f6dc323187 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -62,10 +62,10 @@ struct CommentInfo {
SmallString<16>
Kind; // Kind of comment (FullComment, ParagraphComment, TextComment,
- // InlineCommandComment, HTMLStartTagComment, HTMLEndTagComment,
- // BlockCommandComment, ParamCommandComment,
- // TParamCommandComment, VerbatimBlockComment,
- // VerbatimBlockLineComment, VerbatimLineComment).
+ // InlineCommandComment, HTMLStartTagComment, HTMLEndTagComment,
+ // BlockCommandComment, ParamCommandComment,
+ // TParamCommandComment, VerbatimBlockComment,
+ // VerbatimBlockLineComment, VerbatimLineComment).
SmallString<64> Text; // Text of the comment.
SmallString<16> Name; // Name of the comment (for Verbatim and HTML).
SmallString<8> Direction; // Parameter direction (for (T)ParamCommand).
@@ -73,7 +73,7 @@ struct CommentInfo {
SmallString<16> CloseName; // Closing tag name (for VerbatimBlock).
bool SelfClosing = false; // Indicates if tag is self-closing (for HTML).
bool Explicit = false; // Indicates if the direction of a param is explicit
- // (for (T)ParamCommand).
+ // (for (T)ParamCommand).
llvm::SmallVector<SmallString<16>, 4>
AttrKeys; // List of attribute keys (for HTML).
llvm::SmallVector<SmallString<16>, 4>
@@ -113,8 +113,7 @@ struct Reference {
llvm::SmallString<16> getFileBaseName() const;
SymbolID USR = SymbolID(); // Unique identifier for referenced decl
-
-
+
// Name of type (possibly unresolved). Not including namespaces or template
// parameters (so for a std::vector<int> this would be "vector"). See also
// QualName.
@@ -153,9 +152,9 @@ struct ScopeChildren {
// A base struct for TypeInfos
struct TypeInfo {
-
+
TypeInfo() = default;
-
+
TypeInfo(const Reference &R) : Type(R) {}
// Convenience constructor for when there is no symbol ID or info type
@@ -164,9 +163,9 @@ struct TypeInfo {
: Type(SymbolID(), Name, InfoType::IT_default, Name, Path) {}
bool operator==(const TypeInfo &Other) const { return Type == Other.Type; }
-
+
Reference Type; // Referenced type in this info.
-
+
bool IsTemplate = false;
bool IsBuiltIn = false;
};
@@ -215,7 +214,6 @@ struct FieldTypeInfo : public TypeInfo {
return std::tie(Type, Name, DefaultValue) ==
std::tie(Other.Type, Other.Name, Other.DefaultValue);
}
-
SmallString<16> Name; // Name associated with this info.
@@ -245,14 +243,10 @@ struct MemberTypeInfo : public FieldTypeInfo {
};
struct Location {
- Location(int StartLineNumber = 0,
- int EndLineNumber = 0,
- StringRef Filename = StringRef(),
- bool IsFileInRootDir = false)
- : StartLineNumber(StartLineNumber),
- EndLineNumber(EndLineNumber),
- Filename(Filename),
- IsFileInRootDir(IsFileInRootDir) {}
+ Location(int StartLineNumber = 0, int EndLineNumber = 0,
+ StringRef Filename = StringRef(), bool IsFileInRootDir = false)
+ : StartLineNumber(StartLineNumber), EndLineNumber(EndLineNumber),
+ Filename(Filename), IsFileInRootDir(IsFileInRootDir) {}
bool operator==(const Location &Other) const {
return std::tie(StartLineNumber, EndLineNumber, Filename) ==
@@ -371,7 +365,7 @@ struct FunctionInfo : public SymbolInfo {
// Full qualified name of this function, including namespaces and template
// specializations.
SmallString<16> FullName;
-
+
// Function Prototype
SmallString<256> ProtoType;
@@ -394,7 +388,7 @@ struct RecordInfo : public SymbolInfo {
// Full qualified name of this record, including namespaces and template
// specializations.
SmallString<16> FullName;
-
+
// When present, this record is a template or specialization.
std::optional<TemplateInfo> Template;
@@ -434,8 +428,8 @@ struct TypedefInfo : public SymbolInfo {
// False means it's a C-style typedef:
// typedef std::vector<int> MyVector;
bool IsUsing = false;
-
- std::vector<CommentInfo> Description;
+
+ std::vector<CommentInfo> Description;
};
struct BaseRecordInfo : public RecordInfo {
@@ -473,9 +467,9 @@ struct EnumValueInfo {
// Stores the user-supplied initialization expression for this enumeration
// constant. This will be empty for implicit enumeration values.
SmallString<16> ValueExpr;
-
+
/// Comment description of this field.
- std::vector<CommentInfo> Description;
+ std::vector<CommentInfo> Description;
};
// TODO: Expand to allow for documenting templating.
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index d4d1436646..c2ba7a3a16 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -8,10 +8,10 @@
#include "Serialize.h"
#include "BitcodeWriter.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/Comment.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Lex/Lexer.h"
-#include "clang/AST/Attr.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/SHA1.h"
@@ -33,10 +33,10 @@ populateParentNamespaces(llvm::SmallVector<Reference, 4> &Namespaces,
static void populateMemberTypeInfo(MemberTypeInfo &I, const FieldDecl *D);
-void getTemplateParameters(const TemplateParameterList *TemplateParams,
+void getTemplateParameters(const TemplateParameterList *TemplateParams,
llvm::raw_ostream &Stream) {
Stream << "template <";
-
+
for (unsigned i = 0; i < TemplateParams->size(); ++i) {
if (i > 0) {
Stream << ", ";
@@ -53,13 +53,15 @@ void getTemplateParameters(const TemplateParameterList *TemplateParams,
Stream << "...";
}
Stream << " " << TTP->getNameAsString();
- } else if (const auto *NTTP = llvm::dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+ } else if (const auto *NTTP =
+ llvm::dyn_cast<NonTypeTemplateParmDecl>(Param)) {
NTTP->getType().print(Stream, NTTP->getASTContext().getPrintingPolicy());
if (NTTP->isParameterPack()) {
Stream << "...";
}
Stream << " " << NTTP->getNameAsString();
- } else if (const auto *TTPD = llvm::dyn_cast<TemplateTemplateParmDecl>(Param)) {
+ } else if (const auto *TTPD =
+ llvm::dyn_cast<TemplateTemplateParmDecl>(Param)) {
Stream << "template <";
getTemplateParameters(TTPD->getTemplateParameters(), Stream);
Stream << "> class " << TTPD->getNameAsString();
@@ -69,12 +71,12 @@ void getTemplateParameters(const TemplateParameterList *TemplateParams,
Stream << "> ";
}
-// Extract the full function prototype from a FunctionDecl including
+// Extract the full function prototype from a FunctionDecl including
// Full Decl
llvm::SmallString<256> getFunctionPrototype(const FunctionDecl *FuncDecl) {
- llvm::SmallString<256> Result;
+ llvm::SmallString<256> Result;
llvm::raw_svector_ostream Stream(Result);
- const ASTContext& Ctx = FuncDecl->getASTContext();
+ const ASTContext &Ctx = FuncDecl->getASTContext();
const auto *Method = llvm::dyn_cast<CXXMethodDecl>(FuncDecl);
// If it's a templated function, handle the template parameters
if (const auto *TmplDecl = FuncDecl->getDescribedTemplate()) {
@@ -82,8 +84,7 @@ llvm::SmallString<256> getFunctionPrototype(const FunctionDecl *FuncDecl) {
}
// If it's a virtual method
if (Method) {
- if (Method->isVirtual())
- {
+ if (Method->isVirtual()) {
Stream << "virtual ";
}
}
@@ -135,7 +136,7 @@ llvm::SmallString<256> getFunctionPrototype(const FunctionDecl *FuncDecl) {
Stream << " final";
if (Method->isConst())
Stream << " const";
- if (Method->isPureVirtual())
+ if (Method->isPureVirtual())
Stream << " = 0";
}
return Result; // Convert SmallString to std::string for return
@@ -144,7 +145,7 @@ llvm::SmallString<256> getFunctionPrototype(const FunctionDecl *FuncDecl) {
llvm::SmallString<16> getTypeDefDecl(const TypedefDecl *TypeDef) {
llvm::SmallString<16> Result;
llvm::raw_svector_ostream Stream(Result);
- const ASTContext& Ctx = TypeDef->getASTContext();
+ const ASTContext &Ctx = TypeDef->getASTContext();
Stream << "typedef ";
QualType Q = TypeDef->getUnderlyingType();
Q.print(Stream, Ctx.getPrintingPolicy());
@@ -155,16 +156,14 @@ llvm::SmallString<16> getTypeDefDecl(const TypedefDecl *TypeDef) {
llvm::SmallString<16> getTypeAlias(const TypeAliasDecl *Alias) {
llvm::SmallString<16> Result;
llvm::raw_svector_ostream Stream(Result);
- const ASTContext& Ctx = Alias->getASTContext();
+ const ASTContext &Ctx = Alias->getASTContext();
if (const auto *TmplDecl = Alias->getDescribedTemplate()) {
getTemplateParameters(TmplDecl->getTemplateParameters(), Stream);
}
- Stream << "using "
- << Alias->getNameAsString()
- << " = ";
+ Stream << "using " << Alias->getNameAsString() << " = ";
QualType Q = Alias->getUnderlyingType();
Q.print(Stream, Ctx.getPrintingPolicy());
-
+
return Result;
}
@@ -181,7 +180,8 @@ llvm::SmallString<16> getRecordPrototype(const CXXRecordDecl *CXXRD) {
OS << "template <";
bool FirstParam = true;
for (const auto *Param : *TD->getTemplateParameters()) {
- if (!FirstParam) OS << ", ";
+ if (!FirstParam)
+ OS << ", ";
Param->print(OS, Policy);
FirstParam = false;
}
@@ -199,8 +199,10 @@ llvm::SmallString<16> getRecordPrototype(const CXXRecordDecl *CXXRD) {
OS << " : ";
bool FirstBase = true;
for (const auto &Base : CXXRD->bases()) {
- if (!FirstBase) OS << ", ";
- if (Base.isVirtual()) OS << "virtual ";
+ if (!FirstBase)
+ OS << ", ";
+ if (Base.isVirtual())
+ OS << "virtual ";
OS << getAccessSpelling(Base.getAccessSpecifier()) << " ";
OS << Base.getType().getAsString(Policy);
FirstBase = false;
@@ -209,7 +211,6 @@ llvm::SmallString<16> getRecordPrototype(const CXXRecordDecl *CXXRD) {
return Result;
}
-
// A function to extract the appropriate relative path for a given info's
// documentation. The path returned is a composite of the parent namespaces.
//
@@ -406,7 +407,8 @@ static QualType getBaseQualType(const QualType &T) {
QualType QT = T;
// Get the base type of the QualType
// eg. int* -> int, int& -> int, const int -> int
- bool Modified = true; // Track whether we've modified `qt` in this loop iteration
+ bool Modified =
+ true; // Track whether we've modified `qt` in this loop iteration
while (Modified) {
Modified = false;
// If it's a reference type, strip the reference
@@ -418,8 +420,8 @@ static QualType getBaseQualType(const QualType &T) {
else if (QT->isPointerType()) {
QT = QT->getPointeeType();
Modified = true;
- }
- else if (const auto *ElaboratedType = QT->getAs<clang::ElaboratedType>()) {
+ } else if (const auto *ElaboratedType =
+ QT->getAs<clang::ElaboratedType>()) {
QT = ElaboratedType->desugar();
Modified = true;
}
@@ -427,12 +429,11 @@ static QualType getBaseQualType(const QualType &T) {
else if (QT.hasQualifiers()) {
QT = QT.getUnqualifiedType();
Modified = true;
- }
- else if (const auto *TypedefType = QT->getAs<clang::TypedefType>()) {
+ } else if (const auto *TypedefType = QT->getAs<clang::TypedefType>()) {
return QT;
}
}
-
+
return QT;
}
@@ -458,7 +459,7 @@ TypeInfo getTypeInfoForType(const QualType &T) {
IT = InfoType::IT_record;
else
IT = InfoType::IT_default;
-
+
Reference R = Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
T.getAsString(), getInfoRelativePath(TD));
TypeInfo TI = TypeInfo(R);
@@ -471,8 +472,7 @@ static bool isPublic(const clang::AccessSpecifier AS,
const clang::Linkage Link) {
if (AS == clang::AccessSpecifier::AS_private)
return false;
- if ((Link == clang::Linkage::Module) ||
- (Link == clang::Linkage::External))
+ if ((Link == clang::Linkage::Module) || (Link == clang::Linkage::External))
return true;
return false; // otherwise, linkage is some form of internal linkage
}
@@ -638,7 +638,7 @@ static void parseBases(RecordInfo &I, const CXXRecordDecl *D) {
// Don't parse bases if this isn't a definition.
if (!D->isThisDeclarationADefinition())
return;
-
+
for (const CXXBaseSpecifier &B : D->bases()) {
if (B.isVirtual())
continue;
@@ -739,8 +739,7 @@ static void populateInfo(Info &I, const T *D, const FullComment *C,
template <typename T>
static void populateSymbolInfo(SymbolInfo &I, const T *D, const FullComment *C,
- Location Loc,
- bool &IsInAnonymousNamespace) {
+ Location Loc, bool &IsInAnonymousNamespace) {
populateInfo(I, D, C, IsInAnonymousNamespace);
if (D->isThisDeclarationADefinition())
I.DefLoc = Loc;
@@ -749,8 +748,7 @@ static void populateSymbolInfo(SymbolInfo &I, const T *D, const FullComment *C,
}
static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
- const FullComment *FC,
- Location Loc,
+ const FullComment *FC, Location Loc,
bool &IsInAnonymousNamespace) {
populateSymbolInfo(I, D, FC, Loc, IsInAnonymousNamespace);
I.ReturnType = getTypeInfoForType(D->getReturnType());
@@ -851,7 +849,7 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly) {
auto I = std::make_unique<NamespaceInfo>();
bool IsInAnonymousNamespace = false;
@@ -872,14 +870,14 @@ emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const RecordDecl *D, const FullComment *FC,
- Location Loc, bool PublicOnly) {
+emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly) {
auto I = std::make_unique<RecordInfo>();
bool IsInAnonymousNamespace = false;
populateSymbolInfo(*I, D, FC, Loc, IsInAnonymousNamespace);
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
-
+
I->TagType = D->getTagKind();
parseFields(*I, D, PublicOnly);
if (const auto *C = dyn_cast<CXXRecordDecl>(D)) {
@@ -940,8 +938,8 @@ emitInfo(const RecordDecl *D, const FullComment *FC,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const FunctionDecl *D, const FullComment *FC,
- Location Loc, bool PublicOnly) {
+emitInfo(const FunctionDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly) {
FunctionInfo Func;
bool IsInAnonymousNamespace = false;
populateFunctionInfo(Func, D, FC, Loc, IsInAnonymousNamespace);
@@ -954,8 +952,8 @@ emitInfo(const FunctionDecl *D, const FullComment *FC,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const CXXMethodDecl *D, const FullComment *FC,
- Location Loc, bool PublicOnly) {
+emitInfo(const CXXMethodDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly) {
FunctionInfo Func;
bool IsInAnonymousNamespace = false;
populateFunctionInfo(Func, D, FC, Loc, IsInAnonymousNamespace);
@@ -982,21 +980,21 @@ emitInfo(const CXXMethodDecl *D, const FullComment *FC,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly) {
-
+
TypedefInfo Info;
- ASTContext& Context = D->getASTContext();
+ ASTContext &Context = D->getASTContext();
bool IsInAnonymousNamespace = false;
populateInfo(Info, D, FC, IsInAnonymousNamespace);
-
+
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
-
+
Info.DefLoc = Loc;
Info.Underlying = getTypeInfoForType(D->getUnderlyingType());
Info.TypeDeclaration = getTypeDefDecl(D);
-
+
if (Info.Underlying.Type.Name.empty()) {
// Typedef for an unnamed type. This is like "typedef struct { } Foo;"
// The record serializer explicitly checks for this syntax and constructs
@@ -1018,10 +1016,10 @@ emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
// A type alias is a C++ "using" declaration for a type. It gets mapped to a
// TypedefInfo with the IsUsing flag set.
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypeAliasDecl *D, const FullComment *FC,
- Location Loc, bool PublicOnly) {
+emitInfo(const TypeAliasDecl *D, const FullComment *FC, Location Loc,
+ bool PublicOnly) {
TypedefInfo Info;
- ASTContext& Context = D->getASTContext();
+ ASTContext &Context = D->getASTContext();
bool IsInAnonymousNamespace = false;
populateInfo(Info, D, FC, IsInAnonymousNamespace);
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
@@ -1031,7 +1029,7 @@ emitInfo(const TypeAliasDecl *D, const FullComment *FC,
Info.Underlying = getTypeInfoForType(D->getUnderlyingType());
Info.TypeDeclaration = getTypeAlias(D);
Info.IsUsing = true;
-
+
if (RawComment *Comment = D->getASTContext().getRawCommentForDeclNoCache(D)) {
Comment->setAttached();
if (comments::FullComment *Fc = Comment->parse(Context, nullptr, D)) {
@@ -1044,12 +1042,12 @@ emitInfo(const TypeAliasDecl *D, const FullComment *FC,
}
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly) {
EnumInfo Enum;
bool IsInAnonymousNamespace = false;
populateSymbolInfo(Enum, D, FC, Loc, IsInAnonymousNamespace);
-
+
if (!shouldSerializeInfo(PublicOnly, IsInAnonymousNamespace, D))
return {};
diff --git a/clang-tools-extra/clang-doc/Serialize.h b/clang-tools-extra/clang-doc/Serialize.h
index 8874299e9a..bdf969aa56 100644
--- a/clang-tools-extra/clang-doc/Serialize.h
+++ b/clang-tools-extra/clang-doc/Serialize.h
@@ -37,31 +37,31 @@ namespace serialize {
// its parent scope. For NamespaceDecl and RecordDecl both elements are not
// nullptr.
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const RecordDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const EnumDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const FunctionDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const FunctionDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const CXXMethodDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const CXXMethodDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const TypedefDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
-emitInfo(const TypeAliasDecl *D, const FullComment *FC, Location Loc,
+emitInfo(const TypeAliasDecl *D, const FullComment *FC, Location Loc,
bool PublicOnly);
// Function to hash a given USR value for storage.
diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
index 0bde27eb2a..688d856d7c 100644
--- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -99,12 +99,7 @@ URL of repository that hosts code.
Used for links to definition locations.)"),
llvm::cl::cat(ClangDocCategory));
-enum OutputFormatTy {
- md,
- yaml,
- html,
- mhtml
-};
+enum OutputFormatTy { md, yaml, html, mhtml };
static llvm::cl::opt<OutputFormatTy>
FormatEnum("format", llvm::cl::desc("Format for outputted docs."),
@@ -163,15 +158,14 @@ llvm::Error getAssetFiles(clang::doc::ClangDocContext &CDCtx) {
return llvm::Error::success();
}
-llvm::SmallString<128> appendPathNative(llvm::SmallString<128> Path,
- llvm::StringRef Asset) {
+llvm::SmallString<128> appendPathNative(llvm::SmallString<128> Path,
+ llvm::StringRef Asset) {
llvm::SmallString<128> Default;
llvm::sys::path::native(Path, Default);
llvm::sys::path::append(Default, Asset);
return Default;
}
-
llvm::Error getDefaultAssetFiles(const char *Argv0,
clang::doc::ClangDocContext &CDCtx) {
void *MainAddr = (void *)(intptr_t)getExecutablePath;
@@ -184,8 +178,7 @@ llvm::Error getDefaultAssetFiles(const char *Argv0,
llvm::sys::path::append(AssetsPath, "..", "share", "clang-doc");
llvm::SmallString<128> DefaultStylesheet =
appendPathNative(AssetsPath, "clang-doc-default-stylesheet.css");
- llvm::SmallString<128> IndexJS =
- appendPathNative(AssetsPath, "index.js");
+ llvm::SmallString<128> IndexJS = appendPathNative(AssetsPath, "index.js");
if (!llvm::sys::fs::is_regular_file(IndexJS))
return llvm::createStringError(llvm::inconvertibleErrorCode(),
@@ -216,7 +209,6 @@ llvm::Error getHtmlAssetFiles(const char *Argv0,
return getDefaultAssetFiles(Argv0, CDCtx);
}
-
llvm::Error getMustacheHtmlFiles(const char *Argv0,
clang::doc::ClangDocContext &CDCtx) {
if (!UserAssetPath.empty() &&
@@ -225,45 +217,43 @@ llvm::Error getMustacheHtmlFiles(const char *Argv0,
<< " falling back to default\n";
if (llvm::sys::fs::is_directory(std::string(UserAssetPath)))
return getAssetFiles(CDCtx);
-
+
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");
-
- llvm::SmallString<128> DefaultStylesheet
- = appendPathNative(AssetsPath, "clang-doc-mustache.css");
- llvm::SmallString<128> NamespaceTemplate
- = appendPathNative(AssetsPath, "namespace-template.mustache");
- llvm::SmallString<128> ClassTemplate
- = appendPathNative(AssetsPath, "class-template.mustache");
- llvm::SmallString<128> EnumTemplate
- = appendPathNative(AssetsPath, "enum-template.mustache");
- llvm::SmallString<128> FunctionTemplate
- = appendPathNative(AssetsPath, "function-template.mustache");
- llvm::SmallString<128> CommentTemplate
- = appendPathNative(AssetsPath, "comments-template.mustache");
- llvm::SmallString<128> IndexJS
- = appendPathNative(AssetsPath, "mustache-index.js");
-
+
+ llvm::SmallString<128> DefaultStylesheet =
+ appendPathNative(AssetsPath, "clang-doc-mustache.css");
+ llvm::SmallString<128> NamespaceTemplate =
+ appendPathNative(AssetsPath, "namespace-template.mustache");
+ llvm::SmallString<128> ClassTemplate =
+ appendPathNative(AssetsPath, "class-template.mustache");
+ llvm::SmallString<128> EnumTemplate =
+ appendPathNative(AssetsPath, "enum-template.mustache");
+ llvm::SmallString<128> FunctionTemplate =
+ appendPathNative(AssetsPath, "function-template.mustache");
+ llvm::SmallString<128> CommentTemplate =
+ appendPathNative(AssetsPath, "comments-template.mustache");
+ llvm::SmallString<128> IndexJS =
+ appendPathNative(AssetsPath, "mustache-index.js");
+
CDCtx.JsScripts.insert(CDCtx.JsScripts.begin(), IndexJS.c_str());
CDCtx.UserStylesheets.insert(CDCtx.UserStylesheets.begin(),
std::string(DefaultStylesheet));
- CDCtx.MustacheTemplates.insert({"namespace-template",
- NamespaceTemplate.c_str()});
- CDCtx.MustacheTemplates.insert({"class-template",
- ClassTemplate.c_str()});
- CDCtx.MustacheTemplates.insert({"enum-template",
- EnumTemplate.c_str()});
- CDCtx.MustacheTemplates.insert({"function-template",
- FunctionTemplate.c_str()});
- CDCtx.MustacheTemplates.insert({"comments-template",
- CommentTemplate.c_str()});
-
+ CDCtx.MustacheTemplates.insert(
+ {"namespace-template", NamespaceTemplate.c_str()});
+ CDCtx.MustacheTemplates.insert({"class-template", ClassTemplate.c_str()});
+ CDCtx.MustacheTemplates.insert({"enum-template", EnumTemplate.c_str()});
+ CDCtx.MustacheTemplates.insert(
+ {"function-template", FunctionTemplate.c_str()});
+ CDCtx.MustacheTemplates.insert(
+ {"comments-template", CommentTemplate.c_str()});
+
return llvm::Error::success();
}
@@ -339,7 +329,7 @@ Example usage for a project using a compile commands database:
return 1;
}
}
-
+
if (Format == "mhtml") {
if (auto Err = getMustacheHtmlFiles(argv[0], CDCtx)) {
llvm::errs() << toString(std::move(Err)) << "\n";
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you're planing to split this up, but here's some preliminary feedback.
std::error_code OK; | ||
std::error_code FileErr = llvm::sys::fs::copy_file(PathRead, PathWrite); | ||
if (FileErr != OK) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::error_code OK; | |
std::error_code FileErr = llvm::sys::fs::copy_file(PathRead, PathWrite); | |
if (FileErr != OK) { | |
std::error_code FileErr = llvm::sys::fs::copy_file(PathRead, PathWrite); | |
if (FileErr) { |
llvm::SmallString<128> computeRelativePath(llvm::StringRef Destination, | ||
llvm::StringRef Origin) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should drop this in favor of std::filesystem::relative()
?
@@ -0,0 +1,26 @@ | |||
//===-- FileHelpersClangDoc.h --- File Helpers -------------------*- C++-*-===// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably putting this in clang-doc/support/File.h
is a bit more typical. At the least the file shouldn't have helper in the name, and probably doesn't need ClangDoc in it either.
@@ -379,7 +394,7 @@ struct RecordInfo : public SymbolInfo { | |||
// Full qualified name of this record, including namespaces and template | |||
// specializations. | |||
SmallString<16> FullName; | |||
|
|||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: empty space. the newline is fine though.
|
||
// Inidicates if this is a new C++ "using"-style typedef: | ||
// Underlying type declaration | ||
SmallString<16> TypeDeclaration; | ||
// Indicates if this is a new C++ "using"-style typedef: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use consistent spacing. If you find the file is already inconsistent, then lets make a PR to fix that first.
@@ -359,6 +371,9 @@ struct FunctionInfo : public SymbolInfo { | |||
// Full qualified name of this function, including namespaces and template | |||
// specializations. | |||
SmallString<16> FullName; | |||
|
|||
// Function Prototype | |||
SmallString<256> ProtoType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why 256? you realize that allocates a 256 byte buffer in this struct, right? Do we expect to use many of them? Do you have a feeling for the typical size of the Prototype? like what's the median size in say LLVM? what about 90th percentile? I have a feeling there is a better default that won't use so much space.
Also, I have a felling the layout will be kind of odd right now. You can try adding -Wpadding to the clang-doc build to see if there's a better layout for these internal types.
|
||
std::vector<CommentInfo> Description; /// Comment description of this field. | ||
|
||
/// Comment description of this field. | ||
std::vector<CommentInfo> Description; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets try to keep cleanups like this in their own PRs. The same goes for any other changes that can be done independently of adding Mustache support.
if (Method) { | ||
if (Method->isVirtual()) | ||
{ | ||
Stream << "virtual "; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (Method) { | |
if (Method->isVirtual()) | |
{ | |
Stream << "virtual "; | |
} | |
} | |
if (Method && Method->isVirtual()){ | |
Stream << "virtual "; | |
} |
const Expr *DefaultArg = ParamDecl->getDefaultArg(); | ||
if (DefaultArg) { | ||
Stream << " = "; | ||
DefaultArg->printPretty(Stream, nullptr, Ctx.getPrintingPolicy()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DefaultArg only gets used in the conditional. you can use
if(const Expr* DefaultArg = ...){ ... }
|
||
// Extract the full function prototype from a FunctionDecl including | ||
// Full Decl | ||
llvm::SmallString<256> getFunctionPrototype(const FunctionDecl *FuncDecl) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much does this output differ from PrintName()
or getNameForDiagnostic()
? I'm wondering if we need a custom thing here since we have the FunctionDecl.
https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html#af40656355e6d13ca9d7de07340b1b46c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having very repetitive code is a pervasive problem throughout clang-doc, but I still feel like there's quite a lot in the generator code.
I'm also wondering if its the best idea to generate for each info serially. I don't want to try and change that right now, but in general, is it possible to use a thread pool to get some parallelism as we're processing each Info? or is that fundamentally incompatible with what we're doing?
setupTemplateValue(CDCtx, V, I); | ||
// Serialize the JSON value to the output stream in a readable format. | ||
llvm::outs() << "Visit: " << I->Name << "\n"; | ||
//llvm::outs() << llvm::formatv("{0:2}", V) << "\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debugging leftover?
Value V = extractValue(*static_cast<clang::doc::RecordInfo *>(I), CDCtx); | ||
setupTemplateValue(CDCtx, V, I); | ||
// Serialize the JSON value to the output stream in a readable format. | ||
llvm::outs() << "Visit: " << I->Name << "\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this be pretty verbose? Should this be wrapped in LLVM_DEBUG or something instead?
// Serialize the JSON value to the output stream in a readable format. | ||
llvm::outs() << "Visit: " << I->Name << "\n"; | ||
//llvm::outs() << llvm::formatv("{0:2}", V) << "\n"; | ||
llvm::outs() << RecordTemplate->render(V); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be OS
instead of llvm::outs()
? Not sure why we'd want to render the template to standard output...
else if (Access == AccessSpecifier::AS_protected) | ||
ProtectedFunction.getAsArray()->emplace_back(F); | ||
else | ||
ArrFunction.getAsArray()->emplace_back(F); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you using ArrFunction.getAsArray()
a lot. We should probably cache a reference to it.
return Obj; | ||
} | ||
|
||
Value extractValue(const EnumInfo &I, const ClangDocContext &CDCtx) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is an llvm::json::Value
then lets keep at least the json::
prefix. Value is a very overloaded term in LLVM.
if (CDCtx.RepositoryUrl.has_value()) | ||
Obj.insert({"Location", extractValue(L, | ||
StringRef{*CDCtx.RepositoryUrl})}); | ||
else | ||
Obj.insert({"Location", extractValue(L)}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a bit nicer to use .value_or()
, right?
if (CDCtx.RepositoryUrl.has_value()) | ||
Obj.insert({"Location", extractValue(L, | ||
StringRef{*CDCtx.RepositoryUrl})}); | ||
else | ||
Obj.insert({"Location", extractValue(L)}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
value_or()
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
…8058) Split from llvm#133161. This patch allows Typedefs to now track both their declarations and full descriptions. Subsequent patches will leverage the additional fields in the representation. Co-authored-by: Peter Chou <[email protected]>
This patch adds the various assets used with the HTML Mustache backend. This includes templates for a variety of different language constructs, as well as the CSS. Split from llvm#133161. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Split from #133161. This patch adds HTMLMustacheGenerator.cpp, and the most basic class defintion for the generator. Future patches will add functionality. Co-authored-by: Peter Chou <[email protected]>
Split from #133161. This patch fills in the implementation for a number of the MustacheHTMLGenerator methods. Many of these APIs are just stubbed out, and will have their implementation filled in by later patches. Co-authored-by: Peter Chou <[email protected]>
This patch adds or fills in some helper functions related to template setup when initializing the mustache backend. It was split from #133161. Co-authored-by: Peter Chou <[email protected]>
Split from #133161. This patch provides the implementation of a number of extractValue overloads used with the different types of Info. The new helper functions extract the relevant information from the different *Infos and inserts them into the correct fields of the JSON values that will be used with the specific Mustache templates, which will land separately. Co-authored-by: Peter Chou <[email protected]>
This patch implements the business logic for setupTemplateValue, which was split from #133161. The implementation configures the relative path relationships between the various HTML components, and prepares them prior to their use in the generator. Co-authored-by: Peter Chou <[email protected]>
This patch updates Serialize.cpp to serialize more data about C++ templates, which are supported by the new mustache HTML template. Split from #133161. Co-authored-by: Peter Chou <[email protected]>
This patch adds a command line option and enables the Mustache template HTML backend. This allows users to use the new, more flexible templates over the old and cumbersome HTML output. Split from #133161. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Split from #133161. This patch fills in the implementation for a number of the MustacheHTMLGenerator methods. Many of these APIs are just stubbed out, and will have their implementation filled in by later patches. Co-authored-by: Peter Chou <[email protected]>
This patch adds or fills in some helper functions related to template setup when initializing the mustache backend. It was split from #133161. Co-authored-by: Peter Chou <[email protected]>
Split from #133161. This patch provides the implementation of a number of extractValue overloads used with the different types of Info. The new helper functions extract the relevant information from the different *Infos and inserts them into the correct fields of the JSON values that will be used with the specific Mustache templates, which will land separately. Co-authored-by: Peter Chou <[email protected]>
This patch implements the business logic for setupTemplateValue, which was split from #133161. The implementation configures the relative path relationships between the various HTML components, and prepares them prior to their use in the generator. Co-authored-by: Peter Chou <[email protected]>
This patch updates Serialize.cpp to serialize more data about C++ templates, which are supported by the new mustache HTML template. Split from #133161. Co-authored-by: Peter Chou <[email protected]>
This patch adds a command line option and enables the Mustache template HTML backend. This allows users to use the new, more flexible templates over the old and cumbersome HTML output. Split from #133161. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
Originally part of #133161. This patch adds preliminary tracking for of TypeInfo, by tracking if the type is a builtin or template. The new functionality is not yet exercised. Co-authored-by: Peter Chou <[email protected]>
No description provided.