Index: clang-tools-extra/clang-doc/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-doc/CMakeLists.txt
+++ clang-tools-extra/clang-doc/CMakeLists.txt
@@ -10,6 +10,7 @@
ClangDoc.cpp
Generators.cpp
HTMLGenerator.cpp
+ HTMLTemplates.cpp
Mapper.cpp
MDGenerator.cpp
Representation.cpp
Index: clang-tools-extra/clang-doc/HTMLGenerator.cpp
===================================================================
--- clang-tools-extra/clang-doc/HTMLGenerator.cpp
+++ clang-tools-extra/clang-doc/HTMLGenerator.cpp
@@ -7,10 +7,12 @@
//===----------------------------------------------------------------------===//
#include "Generators.h"
+#include "HTMLTemplates.h"
#include "Representation.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include
#include
using namespace llvm;
@@ -18,105 +20,237 @@
namespace clang {
namespace doc {
-namespace {
+std::string genHTML(const EnumInfo &I);
+std::string genHTML(const FunctionInfo &I);
-// HTML generation
-
-std::string genTag(const Twine &Text, const Twine &Tag) {
- return "<" + Tag.str() + ">" + Text.str() + "" + Tag.str() + ">";
+template
+char *applyHTMLTemplate(const char *Template, Args... TemplateArguments) {
+ // Get the buffer size required
+ int Size = snprintf(NULL, 0, Template, TemplateArguments...);
+ char *Output = new char[Size + 1];
+ sprintf(Output, Template, TemplateArguments...);
+ return std::move(Output);
}
-std::string genItalic(const Twine &Text) { return genTag(Text, "em"); }
+std::string genEnumsBlock(const std::vector &Children) {
+ std::string Output;
+ if (!Children.empty()) {
+ std::string Header =
+ applyHTMLTemplate(HTMLTemplates::SectionHeader, "Enums");
+ std::string Items;
+ for (const auto &C : Children) {
+ Items += genHTML(C);
+ }
+ std::string List =
+ applyHTMLTemplate(HTMLTemplates::BlockList, Items.c_str());
+ Output = applyHTMLTemplate(HTMLTemplates::HeaderDataBlock, Header.c_str(),
+ Items.c_str());
+ }
+ return Output;
+}
-std::string genEmphasis(const Twine &Text) { return genTag(Text, "strong"); }
+std::string
+genEnumMembersBlock(const llvm::SmallVector, 4> &Members) {
+ std::string Output;
+ if (!Members.empty()) {
+ std::string Items;
+ for (const auto &M : Members) {
+ // FIXME: Transition EnumInfos's Members from llvm::SmallString to
+ // std::string
+ Items +=
+ applyHTMLTemplate(HTMLTemplates::BlockItem, M.str().str().c_str());
+ }
+ Output = applyHTMLTemplate(HTMLTemplates::BlockList, Items.c_str());
+ }
+ return Output;
+}
-void writeLine(const Twine &Text, raw_ostream &OS) {
- OS << genTag(Text, "p") << "\n";
+std::string genFunctionsBlock(const std::vector &Children) {
+ std::string Output;
+ if (!Children.empty()) {
+ std::string Header =
+ applyHTMLTemplate(HTMLTemplates::SectionHeader, "Functions");
+ std::string Items;
+ for (const auto &C : Children) {
+ Items += genHTML(C);
+ }
+ std::string List =
+ applyHTMLTemplate(HTMLTemplates::BlockList, Items.c_str());
+ Output = applyHTMLTemplate(HTMLTemplates::HeaderDataBlock, Header.c_str(),
+ Items.c_str());
+ }
+ return Output;
}
-void writeNewLine(raw_ostream &OS) { OS << "
\n"; }
+std::string
+genRecordMembersBlock(const llvm::SmallVector &Members) {
+ std::string Output;
+ if (!Members.empty()) {
+ std::string Header =
+ applyHTMLTemplate(HTMLTemplates::SectionHeader, "Members");
+ std::string Items;
+ for (const auto &M : Members) {
+ std::string Access = getAccess(M.Access);
+ if (Access != "")
+ Access = Access + " ";
+ // FIXME: Transition Reference's Name from llvm::SmallString to
+ // std::string
+ // FIXME: Transition FieldTypeInfo's Name from llvm::SmallString to
+ // std::string
+ std::string Content = applyHTMLTemplate(
+ HTMLTemplates::RecordMemberContent, Access.c_str(),
+ M.Type.Name.str().str().c_str(), M.Name.str().str().c_str());
+ Items += applyHTMLTemplate(HTMLTemplates::BlockItem, Content.c_str());
+ }
+ std::string List =
+ applyHTMLTemplate(HTMLTemplates::BlockList, Items.c_str());
+ Output = applyHTMLTemplate(HTMLTemplates::HeaderDataBlock, Header.c_str(),
+ List.c_str());
+ }
+ return Output;
+}
-void writeHeader(const Twine &Text, const Twine &Num, raw_ostream &OS) {
- OS << genTag(Text, "h" + Num) << "\n";
+std::string genReferencesBlock(const std::vector &References,
+ const char *Title) {
+ std::string Output;
+ if (!References.empty()) {
+ std::string Header = applyHTMLTemplate(HTMLTemplates::SectionHeader, Title);
+ std::string Items;
+ for (const auto &R : References) {
+ Items += applyHTMLTemplate(HTMLTemplates::BlockItem,
+ R.Name.str().str().c_str());
+ ;
+ }
+ std::string List =
+ applyHTMLTemplate(HTMLTemplates::BlockList, Items.c_str());
+ Output = applyHTMLTemplate(HTMLTemplates::HeaderDataBlock, Header.c_str(),
+ Items.c_str());
+ }
+ return Output;
}
-void writeFileDefinition(const Location &L, raw_ostream &OS) {
- writeLine(genItalic("Defined at line " + std::to_string(L.LineNumber) +
- " of " + L.Filename),
- OS);
+std::string writeFileDefinition(const Location &L) {
+ // FIXME: Transition Location's Filename from llvm::SmallString to std::string
+ return applyHTMLTemplate(HTMLTemplates::FileDefinition, L.LineNumber,
+ L.Filename.str().str().c_str());
}
-void writeDescription(const CommentInfo &I, raw_ostream &OS) {
+std::string genHTML(const CommentInfo &I) {
if (I.Kind == "FullComment") {
+ std::string Output;
for (const auto &Child : I.Children)
- writeDescription(*Child, OS);
+ Output += genHTML(*Child);
+ return applyHTMLTemplate(HTMLTemplates::FullComment, Output.c_str());
} else if (I.Kind == "ParagraphComment") {
+ std::string Output;
for (const auto &Child : I.Children)
- writeDescription(*Child, OS);
- writeNewLine(OS);
+ Output += genHTML(*Child);
+ if (Output == "")
+ return {};
+ return applyHTMLTemplate(HTMLTemplates::ParagraphComment, Output.c_str());
} else if (I.Kind == "BlockCommandComment") {
- OS << genEmphasis(I.Name);
+ std::string Output;
for (const auto &Child : I.Children)
- writeDescription(*Child, OS);
+ Output += genHTML(*Child);
+ // FIXME: Transition CommentInfo's Name from llvm::SmallString to
+ // std::string
+ return applyHTMLTemplate(HTMLTemplates::BlockCommandComment,
+ I.Name.str().str().c_str(), Output.c_str());
} else if (I.Kind == "InlineCommandComment") {
- OS << genEmphasis(I.Name) << " " << I.Text;
+ // FIXME: Transition CommentInfo's Text from llvm::SmallString to
+ // std::string
+ return applyHTMLTemplate(HTMLTemplates::InlineCommandComment,
+ I.Name.str().str().c_str(),
+ I.Text.str().str().c_str());
} else if (I.Kind == "ParamCommandComment") {
std::string Direction = I.Explicit ? (" " + I.Direction).str() : "";
- OS << genEmphasis(I.ParamName) << I.Text << Direction << "\n\n";
+ std::string Output;
+ for (const auto &Child : I.Children)
+ Output += genHTML(*Child);
+ // FIXME: Transition CommentInfo's ParamName from llvm::SmallString to
+ // std::string
+ return applyHTMLTemplate(HTMLTemplates::ParamCommandComment,
+ I.ParamName.str().str().c_str(), Direction.c_str(),
+ Output.c_str());
} else if (I.Kind == "TParamCommandComment") {
std::string Direction = I.Explicit ? (" " + I.Direction).str() : "";
- OS << genEmphasis(I.ParamName) << I.Text << Direction << "\n\n";
+ std::string Output;
+ for (const auto &Child : I.Children)
+ Output += genHTML(*Child);
+ return applyHTMLTemplate(HTMLTemplates::TParamCommandComment,
+ I.ParamName.str().str().c_str(), Direction.c_str(),
+ Output.c_str());
} else if (I.Kind == "VerbatimBlockComment") {
+ std::string Output;
for (const auto &Child : I.Children)
- writeDescription(*Child, OS);
+ Output += genHTML(*Child);
+ return applyHTMLTemplate(HTMLTemplates::VerbatimBlockComment,
+ Output.c_str());
} else if (I.Kind == "VerbatimBlockLineComment") {
- OS << I.Text;
- writeNewLine(OS);
+ return applyHTMLTemplate(HTMLTemplates::VerbatimBlockLineComment,
+ I.Text.str().str().c_str());
} else if (I.Kind == "VerbatimLineComment") {
- OS << I.Text;
- writeNewLine(OS);
+ return applyHTMLTemplate(HTMLTemplates::VerbatimLineComment,
+ I.Text.str().str().c_str());
} else if (I.Kind == "HTMLStartTagComment") {
if (I.AttrKeys.size() != I.AttrValues.size())
- return;
- std::string Buffer;
- llvm::raw_string_ostream Attrs(Buffer);
+ return {};
+ std::string Attrs;
for (unsigned Idx = 0; Idx < I.AttrKeys.size(); ++Idx)
- Attrs << " \"" << I.AttrKeys[Idx] << "=" << I.AttrValues[Idx] << "\"";
-
+ // FIXME: Transition CommentInfo's AttrKeys and AttrValues from
+ // llvm::SmallString to std::string
+ Attrs += applyHTMLTemplate(HTMLTemplates::HTMLStartTagAttribute,
+ I.AttrKeys[Idx].str().str().c_str(),
+ I.AttrValues[Idx].str().str().c_str());
std::string CloseTag = I.SelfClosing ? "/>" : ">";
- writeLine("<" + I.Name + Attrs.str() + CloseTag, OS);
+ return applyHTMLTemplate(HTMLTemplates::HTMLStartTagComment,
+ I.Name.str().str().c_str(), Attrs.c_str(),
+ CloseTag.c_str());
} else if (I.Kind == "HTMLEndTagComment") {
- writeLine("" + I.Name + ">", OS);
+ return applyHTMLTemplate(HTMLTemplates::HTMLEndTagComment,
+ I.Name.str().str().c_str());
} else if (I.Kind == "TextComment") {
- OS << I.Text;
+ return I.Text.str();
} else {
- OS << "Unknown comment kind: " << I.Kind << ".\n\n";
+ // FIXME: Transition CommentInfo's Kind from llvm::SmallString to
+ // std::string
+ return applyHTMLTemplate(HTMLTemplates::UnknownComment,
+ I.Kind.str().str().c_str());
}
}
-} // namespace
-
-void genHTML(const EnumInfo &I, llvm::raw_ostream &OS) {
+std::string genHTML(const EnumInfo &I) {
+ std::string EnumType;
if (I.Scoped)
- writeLine("| enum class " + I.Name + " |", OS);
+ EnumType = "enum class";
else
- writeLine("| enum " + I.Name + " |", OS);
- writeLine("--", OS);
+ EnumType = "enum";
+ std::string Header =
+ applyHTMLTemplate(HTMLTemplates::EnumInfoName, EnumType.c_str(),
+ I.Name.str().str().c_str());
+ Header = applyHTMLTemplate(HTMLTemplates::FunctionEnumHeader, Header.c_str());
- std::string Buffer;
- llvm::raw_string_ostream Members(Buffer);
- if (!I.Members.empty())
- for (const auto &N : I.Members)
- Members << "| " << N << " |\n";
- writeLine(Members.str(), OS);
- if (I.DefLoc)
- writeFileDefinition(I.DefLoc.getValue(), OS);
+ std::string Members = genEnumMembersBlock(I.Members);
- for (const auto &C : I.Description)
- writeDescription(C, OS);
+ std::string DefLoc = I.DefLoc ? writeFileDefinition(I.DefLoc.getValue()) : "";
+
+ std::string Description;
+ if (!I.Description.empty()) {
+ for (const auto &C : I.Description)
+ Description += genHTML(C);
+ Description =
+ applyHTMLTemplate(HTMLTemplates::CommentBlock, Description.c_str());
+ }
+
+ return applyHTMLTemplate(HTMLTemplates::EnumBlock, Header.c_str(),
+ Members.c_str(), DefLoc.c_str(),
+ Description.c_str());
}
-void genHTML(const FunctionInfo &I, llvm::raw_ostream &OS) {
+std::string genHTML(const FunctionInfo &I) {
+ std::string Header = applyHTMLTemplate(HTMLTemplates::FunctionEnumHeader,
+ I.Name.str().str().c_str());
+
std::string Buffer;
llvm::raw_string_ostream Stream(Buffer);
bool First = true;
@@ -126,115 +260,105 @@
Stream << N.Type.Name + " " + N.Name;
First = false;
}
- writeHeader(I.Name, "3", OS);
+
std::string Access = getAccess(I.Access);
if (Access != "")
- writeLine(genItalic(Access + " " + I.ReturnType.Type.Name + " " + I.Name +
- "(" + Stream.str() + ")"),
- OS);
- else
- writeLine(genItalic(I.ReturnType.Type.Name + " " + I.Name + "(" +
- Stream.str() + ")"),
- OS);
- if (I.DefLoc)
- writeFileDefinition(I.DefLoc.getValue(), OS);
+ Access = Access + " ";
+
+ std::string DefHeader =
+ applyHTMLTemplate(HTMLTemplates::FunctionDefHeader, Access.c_str(),
+ I.ReturnType.Type.Name.str().str().c_str(),
+ I.Name.str().str().c_str(), Stream.str().c_str());
+
+ std::string DefLoc = I.DefLoc ? writeFileDefinition(I.DefLoc.getValue()) : "";
+
+ std::string Description;
+ if (!I.Description.empty()) {
+ for (const auto &C : I.Description)
+ Description += genHTML(C);
+ Description =
+ applyHTMLTemplate(HTMLTemplates::CommentBlock, Description.c_str());
+ }
- for (const auto &C : I.Description)
- writeDescription(C, OS);
+ return applyHTMLTemplate(HTMLTemplates::FunctionBlock, Header.c_str(),
+ DefHeader.c_str(), DefLoc.c_str(),
+ Description.c_str());
}
-void genHTML(const NamespaceInfo &I, llvm::raw_ostream &OS) {
- if (I.Name == "")
- writeHeader("Global Namespace", "1", OS);
+std::string genHTML(const NamespaceInfo &I, std::string &InfoTitle) {
+ if (I.Name.str() == "")
+ InfoTitle = HTMLTemplates::GlobalNamespaceName;
else
- writeHeader("namespace " + I.Name, "1", OS);
- writeNewLine(OS);
+ InfoTitle = applyHTMLTemplate(HTMLTemplates::NamespaceInfoName,
+ I.Name.str().str().c_str());
+ std::string Header =
+ applyHTMLTemplate(HTMLTemplates::TopLevelInfoHeader, InfoTitle.c_str());
+
+ std::string Description;
if (!I.Description.empty()) {
for (const auto &C : I.Description)
- writeDescription(C, OS);
- writeNewLine(OS);
+ Description += genHTML(C);
+ Description =
+ applyHTMLTemplate(HTMLTemplates::CommentBlock, Description.c_str());
}
- if (!I.ChildNamespaces.empty()) {
- writeHeader("Namespaces", "2", OS);
- for (const auto &R : I.ChildNamespaces)
- writeLine(R.Name, OS);
- writeNewLine(OS);
- }
- if (!I.ChildRecords.empty()) {
- writeHeader("Records", "2", OS);
- for (const auto &R : I.ChildRecords)
- writeLine(R.Name, OS);
- writeNewLine(OS);
- }
- if (!I.ChildFunctions.empty()) {
- writeHeader("Functions", "2", OS);
- for (const auto &F : I.ChildFunctions)
- genHTML(F, OS);
- writeNewLine(OS);
- }
- if (!I.ChildEnums.empty()) {
- writeHeader("Enums", "2", OS);
- for (const auto &E : I.ChildEnums)
- genHTML(E, OS);
- writeNewLine(OS);
- }
+ std::string ChildNamespaces =
+ genReferencesBlock(I.ChildNamespaces, "Namespaces");
+ std::string ChildRecords = genReferencesBlock(I.ChildRecords, "Records");
+
+ std::string ChildFunctions = genFunctionsBlock(I.ChildFunctions);
+ std::string ChildEnums = genEnumsBlock(I.ChildEnums);
+
+ return applyHTMLTemplate(HTMLTemplates::NamespaceBlock, Header.c_str(),
+ Description.c_str(), ChildNamespaces.c_str(),
+ ChildRecords.c_str(), ChildFunctions.c_str(),
+ ChildEnums.c_str());
}
-void genHTML(const RecordInfo &I, llvm::raw_ostream &OS) {
- writeHeader(getTagType(I.TagType) + " " + I.Name, "1", OS);
+std::string genHTML(const RecordInfo &I, std::string &InfoTitle) {
+ InfoTitle = applyHTMLTemplate(HTMLTemplates::RecordInfoName,
+ getTagType(I.TagType).c_str(),
+ I.Name.str().str().c_str());
+ std::string Header =
+ applyHTMLTemplate(HTMLTemplates::TopLevelInfoHeader, InfoTitle.c_str());
+
+ std::string DefLoc;
if (I.DefLoc)
- writeFileDefinition(I.DefLoc.getValue(), OS);
+ DefLoc = writeFileDefinition(I.DefLoc.getValue());
+ std::string Description;
if (!I.Description.empty()) {
for (const auto &C : I.Description)
- writeDescription(C, OS);
- writeNewLine(OS);
+ Description += genHTML(C);
+ Description =
+ applyHTMLTemplate(HTMLTemplates::CommentBlock, Description.c_str());
}
+ std::string Inheritance;
std::string Parents = genReferenceList(I.Parents);
std::string VParents = genReferenceList(I.VirtualParents);
if (!Parents.empty() || !VParents.empty()) {
if (Parents.empty())
- writeLine("Inherits from " + VParents, OS);
+ Inheritance = VParents;
else if (VParents.empty())
- writeLine("Inherits from " + Parents, OS);
+ Inheritance = Parents;
else
- writeLine("Inherits from " + Parents + ", " + VParents, OS);
- writeNewLine(OS);
+ Inheritance = Parents + ", " + VParents;
+ Inheritance = applyHTMLTemplate(HTMLTemplates::RecordInheritance,
+ Inheritance.c_str());
}
- if (!I.Members.empty()) {
- writeHeader("Members", "2", OS);
- for (const auto Member : I.Members) {
- std::string Access = getAccess(Member.Access);
- if (Access != "")
- writeLine(Access + " " + Member.Type.Name + " " + Member.Name, OS);
- else
- writeLine(Member.Type.Name + " " + Member.Name, OS);
- }
- writeNewLine(OS);
- }
+ std::string Members = genRecordMembersBlock(I.Members);
+ std::string ChildRecords = genReferencesBlock(I.ChildRecords, "Records");
- if (!I.ChildRecords.empty()) {
- writeHeader("Records", "2", OS);
- for (const auto &R : I.ChildRecords)
- writeLine(R.Name, OS);
- writeNewLine(OS);
- }
- if (!I.ChildFunctions.empty()) {
- writeHeader("Functions", "2", OS);
- for (const auto &F : I.ChildFunctions)
- genHTML(F, OS);
- writeNewLine(OS);
- }
- if (!I.ChildEnums.empty()) {
- writeHeader("Enums", "2", OS);
- for (const auto &E : I.ChildEnums)
- genHTML(E, OS);
- writeNewLine(OS);
- }
+ std::string ChildFunctions = genFunctionsBlock(I.ChildFunctions);
+ std::string ChildEnums = genEnumsBlock(I.ChildEnums);
+
+ return applyHTMLTemplate(
+ HTMLTemplates::RecordBlock, Header.c_str(), DefLoc.c_str(),
+ Description.c_str(), Inheritance.c_str(), Members.c_str(),
+ ChildRecords.c_str(), ChildFunctions.c_str(), ChildEnums.c_str());
}
/// Generator for HTML documentation.
@@ -248,23 +372,32 @@
const char *HTMLGenerator::Format = "html";
llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
+ std::string Output;
+ std::string InfoTitle;
+
switch (I->IT) {
case InfoType::IT_namespace:
- genHTML(*static_cast(I), OS);
+ Output = genHTML(*static_cast(I), InfoTitle);
break;
case InfoType::IT_record:
- genHTML(*static_cast(I), OS);
+ Output = genHTML(*static_cast(I), InfoTitle);
break;
case InfoType::IT_enum:
- genHTML(*static_cast(I), OS);
+ Output = genHTML(*static_cast(I));
break;
case InfoType::IT_function:
- genHTML(*static_cast(I), OS);
+ Output = genHTML(*static_cast(I));
break;
case InfoType::IT_default:
return llvm::make_error("Unexpected info type.\n",
llvm::inconvertibleErrorCode());
}
+
+ Output = applyHTMLTemplate(HTMLTemplates::MainContent, Output.c_str());
+ Output = applyHTMLTemplate(HTMLTemplates::HTMLDoc, InfoTitle.c_str(),
+ Output.c_str());
+ OS << Output;
+
return llvm::Error::success();
}
Index: clang-tools-extra/clang-doc/HTMLTemplates.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-doc/HTMLTemplates.h
@@ -0,0 +1,61 @@
+///===-- HTMLTemplates.h - ClangDoc Representation --------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the HTML templates used to generate HTML documentation
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_HTMLTEMPLATES_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_HTMLTEMPLATES_H
+
+#include
+
+namespace clang {
+namespace doc {
+
+struct HTMLTemplates {
+ static const char *NamespaceBlock;
+ static const char *RecordBlock;
+ static const char *CommentBlock;
+ static const char *FunctionBlock;
+ static const char *EnumBlock;
+ static const char *TopLevelInfoHeader;
+ static const char *RecordInfoName;
+ static const char *NamespaceInfoName;
+ static const char *GlobalNamespaceName;
+ static const char *HeaderDataBlock;
+ static const char *FileDefinition;
+ static const char *RecordInheritance;
+ static const char *FunctionEnumHeader;
+ static const char *EnumInfoName;
+ static const char *FunctionDefHeader;
+ static const char *SectionHeader;
+ static const char *BlockList;
+ static const char *BlockItem;
+ static const char *RecordMemberContent;
+ static const char *FullComment;
+ static const char *ParagraphComment;
+ static const char *BlockCommandComment;
+ static const char *InlineCommandComment;
+ static const char *ParamCommandComment;
+ static const char *TParamCommandComment;
+ static const char *VerbatimBlockComment;
+ static const char *VerbatimBlockLineComment;
+ static const char *VerbatimLineComment;
+ static const char *HTMLStartTagAttribute;
+ static const char *HTMLStartTagComment;
+ static const char *HTMLEndTagComment;
+ static const char *UnknownComment;
+ static const char *HTMLDoc;
+ static const char *MainContent;
+};
+
+} // namespace doc
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_HTMLTEMPLATES_H
Index: clang-tools-extra/clang-doc/HTMLTemplates.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-doc/HTMLTemplates.cpp
@@ -0,0 +1,209 @@
+///===-- HTMLTemplates.cpp - ClangDoc Representation ------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "HTMLTemplates.h"
+
+namespace clang {
+namespace doc {
+
+// Used for NamespaceInfo
+// - Main header (string), use TopLevelInfoHeader template
+// - Description (string), use CommentBlock template or empty string
+// - ChildNamespaces (string), use HeaderDataBlock or empty string
+// - ChildRecords (string), use HeaderDataBlock or empty string
+// - ChildFunctions (string), use HeaderDataBlock or empty string
+// - ChildEnums (string), use HeaderDataBlock or empty string
+const char *HTMLTemplates::NamespaceBlock = "%s%s%s%s%s%s";
+
+// Used for RecordInfo
+// - Main header (string), use TopLevelInfoHeader template
+// - Definition Location (string), use FileDefinition template or empty string
+// - Description (string), use CommentBlock template or empty string
+// - Parents (string), use RecordInheritance template or empty string
+// - Members (string), use HeaderDataBlock template or empty string
+// - ChildRecords (string), use HeaderDataBlock or empty string
+// - ChildFunctions (string), use HeaderDataBlock or empty string
+// - ChildEnums (string), use HeaderDataBlock or empty string
+const char *HTMLTemplates::RecordBlock = "%s%s%s%s%s%s%s%s";
+
+// Used for CommentInfo
+// - CommentInfo content (string), use the concatenation of multiple Comment
+// templates
+const char *HTMLTemplates::CommentBlock = "\n%s
\n";
+
+// Used for FunctionInfo
+// - Main header (string), use FunctionEnumHeader template
+// - Function header (string), use FunctionDefHeader template
+// - Definition Location (string), use FileDefinition template or empty string
+// - Description (string), use CommentBlock template or empty string
+const char *HTMLTemplates::FunctionBlock = "\n%s%s%s%s
\n";
+
+// Used for EnumInfo
+// - Main header (string), use FunctionEnumHeader template
+// - Members (string), use BlockList template or empty string
+// - Definition Location (string), use FileDefinition template or empty string
+// - Description (string), use CommentBlock template or empty string
+const char *HTMLTemplates::EnumBlock = "\n%s%s%s%s
\n";
+
+// Used for the header of a top level Info (namespace or record)
+// - Content of header (string), use RecordInfoName, NamespaceInfoName, or
+// GlobalNamespaceName template
+const char *HTMLTemplates::TopLevelInfoHeader = "%s
\n";
+
+// Used for the title of a RecordInfo
+// - Tag type (string), use any return value of getTagType()
+// - Record name (string), use Name attribute of Info
+const char *HTMLTemplates::RecordInfoName = "%s %s";
+
+// Used for the title of a NamespaceInfo
+// - Namespace name (string), use Name attribute of Info
+const char *HTMLTemplates::NamespaceInfoName = "namespace %s";
+
+// Constant to be used as the title of the global namespace
+const char *HTMLTemplates::GlobalNamespaceName = "Global Namespace";
+
+// Used for a block that contains a header and data
+// - Header (string), use SectionHeader template
+// - Data (string), use BlockList template
+const char *HTMLTemplates::HeaderDataBlock = "%s%s";
+
+// Used for the definition location of an Info
+// - Line number (integer), use LineNumber attribute of a Location object
+// - File name (string), use Filename attribute of a Location object
+const char *HTMLTemplates::FileDefinition = "Defined at line %d of %s
\n";
+
+// Used for the inheritance of a RecordInfo
+// - Parents (string), use return value of genReferenceList()
+const char *HTMLTemplates::RecordInheritance = "Inherits from %s
\n";
+
+// Used for the header of a FunctionInfo or EnumInfo
+// - Content of header (string), use EnumInfoName template if Info is an Enum
+// and Name attribute of Info if it a Function
+const char *HTMLTemplates::FunctionEnumHeader = "%s
\n";
+
+// Used for the title of a EnumInfo
+// - Enum type (string), use "enum class" or "enum"
+// - Enum name (string), use Name attribute of Info
+const char *HTMLTemplates::EnumInfoName = "%s %s";
+
+// Used for the header of a FunctionInfo
+// - Access level (string), use return value of getAccess() with an appended
+// space at the end or an empty string
+// - Return type (string), use .ReturnType.Type.Name of Function
+// - Function name (string), use Name attribute of Info
+// - Parameters (string), use list of parameters that includes type and name
+const char *HTMLTemplates::FunctionDefHeader = "%s%s %s(%s)
\n";
+
+// Used for the header of record's members and child namespaces, records,
+// functions, enums
+// - Content of header (string), use "Members", "Namespaces", "Records",
+// "Functions", or "Enums"
+const char *HTMLTemplates::SectionHeader = "%s
\n";
+
+// Used to generate an unlisted list
+// - Items (string), use concatenation of BlockItem templates
+const char *HTMLTemplates::BlockList = "\n";
+
+// Used to generate a list item
+// - Content (string)
+const char *HTMLTemplates::BlockItem = "%s\n";
+
+// Used for a member of a RecordInfo
+// - Access level (string), use return value of getAccess() with an appended
+// space at the end or an empty string
+// - Member type (string), use .Type.Name of Member
+// - Member name (string), use Name attribute of Member
+const char *HTMLTemplates::RecordMemberContent = "%s%s %s";
+
+// Used for FullComment CommentInfo
+// - Content of comment (string), use concatenated return value of genHTML() for
+// each child of Info
+const char *HTMLTemplates::FullComment = "\n%s
\n";
+
+// Used for ParagraphComment CommentInfo
+// - Content of comment (string), use concatenated return value of genHTML() for
+// each child of Info
+const char *HTMLTemplates::ParagraphComment = "%s
\n";
+
+// Used for BlockCommandComment CommentInfo
+// - Argument (string), use Name attribute of Info
+// - Content of comment (string), use concatenated return value of genHTML() for
+// each child of Info
+const char *HTMLTemplates::BlockCommandComment = "%s %s";
+
+// Used for InlineCommandComment CommentInfo
+// - Argument (string), use Name attribute of Info
+// - Content of comment (string), use Text attribute of Info
+const char *HTMLTemplates::InlineCommandComment = "%s %s";
+
+// Used for ParamCommandComment CommentInfo
+// - Param name (string), use ParamName attribute of Info
+// - Direction (string), use Direction attribute of Info with an appended space
+// at the end or empty string
+// - Content of comment (string), use concatenated return value of genHTML() for
+// each child of Info
+const char *HTMLTemplates::ParamCommandComment =
+ "\n%s%s %s
\n";
+
+// Used for ParamCommandComment CommentInfo
+// - Param name (string), use ParamName attribute of Info
+// - Direction (string), use Direction attribute of Info with an appended space
+// at the end or empty string
+// - Content of comment (string), use concatenated return value of genHTML() for
+// each child of Info
+const char *HTMLTemplates::TParamCommandComment =
+ "\n%s%s %s
\n";
+
+// Used for VerbatimBlockComment CommentInfo
+// - Content of comment (string), use concatenated return value of genHTML() for
+// each child of Info
+const char *HTMLTemplates::VerbatimBlockComment = "\n%s
\n";
+
+// Used for VerbatimBlockLineComment CommentInfo
+// - Content of comment (string), use Text attribute of Info
+const char *HTMLTemplates::VerbatimBlockLineComment = "%s
\n";
+
+// Used for VerbatimBlockLineComment CommentInfo
+// - Content of comment (string), use Text attribute of Info
+const char *HTMLTemplates::VerbatimLineComment = "%s
\n";
+
+// Used for an attribute of an opening HTML tag
+// - Key (string), use an element of the AttrKeys attribute of Info
+// - Value (string), use an element of the AttrValues attribute of Info
+const char *HTMLTemplates::HTMLStartTagAttribute = " \"%s=%s\"";
+
+// Use for HTMLStartTagComment CommentInfo
+// - Name of tag (string), use Name attribute of Info
+// - Attributes of tag (string), use concatenation of HTMLStartTagAttribute
+// templates
+// - CloseTag (string), use ">" or "/>"
+const char *HTMLTemplates::HTMLStartTagComment = "<%s%s%s";
+
+// Use for HTMLEndTagComment CommentInfo
+// - Name of tag (string), use Name attribute of Info
+const char *HTMLTemplates::HTMLEndTagComment = "%s>";
+
+// Use for unexpected kind of CommentInfo
+const char *HTMLTemplates::UnknownComment =
+ "Unknown comment kind: %s.
\n";
+
+// Used for the complete HTML file to be generated.
+// - Page title (string)
+// - Page main content (string)
+const char *HTMLTemplates::HTMLDoc = R"raw(
+
+%s
+%s)raw";
+
+// Used for the main content of the page, the top level Info's documentation.
+// Navbar, footer, index should not be included.
+// - Top level info (string)
+const char *HTMLTemplates::MainContent = "\n%s
\n";
+
+} // namespace doc
+} // namespace clang
Index: clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
===================================================================
--- clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
+++ clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -40,23 +40,25 @@
llvm::raw_string_ostream Actual(Buffer);
auto Err = G->generateDocForInfo(&I, Actual);
assert(!Err);
- std::string Expected = R"raw(namespace Namespace
-
+ std::string Expected = R"raw(
+
+namespace Namespace
+
+
namespace Namespace
Namespaces
-
ChildNamespace
-
+
ChildNamespace
Records
-
ChildStruct
-
+
ChildStruct
Functions
+
OneFunction
-
OneFunction()
-
+
OneFunction()
+
Enums
-
| enum OneEnum |
-
--
-
-
+
+
enum OneEnum
+
+
)raw";
EXPECT_EQ(Expected, Actual.str());
@@ -87,25 +89,29 @@
llvm::raw_string_ostream Actual(Buffer);
auto Err = G->generateDocForInfo(&I, Actual);
assert(!Err);
- std::string Expected = R"raw(class r
-Defined at line 10 of test.cpp
+ std::string Expected = R"raw(
+
+class r
+
+
class r
+
Defined at line 10 of test.cpp
Inherits from F, G
-
Members
-
private int X
-
+
Records
-
ChildStruct
-
+
ChildStruct
Functions
+
OneFunction
-
OneFunction()
-
+
OneFunction()
+
Enums
-
| enum OneEnum |
-
--
-
-
+
+
enum OneEnum
+
+
)raw";
EXPECT_EQ(Expected, Actual.str());
@@ -130,9 +136,16 @@
llvm::raw_string_ostream Actual(Buffer);
auto Err = G->generateDocForInfo(&I, Actual);
assert(!Err);
- std::string Expected = R"raw(f
-void f(int P)
-Defined at line 10 of test.cpp
+ std::string Expected = R"raw(
+
+
+
+
+
f
+
void f(int P)
+
Defined at line 10 of test.cpp
+
+
)raw";
EXPECT_EQ(Expected, Actual.str());
@@ -155,11 +168,18 @@
llvm::raw_string_ostream Actual(Buffer);
auto Err = G->generateDocForInfo(&I, Actual);
assert(!Err);
- std::string Expected = R"raw(| enum class e |
---
-| X |
-
-Defined at line 10 of test.cpp
+ std::string Expected = R"raw(
+
+
+
+
+
enum class e
+
+
Defined at line 10 of test.cpp
+
+
)raw";
EXPECT_EQ(Expected, Actual.str());
@@ -281,22 +301,33 @@
llvm::raw_string_ostream Actual(Buffer);
auto Err = G->generateDocForInfo(&I, Actual);
assert(!Err);
- std::string Expected = R"raw(f
-void f(int I, int J)
-Defined at line 10 of test.cpp
-
- Brief description.
- Extended description that continues onto the next line.
-
-
- Testing.
-
- The description continues.
-I [out]
-
-J
-
-returnvoid
+ std::string Expected = R"raw(
+
+
+
+
+
f
+
void f(int I, int J)
+
Defined at line 10 of test.cpp
+
+
+
Brief description.
+
Extended description that continues onto the next line.
+
+
+
The description continues.
+
+
+
I [out]
is a parameter.
+
+
+
return void
+
+
+
+
)raw";
EXPECT_EQ(Expected, Actual.str());