[clang-tools-extra] r369139 - [clang-doc] Redesign of generated HTML files

Hubert Tong via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 16 16:34:18 PDT 2019


This patch broke our GCC 5.4.0 builder:
```
In file included from
/tmp/worker/LLVM-Master-Ubuntu-Release/llvm/clang-tools-extra/clang-doc/HTMLGenerator.cpp:9:
In file included from
/tmp/worker/LLVM-Master-Ubuntu-Release/llvm/clang-tools-extra/clang-doc/Generators.h:15:
In file included from
/tmp/worker/LLVM-Master-Ubuntu-Release/llvm/clang-tools-extra/clang-doc/Representation.h:17:
In file included from
/tmp/worker/LLVM-Master-Ubuntu-Release/llvm/clang/include/clang/AST/Type.h:20:
In file included from
/tmp/worker/LLVM-Master-Ubuntu-Release/llvm/clang/include/clang/AST/NestedNameSpecifier.h:17:
In file included from
/tmp/worker/LLVM-Master-Ubuntu-Release/llvm/clang/include/clang/Basic/Diagnostic.h:17:
In file included from
/tmp/worker/LLVM-Master-Ubuntu-Release/llvm/clang/include/clang/Basic/DiagnosticIDs.h:17:
In file included from
/tmp/worker/LLVM-Master-Ubuntu-Release/llvm/clang/include/clang/Basic/LLVM.h:21:
In file included from
/tmp/worker/LLVM-Master-Ubuntu-Release/llvm/llvm/include/llvm/Support/Casting.h:20:
In file included from
/usr/lib/gcc/powerpc64le-linux-gnu/5.4.0/../../../../include/c++/5.4.0/memory:63:
In file included from
/usr/lib/gcc/powerpc64le-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/allocator.h:46:
In file included from
/usr/lib/gcc/powerpc64le-linux-gnu/5.4.0/../../../../include/powerpc64le-linux-gnu/c++/5.4.0/bits/c++allocator.h:33:
/usr/lib/gcc/powerpc64le-linux-gnu/5.4.0/../../../../include/c++/5.4.0/ext/new_allocator.h:120:23:
error: no matching constructor for initialization of
'std::pair<llvm::SmallString<16>, llvm::SmallString<16> >'
        { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
                             ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/powerpc64le-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/alloc_traits.h:530:8:
note: in instantiation of function template specialization
'__gnu_cxx::new_allocator<std::pair<llvm::SmallString<16>,
llvm::SmallString<16> > >::construct<std::pair<llvm::SmallString<16>,
llvm::SmallString<16> >, char const (&)[3],
std::__cxx11::basic_string<char> >' requested here
        { __a.construct(__p, std::forward<_Args>(__args)...); }
              ^
/usr/lib/gcc/powerpc64le-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/vector.tcc:96:21:
note: in instantiation of function template specialization
'std::allocator_traits<std::allocator<std::pair<llvm::SmallString<16>,
llvm::SmallString<16> > > >::construct<std::pair<llvm::SmallString<16>,
llvm::SmallString<16> >, char const (&)[3],
std::__cxx11::basic_string<char> >' requested here
            _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
                           ^
/tmp/worker/LLVM-Master-Ubuntu-Release/llvm/clang-tools-extra/clang-doc/HTMLGenerator.cpp:647:26:
note: in instantiation of function template specialization
'std::vector<std::pair<llvm::SmallString<16>, llvm::SmallString<16> >,
std::allocator<std::pair<llvm::SmallString<16>, llvm::SmallString<16> > >
>::emplace_back<char const (&)[3], std::__cxx11::basic_string<char> >'
requested here
  Out.back()->Attributes.emplace_back("id",
                         ^
```

-- HT

On Fri, Aug 16, 2019 at 2:37 PM Diego Astiazaran via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: diegoastiazaran
> Date: Fri Aug 16 11:38:11 2019
> New Revision: 369139
>
> URL: http://llvm.org/viewvc/llvm-project?rev=369139&view=rev
> Log:
> [clang-doc] Redesign of generated HTML files
>
> The new design includes a header (contains the project name), a main
> section, and a footer.
> The main section is divided into three subsections. Left, middle, right.
> The left section contains the general index, the middle contains the info's
> data, and the right contains the index for the info's content.
> The CSS has been updated.
> A flag --project-name is added.
> The Attributes attribute of the TagNode struct is now a vector of pairs
> because these attributes should be rendered in the insertion order.
> The functions (cpp and js) that converts an Index tree structure into HTML
> were slightly modified; the first ul tag created is now a ol tag. The inner
> lists are still ul.
>
> Differential Revision: https://reviews.llvm.org/D66353
>
> Modified:
>     clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp
>     clang-tools-extra/trunk/clang-doc/Representation.cpp
>     clang-tools-extra/trunk/clang-doc/Representation.h
>
> clang-tools-extra/trunk/clang-doc/assets/clang-doc-default-stylesheet.css
>     clang-tools-extra/trunk/clang-doc/assets/index.js
>     clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp
>     clang-tools-extra/trunk/docs/clang-doc.rst
>     clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp
>
> Modified: clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp?rev=369139&r1=369138&r2=369139&view=diff
>
> ==============================================================================
> --- clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp (original)
> +++ clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp Fri Aug 16
> 11:38:11 2019
> @@ -8,6 +8,7 @@
>
>  #include "Generators.h"
>  #include "Representation.h"
> +#include "clang/Basic/Version.h"
>  #include "llvm/ADT/StringExtras.h"
>  #include "llvm/ADT/StringRef.h"
>  #include "llvm/Support/FileSystem.h"
> @@ -29,12 +30,16 @@ public:
>    enum TagType {
>      TAG_A,
>      TAG_DIV,
> +    TAG_FOOTER,
>      TAG_H1,
>      TAG_H2,
>      TAG_H3,
> +    TAG_HEADER,
>      TAG_LI,
>      TAG_LINK,
> +    TAG_MAIN,
>      TAG_META,
> +    TAG_OL,
>      TAG_P,
>      TAG_SCRIPT,
>      TAG_SPAN,
> @@ -84,7 +89,7 @@ struct TagNode : public HTMLNode {
>
>    HTMLTag Tag; // Name of HTML Tag (p, div, h1)
>    std::vector<std::unique_ptr<HTMLNode>> Children; // List of child nodes
> -  llvm::StringMap<llvm::SmallString<16>>
> +  std::vector<std::pair<llvm::SmallString<16>, llvm::SmallString<16>>>
>        Attributes; // List of key-value attributes for tag
>
>    void Render(llvm::raw_ostream &OS, int IndentationLevel) override;
> @@ -112,10 +117,14 @@ bool HTMLTag::IsSelfClosing() const {
>      return true;
>    case HTMLTag::TAG_A:
>    case HTMLTag::TAG_DIV:
> +  case HTMLTag::TAG_FOOTER:
>    case HTMLTag::TAG_H1:
>    case HTMLTag::TAG_H2:
>    case HTMLTag::TAG_H3:
> +  case HTMLTag::TAG_HEADER:
>    case HTMLTag::TAG_LI:
> +  case HTMLTag::TAG_MAIN:
> +  case HTMLTag::TAG_OL:
>    case HTMLTag::TAG_P:
>    case HTMLTag::TAG_SCRIPT:
>    case HTMLTag::TAG_SPAN:
> @@ -132,18 +141,26 @@ llvm::SmallString<16> HTMLTag::ToString(
>      return llvm::SmallString<16>("a");
>    case HTMLTag::TAG_DIV:
>      return llvm::SmallString<16>("div");
> +  case HTMLTag::TAG_FOOTER:
> +    return llvm::SmallString<16>("footer");
>    case HTMLTag::TAG_H1:
>      return llvm::SmallString<16>("h1");
>    case HTMLTag::TAG_H2:
>      return llvm::SmallString<16>("h2");
>    case HTMLTag::TAG_H3:
>      return llvm::SmallString<16>("h3");
> +  case HTMLTag::TAG_HEADER:
> +    return llvm::SmallString<16>("header");
>    case HTMLTag::TAG_LI:
>      return llvm::SmallString<16>("li");
>    case HTMLTag::TAG_LINK:
>      return llvm::SmallString<16>("link");
> +  case HTMLTag::TAG_MAIN:
> +    return llvm::SmallString<16>("main");
>    case HTMLTag::TAG_META:
>      return llvm::SmallString<16>("meta");
> +  case HTMLTag::TAG_OL:
> +    return llvm::SmallString<16>("ol");
>    case HTMLTag::TAG_P:
>      return llvm::SmallString<16>("p");
>    case HTMLTag::TAG_SCRIPT:
> @@ -174,7 +191,7 @@ void TagNode::Render(llvm::raw_ostream &
>    OS.indent(IndentationLevel * 2);
>    OS << "<" << Tag.ToString();
>    for (const auto &A : Attributes)
> -    OS << " " << A.getKey() << "=\"" << A.getValue() << "\"";
> +    OS << " " << A.first << "=\"" << A.second << "\"";
>    if (Tag.IsSelfClosing()) {
>      OS << "/>";
>      return;
> @@ -255,13 +272,13 @@ genStylesheetsHTML(StringRef InfoPath, c
>    std::vector<std::unique_ptr<TagNode>> Out;
>    for (const auto &FilePath : CDCtx.UserStylesheets) {
>      auto LinkNode = std::make_unique<TagNode>(HTMLTag::TAG_LINK);
> -    LinkNode->Attributes.try_emplace("rel", "stylesheet");
> +    LinkNode->Attributes.emplace_back("rel", "stylesheet");
>      SmallString<128> StylesheetPath = computeRelativePath("", InfoPath);
>      llvm::sys::path::append(StylesheetPath,
>                              llvm::sys::path::filename(FilePath));
>      // Paths in HTML must be in posix-style
>      llvm::sys::path::native(StylesheetPath,
> llvm::sys::path::Style::posix);
> -    LinkNode->Attributes.try_emplace("href", StylesheetPath);
> +    LinkNode->Attributes.emplace_back("href", StylesheetPath);
>      Out.emplace_back(std::move(LinkNode));
>    }
>    return Out;
> @@ -276,7 +293,7 @@ genJsScriptsHTML(StringRef InfoPath, con
>      llvm::sys::path::append(ScriptPath,
> llvm::sys::path::filename(FilePath));
>      // Paths in HTML must be in posix-style
>      llvm::sys::path::native(ScriptPath, llvm::sys::path::Style::posix);
> -    ScriptNode->Attributes.try_emplace("src", ScriptPath);
> +    ScriptNode->Attributes.emplace_back("src", ScriptPath);
>      Out.emplace_back(std::move(ScriptNode));
>    }
>    return Out;
> @@ -284,7 +301,7 @@ genJsScriptsHTML(StringRef InfoPath, con
>
>  static std::unique_ptr<TagNode> genLink(const Twine &Text, const Twine
> &Link) {
>    auto LinkNode = std::make_unique<TagNode>(HTMLTag::TAG_A, Text);
> -  LinkNode->Attributes.try_emplace("href", Link.str());
> +  LinkNode->Attributes.emplace_back("href", Link.str());
>    return LinkNode;
>  }
>
> @@ -333,7 +350,7 @@ genEnumsBlock(const std::vector<EnumInfo
>
>    std::vector<std::unique_ptr<TagNode>> Out;
>    Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H2, "Enums"));
> -  Out.back()->Attributes.try_emplace("id", "Enums");
> +  Out.back()->Attributes.emplace_back("id", "Enums");
>    Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_DIV));
>    auto &DivBody = Out.back();
>    for (const auto &E : Enums) {
> @@ -362,7 +379,7 @@ genFunctionsBlock(const std::vector<Func
>
>    std::vector<std::unique_ptr<TagNode>> Out;
>    Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H2,
> "Functions"));
> -  Out.back()->Attributes.try_emplace("id", "Functions");
> +  Out.back()->Attributes.emplace_back("id", "Functions");
>    Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_DIV));
>    auto &DivBody = Out.back();
>    for (const auto &F : Functions) {
> @@ -381,7 +398,7 @@ genRecordMembersBlock(const llvm::SmallV
>
>    std::vector<std::unique_ptr<TagNode>> Out;
>    Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H2, "Members"));
> -  Out.back()->Attributes.try_emplace("id", "Members");
> +  Out.back()->Attributes.emplace_back("id", "Members");
>    Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_UL));
>    auto &ULBody = Out.back();
>    for (const auto &M : Members) {
> @@ -405,7 +422,7 @@ genReferencesBlock(const std::vector<Ref
>
>    std::vector<std::unique_ptr<TagNode>> Out;
>    Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H2, Title));
> -  Out.back()->Attributes.try_emplace("id", Title);
> +  Out.back()->Attributes.emplace_back("id", Title);
>    Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_UL));
>    auto &ULBody = Out.back();
>    for (const auto &R : References) {
> @@ -431,23 +448,29 @@ writeFileDefinition(const Location &L,
>        std::make_unique<TagNode>(HTMLTag::TAG_A,
> std::to_string(L.LineNumber));
>    // The links to a specific line in the source code use the github /
>    // googlesource notation so it won't work for all hosting pages.
> -  LocNumberNode->Attributes.try_emplace(
> +  LocNumberNode->Attributes.emplace_back(
>        "href", (FileURL + "#" + std::to_string(L.LineNumber)).str());
>    Node->Children.emplace_back(std::move(LocNumberNode));
>    Node->Children.emplace_back(std::make_unique<TextNode>(" of file "));
>    auto LocFileNode = std::make_unique<TagNode>(
>        HTMLTag::TAG_A, llvm::sys::path::filename(FileURL));
> -  LocFileNode->Attributes.try_emplace("href", FileURL);
> +  LocFileNode->Attributes.emplace_back("href", FileURL);
>    Node->Children.emplace_back(std::move(LocFileNode));
>    return Node;
>  }
>
>  static std::vector<std::unique_ptr<TagNode>>
> -genCommonFileNodes(StringRef Title, StringRef InfoPath,
> -                   const ClangDocContext &CDCtx) {
> +genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList);
> +
> +// Generates a list of child nodes for the HTML head tag
> +// It contains a meta node, link nodes to import CSS files, and script
> nodes to
> +// import JS files
> +static std::vector<std::unique_ptr<TagNode>>
> +genFileHeadNodes(StringRef Title, StringRef InfoPath,
> +                 const ClangDocContext &CDCtx) {
>    std::vector<std::unique_ptr<TagNode>> Out;
>    auto MetaNode = std::make_unique<TagNode>(HTMLTag::TAG_META);
> -  MetaNode->Attributes.try_emplace("charset", "utf-8");
> +  MetaNode->Attributes.emplace_back("charset", "utf-8");
>    Out.emplace_back(std::move(MetaNode));
>    Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_TITLE, Title));
>    std::vector<std::unique_ptr<TagNode>> StylesheetsNodes =
> @@ -456,14 +479,87 @@ genCommonFileNodes(StringRef Title, Stri
>    std::vector<std::unique_ptr<TagNode>> JsNodes =
>        genJsScriptsHTML(InfoPath, CDCtx);
>    AppendVector(std::move(JsNodes), Out);
> -  // An empty <div> is generated but the index will be then rendered here
> -  auto IndexNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
> -  IndexNode->Attributes.try_emplace("id", "index");
> -  IndexNode->Attributes.try_emplace("path", InfoPath);
> -  Out.emplace_back(std::move(IndexNode));
>    return Out;
>  }
>
> +// Generates a header HTML node that can be used for any file
> +// It contains the project name
> +static std::unique_ptr<TagNode> genFileHeaderNode(StringRef ProjectName) {
> +  auto HeaderNode = std::make_unique<TagNode>(HTMLTag::TAG_HEADER,
> ProjectName);
> +  HeaderNode->Attributes.emplace_back("id", "project-title");
> +  return HeaderNode;
> +}
> +
> +// Generates a main HTML node that has all the main content of an info
> file
> +// It contains both indexes and the info's documented information
> +// This function should only be used for the info files (not for the file
> that
> +// only has the general index)
> +static std::unique_ptr<TagNode> genInfoFileMainNode(
> +    StringRef InfoPath,
> +    std::vector<std::unique_ptr<TagNode>> &MainContentInnerNodes,
> +    const Index &InfoIndex) {
> +  auto MainNode = std::make_unique<TagNode>(HTMLTag::TAG_MAIN);
> +
> +  auto LeftSidebarNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
> +  LeftSidebarNode->Attributes.emplace_back("id", "sidebar-left");
> +  LeftSidebarNode->Attributes.emplace_back("path", InfoPath);
> +  LeftSidebarNode->Attributes.emplace_back(
> +      "class", "col-xs-6 col-sm-3 col-md-2 sidebar
> sidebar-offcanvas-left");
> +
> +  auto MainContentNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
> +  MainContentNode->Attributes.emplace_back("id", "main-content");
> +  MainContentNode->Attributes.emplace_back(
> +      "class", "col-xs-12 col-sm-9 col-md-8 main-content");
> +  AppendVector(std::move(MainContentInnerNodes),
> MainContentNode->Children);
> +
> +  auto RightSidebarNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
> +  RightSidebarNode->Attributes.emplace_back("id", "sidebar-right");
> +  RightSidebarNode->Attributes.emplace_back(
> +      "class", "col-xs-6 col-sm-6 col-md-2 sidebar
> sidebar-offcanvas-right");
> +  std::vector<std::unique_ptr<TagNode>> InfoIndexHTML =
> +      genHTML(InfoIndex, InfoPath, true);
> +  AppendVector(std::move(InfoIndexHTML), RightSidebarNode->Children);
> +
> +  MainNode->Children.emplace_back(std::move(LeftSidebarNode));
> +  MainNode->Children.emplace_back(std::move(MainContentNode));
> +  MainNode->Children.emplace_back(std::move(RightSidebarNode));
> +
> +  return MainNode;
> +}
> +
> +// Generates a footer HTML node that can be used for any file
> +// It contains clang-doc's version
> +static std::unique_ptr<TagNode> genFileFooterNode() {
> +  auto FooterNode = std::make_unique<TagNode>(HTMLTag::TAG_FOOTER);
> +  auto SpanNode = std::make_unique<TagNode>(
> +      HTMLTag::TAG_SPAN, clang::getClangToolFullVersion("clang-doc"));
> +  SpanNode->Attributes.emplace_back("class", "no-break");
> +  FooterNode->Children.emplace_back(std::move(SpanNode));
> +  return FooterNode;
> +}
> +
> +// Generates a complete HTMLFile for an Info
> +static HTMLFile
> +genInfoFile(StringRef Title, StringRef InfoPath,
> +            std::vector<std::unique_ptr<TagNode>> &MainContentNodes,
> +            const Index &InfoIndex, const ClangDocContext &CDCtx) {
> +  HTMLFile F;
> +
> +  std::vector<std::unique_ptr<TagNode>> HeadNodes =
> +      genFileHeadNodes(Title, InfoPath, CDCtx);
> +  std::unique_ptr<TagNode> HeaderNode =
> genFileHeaderNode(CDCtx.ProjectName);
> +  std::unique_ptr<TagNode> MainNode =
> +      genInfoFileMainNode(InfoPath, MainContentNodes, InfoIndex);
> +  std::unique_ptr<TagNode> FooterNode = genFileFooterNode();
> +
> +  AppendVector(std::move(HeadNodes), F.Children);
> +  F.Children.emplace_back(std::move(HeaderNode));
> +  F.Children.emplace_back(std::move(MainNode));
> +  F.Children.emplace_back(std::move(FooterNode));
> +
> +  return F;
> +}
> +
>  template <typename T,
>            typename = std::enable_if<std::is_base_of<T, Info>::value>>
>  static Index genInfoIndexItem(const std::vector<T> &Infos, StringRef
> Title) {
> @@ -474,8 +570,8 @@ static Index genInfoIndexItem(const std:
>    return Idx;
>  }
>
> -static std::vector<std::unique_ptr<TagNode>> genHTML(const Index &Index,
> -                                                     StringRef InfoPath) {
> +static std::vector<std::unique_ptr<TagNode>>
> +genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) {
>    std::vector<std::unique_ptr<TagNode>> Out;
>    if (!Index.Name.empty()) {
>      Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_SPAN));
> @@ -488,11 +584,13 @@ static std::vector<std::unique_ptr<TagNo
>    }
>    if (Index.Children.empty())
>      return Out;
> -  Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_UL));
> +  // Only the outermost list should use ol, the others should use ul
> +  HTMLTag ListHTMLTag = IsOutermostList ? HTMLTag::TAG_OL :
> HTMLTag::TAG_UL;
> +  Out.emplace_back(std::make_unique<TagNode>(ListHTMLTag));
>    const auto &UlBody = Out.back();
>    for (const auto &C : Index.Children) {
>      auto LiBody = std::make_unique<TagNode>(HTMLTag::TAG_LI);
> -    std::vector<std::unique_ptr<TagNode>> Nodes = genHTML(C, InfoPath);
> +    std::vector<std::unique_ptr<TagNode>> Nodes = genHTML(C, InfoPath,
> false);
>      AppendVector(std::move(Nodes), LiBody->Children);
>      UlBody->Children.emplace_back(std::move(LiBody));
>    }
> @@ -546,8 +644,8 @@ genHTML(const EnumInfo &I, const ClangDo
>
>    Out.emplace_back(
>        std::make_unique<TagNode>(HTMLTag::TAG_H3, EnumType + I.Name));
> -  Out.back()->Attributes.try_emplace("id",
> -
>  llvm::toHex(llvm::toStringRef(I.USR)));
> +  Out.back()->Attributes.emplace_back("id",
> +
> llvm::toHex(llvm::toStringRef(I.USR)));
>
>    std::unique_ptr<TagNode> Node = genEnumMembersBlock(I.Members);
>    if (Node)
> @@ -575,8 +673,8 @@ genHTML(const FunctionInfo &I, const Cla
>    Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_H3, I.Name));
>    // USR is used as id for functions instead of name to disambiguate
> function
>    // overloads.
> -  Out.back()->Attributes.try_emplace("id",
> -
>  llvm::toHex(llvm::toStringRef(I.USR)));
> +  Out.back()->Attributes.emplace_back("id",
> +
> llvm::toHex(llvm::toStringRef(I.USR)));
>
>    Out.emplace_back(std::make_unique<TagNode>(HTMLTag::TAG_P));
>    auto &FunctionHeader = Out.back();
> @@ -738,48 +836,32 @@ const char *HTMLGenerator::Format = "htm
>
>  llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream
> &OS,
>                                                const ClangDocContext
> &CDCtx) {
> -  HTMLFile F;
>    std::string InfoTitle;
> -  auto MainContentNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
> +  std::vector<std::unique_ptr<TagNode>> MainContentNodes;
>    Index InfoIndex;
>    switch (I->IT) {
> -  case InfoType::IT_namespace: {
> -    std::vector<std::unique_ptr<TagNode>> Nodes =
> -        genHTML(*static_cast<clang::doc::NamespaceInfo *>(I), InfoIndex,
> CDCtx,
> -                InfoTitle);
> -    AppendVector(std::move(Nodes), MainContentNode->Children);
> +  case InfoType::IT_namespace:
> +    MainContentNodes = genHTML(*static_cast<clang::doc::NamespaceInfo
> *>(I),
> +                               InfoIndex, CDCtx, InfoTitle);
>      break;
> -  }
> -  case InfoType::IT_record: {
> -    std::vector<std::unique_ptr<TagNode>> Nodes = genHTML(
> -        *static_cast<clang::doc::RecordInfo *>(I), InfoIndex, CDCtx,
> InfoTitle);
> -    AppendVector(std::move(Nodes), MainContentNode->Children);
> +  case InfoType::IT_record:
> +    MainContentNodes = genHTML(*static_cast<clang::doc::RecordInfo *>(I),
> +                               InfoIndex, CDCtx, InfoTitle);
>      break;
> -  }
> -  case InfoType::IT_enum: {
> -    std::vector<std::unique_ptr<TagNode>> Nodes =
> -        genHTML(*static_cast<clang::doc::EnumInfo *>(I), CDCtx);
> -    AppendVector(std::move(Nodes), MainContentNode->Children);
> +  case InfoType::IT_enum:
> +    MainContentNodes = genHTML(*static_cast<clang::doc::EnumInfo *>(I),
> CDCtx);
>      break;
> -  }
> -  case InfoType::IT_function: {
> -    std::vector<std::unique_ptr<TagNode>> Nodes =
> +  case InfoType::IT_function:
> +    MainContentNodes =
>          genHTML(*static_cast<clang::doc::FunctionInfo *>(I), CDCtx, "");
> -    AppendVector(std::move(Nodes), MainContentNode->Children);
>      break;
> -  }
>    case InfoType::IT_default:
>      return llvm::make_error<llvm::StringError>("Unexpected info type.\n",
>
> llvm::inconvertibleErrorCode());
>    }
>
> -  std::vector<std::unique_ptr<TagNode>> BasicNodes =
> -      genCommonFileNodes(InfoTitle, I->Path, CDCtx);
> -  AppendVector(std::move(BasicNodes), F.Children);
> -  std::vector<std::unique_ptr<TagNode>> InfoIndexHTML =
> -      genHTML(InfoIndex, I->Path);
> -  AppendVector(std::move(InfoIndexHTML), F.Children);
> -  F.Children.emplace_back(std::move(MainContentNode));
> +  HTMLFile F =
> +      genInfoFile(InfoTitle, I->Path, MainContentNodes, InfoIndex, CDCtx);
>    F.Render(OS);
>
>    return llvm::Error::success();
> @@ -832,6 +914,24 @@ static bool SerializeIndex(ClangDocConte
>    return true;
>  }
>
> +// Generates a main HTML node that has the main content of the file that
> shows
> +// only the general index
> +// It contains the general index with links to all the generated files
> +static std::unique_ptr<TagNode> genIndexFileMainNode() {
> +  auto MainNode = std::make_unique<TagNode>(HTMLTag::TAG_MAIN);
> +
> +  auto LeftSidebarNode = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
> +  LeftSidebarNode->Attributes.emplace_back("id", "sidebar-left");
> +  LeftSidebarNode->Attributes.emplace_back("path", "");
> +  LeftSidebarNode->Attributes.emplace_back(
> +      "class", "col-xs-6 col-sm-3 col-md-2 sidebar
> sidebar-offcanvas-left");
> +  LeftSidebarNode->Attributes.emplace_back("style", "flex: 0 100%;");
> +
> +  MainNode->Children.emplace_back(std::move(LeftSidebarNode));
> +
> +  return MainNode;
> +}
> +
>  static bool GenIndex(const ClangDocContext &CDCtx) {
>    std::error_code FileErr, OK;
>    llvm::SmallString<128> IndexPath;
> @@ -842,11 +942,22 @@ static bool GenIndex(const ClangDocConte
>      llvm::errs() << "Error creating main index: " << FileErr.message() <<
> "\n";
>      return false;
>    }
> +
>    HTMLFile F;
> -  std::vector<std::unique_ptr<TagNode>> BasicNodes =
> -      genCommonFileNodes("Index", "", CDCtx);
> -  AppendVector(std::move(BasicNodes), F.Children);
> +
> +  std::vector<std::unique_ptr<TagNode>> HeadNodes =
> +      genFileHeadNodes("Index", "", CDCtx);
> +  std::unique_ptr<TagNode> HeaderNode =
> genFileHeaderNode(CDCtx.ProjectName);
> +  std::unique_ptr<TagNode> MainNode = genIndexFileMainNode();
> +  std::unique_ptr<TagNode> FooterNode = genFileFooterNode();
> +
> +  AppendVector(std::move(HeadNodes), F.Children);
> +  F.Children.emplace_back(std::move(HeaderNode));
> +  F.Children.emplace_back(std::move(MainNode));
> +  F.Children.emplace_back(std::move(FooterNode));
> +
>    F.Render(IndexOS);
> +
>    return true;
>  }
>
>
> Modified: clang-tools-extra/trunk/clang-doc/Representation.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/Representation.cpp?rev=369139&r1=369138&r2=369139&view=diff
>
> ==============================================================================
> --- clang-tools-extra/trunk/clang-doc/Representation.cpp (original)
> +++ clang-tools-extra/trunk/clang-doc/Representation.cpp Fri Aug 16
> 11:38:11 2019
> @@ -274,12 +274,14 @@ void Index::sort() {
>  }
>
>  ClangDocContext::ClangDocContext(tooling::ExecutionContext *ECtx,
> -                                 bool PublicOnly, StringRef OutDirectory,
> -                                 StringRef SourceRoot, StringRef
> RepositoryUrl,
> +                                 StringRef ProjectName, bool PublicOnly,
> +                                 StringRef OutDirectory, StringRef
> SourceRoot,
> +                                 StringRef RepositoryUrl,
>                                   std::vector<std::string> UserStylesheets,
>                                   std::vector<std::string> JsScripts)
> -    : ECtx(ECtx), PublicOnly(PublicOnly), OutDirectory(OutDirectory),
> -      UserStylesheets(UserStylesheets), JsScripts(JsScripts) {
> +    : ECtx(ECtx), ProjectName(ProjectName), PublicOnly(PublicOnly),
> +      OutDirectory(OutDirectory), UserStylesheets(UserStylesheets),
> +      JsScripts(JsScripts) {
>    llvm::SmallString<128> SourceRootDir(SourceRoot);
>    if (SourceRoot.empty())
>      // If no SourceRoot was provided the current path is used as the
> default
>
> Modified: clang-tools-extra/trunk/clang-doc/Representation.h
> URL:
> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/Representation.h?rev=369139&r1=369138&r2=369139&view=diff
>
> ==============================================================================
> --- clang-tools-extra/trunk/clang-doc/Representation.h (original)
> +++ clang-tools-extra/trunk/clang-doc/Representation.h Fri Aug 16 11:38:11
> 2019
> @@ -413,12 +413,13 @@ mergeInfos(std::vector<std::unique_ptr<I
>
>  struct ClangDocContext {
>    ClangDocContext() = default;
> -  ClangDocContext(tooling::ExecutionContext *ECtx, bool PublicOnly,
> -                  StringRef OutDirectory, StringRef SourceRoot,
> +  ClangDocContext(tooling::ExecutionContext *ECtx, StringRef ProjectName,
> +                  bool PublicOnly, StringRef OutDirectory, StringRef
> SourceRoot,
>                    StringRef RepositoryUrl,
>                    std::vector<std::string> UserStylesheets,
>                    std::vector<std::string> JsScripts);
>    tooling::ExecutionContext *ECtx;
> +  std::string ProjectName; // Name of project clang-doc is documenting.
>    bool PublicOnly; // Indicates if only public declarations are
> documented.
>    std::string OutDirectory; // Directory for outputting generated files.
>    std::string SourceRoot;   // Directory where processed files are
> stored. Links
>
> Modified:
> clang-tools-extra/trunk/clang-doc/assets/clang-doc-default-stylesheet.css
> URL:
> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/assets/clang-doc-default-stylesheet.css?rev=369139&r1=369138&r2=369139&view=diff
>
> ==============================================================================
> ---
> clang-tools-extra/trunk/clang-doc/assets/clang-doc-default-stylesheet.css
> (original)
> +++
> clang-tools-extra/trunk/clang-doc/assets/clang-doc-default-stylesheet.css
> Fri Aug 16 11:38:11 2019
> @@ -1,205 +1,969 @@
> -body,div {
> +.dark-primary-color    { background: #1976D2; }
> +.default-primary-color { background: #2196F3; }
> +.light-primary-color   { background: #BBDEFB; }
> +.text-primary-color    { color: #FFFFFF; }
> +.accent-color          { background: #00BCD4; }
> +.primary-text-color    { color: #212121; }
> +.secondary-text-color  { color: #727272; }
> +.divider-color         { border-color: #B6B6B6; }
> +
> +/* for layout */
> +html,
> +body {
>    margin: 0;
>    padding: 0;
> +  height: 100%;
> +  width: 100%;
> +  overflow: hidden;
> +  box-sizing: border-box;
>  }
>
> -body[no-overflow] {
> -  overflow: hidden;
> +*, *:before, *:after {
> +  box-sizing: inherit;
>  }
>
> -li>p:first-child {
> -  margin-top: 0;
> +body {
> +  display: flex;
> +  flex-direction: column;
> +  min-height: 100vh;
> +}
> +
> +header {
> +  flex: 0 0 50px;
> +  display: flex;
> +  flex-direction: row;
> +  align-items: center;
> +  padding-left: 30px;
>  }
>
> -li>p:last-child {
> -  margin-bottom: 0;
> +header ol {
> +  list-style: none;
> +  margin: 0;
> +  padding: 0;
>  }
>
> -html {
> -  -webkit-box-sizing: border-box;
> -  box-sizing: border-box;
> +header ol li {
> +  display: inline;
>  }
>
> -*,*::before,*::after {
> -  -webkit-box-sizing: inherit;
> -  box-sizing: inherit;
> +header form {
> +  display: flex;
> +  flex: 1;
> +  justify-content: flex-end;
> +  padding-right: 30px;
>  }
>
> -body,html {
> -  color: #202124;
> -  font: 400 16px/24px Roboto,sans-serif;
> -  -moz-osx-font-smoothing: grayscale;
> -  -webkit-font-smoothing: antialiased;
> -  height: 100%;
> -  margin: 36px;
> -  -webkit-text-size-adjust: 100%;
> -  -moz-text-size-adjust: 100%;
> -  -ms-text-size-adjust: 100%;
> -  text-size-adjust: 100%;
> +header#header-search-sidebar {
> +  height: 50px;
> +  margin-bottom: 25px;
>  }
>
> -body[devsite-framebox] {
> -  overflow: hidden;
> +footer {
> +  flex: 0 0 16px;
> +  text-align: center;
> +  padding: 16px 20px;
> +}
> +
> +main {
> +  flex: 1;
> +  display: flex;
> +  flex-direction: row;
>    padding: 20px;
> +  min-height: 0;
>  }
>
> -body[sitemask--active] {
> -  overflow: hidden;
> +.sidebar-offcanvas-left {
> +  flex: 0 1 230px;
> +  overflow-y: scroll;
> +  padding: 20px 0 15px 30px;
> +  margin: 5px 20px 0 0;
> +  visibility: visible; /* shown by Javascript after scroll position
> restore */
>  }
>
> -p {
> -  margin: 16px 0;
> +::-webkit-scrollbar-button{ display: none; height: 13px; border-radius:
> 0px; background-color: #AAA; }
> +::-webkit-scrollbar-button:hover{ background-color: #AAA; }
> +::-webkit-scrollbar-thumb{ background-color: #CCC; }
> +::-webkit-scrollbar-thumb:hover{ background-color: #CCC; }
> +::-webkit-scrollbar{ width: 4px; }
> +/* ::-webkit-overflow-scrolling: touch; */
> +
> +.main-content::-webkit-scrollbar{ width: 8px; }
> +
> +.main-content {
> +  flex: 1;
> +  overflow-y: scroll;
> +  padding: 10px 20px 0 20px;
> +  visibility: visible; /* shown by Javascript after scroll position
> restore */
> +}
> +
> +.sidebar-offcanvas-right {
> +  flex: 0 1 12em;
> +  overflow-y: scroll;
> +  padding: 20px 15px 15px 15px;
> +  margin-top: 5px;
> +  margin-right: 20px;
> +  visibility: visible; /* shown by Javascript after scroll position
> restore */
> +}
> +/* end for layout */
> +
> +body {
> +  -webkit-text-size-adjust: 100%;
> +  overflow-x: hidden;
> +  font-family: Roboto, sans-serif;
> +  font-size: 16px;
> +  line-height: 1.42857143;
> +  color: #111111;
> +  background-color: #fff;
> +}
> +
> +/* some of this is to reset bootstrap */
> +nav.navbar {
> +  background-color: inherit;
> +  min-height: 50px;
> +  border: 0;
> +}
> +
> + at media (max-width: 768px) {
> +  .hidden-xs {
> +    display: none !important;
> +  }
> +}
> +
> + at media (min-width: 769px) {
> +  .hidden-l {
> +    display: none !important;
> +  }
> +}
> +
> +nav.navbar .row {
> +  padding-top: 8px;
> +}
> +
> +nav .container {
> +  white-space: nowrap;
> +}
> +
> +header {
> +  background-color: #eeeeee;
> +  box-shadow: 0 3px 5px rgba(0,0,0,0.1);
> +}
> +
> +header#project-title {
> +  background-color: #fff;
> +  font-size: 200%;
> +  padding-top: 0.25em;
> +  padding-bottom: 0.25em;
> +  /* padding: 0em; */
> +}
> +
> +header.header-fixed nav.navbar-fixed-top {
> +  box-shadow: 0 3px 5px rgba(0,0,0,0.1);
> +}
> +
> +header.container-fluid {
>    padding: 0;
>  }
>
> -:link,:visited {
> -  color: #039be5;
> -  outline: 0;
> +header .masthead {
> +  padding-top: 64px;
> +}
> +
> +header .contents {
> +  padding: 0;
> +}
> +
> + at media screen and (max-width:768px) {
> +  header .contents {
> +    padding-left: 15px;
> +    padding-right: 15px;
> +  }
> +}
> +
> +a {
>    text-decoration: none;
>  }
>
> -ul {
> +.body {
> +  margin-top: 90px;
> +}
> +
> +section {
> +  margin-bottom: 36px;
> +}
> +
> +dl {
>    margin: 0;
> -  padding-left: 40px;
>  }
>
> -ul {
> -  list-style: disc outside;
> +h1,
> +h2,
> +h3,
> +h4,
> +h5,
> +h6 {
> +  font-family: Roboto, sans-serif;
> +  font-weight: 400;
> +  margin-top: 1.5em;
> +  color: #111111;
>  }
>
> -li,li p {
> -  margin: 12px 0;
> -  padding: 0;
> +h1.title {
> +  overflow: hidden;
> +  text-overflow: ellipsis;
>  }
>
> -*[visually-hidden] {
> -  opacity: 0 !important;
> -  pointer-events: none !important;
> -  visibility: hidden !important;
> +h1 {
> +  font-size: 37px;
> +  margin-top: 0;
> +  margin-bottom: 0.67em;
>  }
>
> -*[hidden] {
> -  display: none !important;
> +h2 {
> +  font-size: 28px;
>  }
>
> -[render-hidden] {
> -  display: inline !important;
> -  position: absolute !important;
> -  visibility: hidden !important;
> +h5 {
> +  font-size: 16px;
>  }
>
> -*[no-scroll] {
> -  overflow: hidden;
> +.subtitle {
> +  font-size: 17px;
> +  min-height: 1.4em;
> +}
> +
> +.title-description .subtitle {
> +  white-space: nowrap;
> +  overflow-x: hidden;
> +  text-overflow: ellipsis;
> +}
> +
> +p {
> +  margin-bottom: 1em;
> +  margin-top: 0;
> +}
> +
> +a {
> +  color: #0175C2;
> +}
> +
> +a:hover {
> +  color: #13B9FD;
> +}
> +
> +pre.prettyprint {
> +  font-family: 'Source Code Pro', Menlo, monospace;
> +  color: black;
> +  border-radius: 0;
> +  font-size: 15px;
> +  word-wrap: normal;
> +  line-height: 1.4;
> +  border: 0;
> +  margin: 16px 0 16px 0;
> +  padding: 8px;
> +}
> +
> +pre code {
> +  white-space: pre;
> +  word-wrap: initial;
> +  font-size: 100%
> +}
> +
> +.fixed {
> +  white-space: pre;
> +}
> +
> +pre {
> +  border: 1px solid #ddd;
> +  background-color: #eee;
> +  font-size: 14px;
> +}
> +
> +code {
> +  font-family: 'Source Code Pro', Menlo, monospace;
> +  /* overriding bootstrap */
> +  color: inherit;
> +  padding: 0.2em 0.4em;
> +  font-size: 85%;
> +  background-color: rgba(27,31,35,0.05);
> +  border-radius: 3px;
>  }
>
> - at supports (display: flex) {
> -  body[ready] .devsite-wrapper {
> -    display: -webkit-box;
> -    display: -ms-flexbox;
> -    display: flex;
> -    -webkit-box-orient: vertical;
> -    -webkit-box-direction: normal;
> -    -ms-flex-direction: column;
> -    flex-direction: column;
> + at media(max-width: 768px) {
> +  nav .container {
> +    width: 100%
> +  }
> +
> +  h1 {
> +    font-size: 24px;
> +  }
> +
> +  pre {
> +    margin: 16px 0;
>    }
>  }
>
> - at media screen and (max-width: 840px) {
> -  body[devsite-book-nav--open] {
> -    overflow: hidden;
> + at media (min-width: 768px) {
> +  ul.subnav li {
> +    font-size: 17px;
>    }
>  }
>
> -h1,h2,h3,h4,h5,h6 {
> -  overflow: hidden;
> -  padding: 0;
> +header h1 {
> +  font-weight: 400;
> +  margin-bottom: 16px;
> +}
> +
> +header a,
> +header p,
> +header li {
> +  color: #111111;
> +}
> +
> +header a:hover {
> +  color: #0175C2;
> +}
> +
> +header h1 .kind {
> +  color: #555;
> +}
> +
> +dt {
> +  font-weight: normal;
> +}
> +
> +dd {
> +  color: #212121;
> +  margin-bottom: 1em;
> +  margin-left: 0;
> +}
> +
> +dd.callable, dd.constant, dd.property {
> +  margin-bottom: 24px;
> +}
> +
> +dd p {
> +  overflow-x: hidden;
>    text-overflow: ellipsis;
> +  margin-bottom: 0;
>  }
>
> -h1 {
> -  color: #80868b;
> -  font: 300 34px/40px Roboto,sans-serif;
> -  letter-spacing: -0.01em;
> -  margin: 40px 0 20px;
> +/* indents wrapped lines */
> +section.summary dt {
> +  margin-left: 24px;
> +  text-indent: -24px;
>  }
>
> -[layout=docs] h2 {
> -  border-bottom: 1px solid #e8eaed;
> -  padding-bottom: 3px;
> +.dl-horizontal dd {
> +  margin-left: initial;
>  }
>
> -h2 {
> -  font: 300 24px/32px Roboto,sans-serif;
> -  letter-spacing: -0.01em;
> -  margin: 40px 0 20px;
> +dl.dl-horizontal dt {
> +  font-style: normal;
> +  text-align: left;
> +  color: #727272;
> +  margin-right: 20px;
> +  width: initial;
>  }
>
> -h3 {
> -  font: 400 20px/32px Roboto,sans-serif;
> -  margin: 32px 0 16px;
> +dt .name {
> +  font-weight: 500;
>  }
>
> -h4,h5,h6 {
> -  margin: 32px 0 16px;
> +dl dt.callable .name {
> +  float: none;
> +  width: auto;
>  }
>
> -h4 {
> -  font: 500 16px/24px Roboto,sans-serif;
> +.parameter {
> +  white-space: nowrap;
>  }
>
> -h5 {
> -  font: 700 14px/24px Roboto,sans-serif;
> +.type-parameter {
> +  white-space: nowrap;
>  }
>
> -h6 {
> -  font: 500 14px/24px Roboto,sans-serif;
> +.multi-line-signature .type-parameter .parameter {
> +  margin-left: 0px;
> +  display: unset;
>  }
>
> -h1+h1,h1+h2,h1+h3,h1+h4,h1+h5,h1+h6,h2+h1,h2+h2,h2+h3,h2+h4,h2+h5,h2+h6,h3+h1,h3+h2,h3+h3,h3+h4,h3+h5,h3+h6,h4+h1,h4+h2,h4+h3,h4+h4,h4+h5,h4+h6,h5+h1,h5+h2,h5+h3,h5+h4,h5+h5,h5+h6,h6+h1,h6+h2,h6+h3,h6+h4,h6+h5,h6+h6
> {
> -  margin-top: 0;
> +.signature {
> +  color: #727272;
>  }
>
> - at media screen and (max-width: 600px) {
> -  h1 {
> -    font: 300 24px/32px Roboto,sans-serif;
> +.signature a {
> +  /* 50% mix of default-primary-color and primary-text-color. */
> +  color: #4674a2;
> +}
> +
> +.optional {
> +  font-style: italic;
> +}
> +
> +.undocumented {
> +  font-style: italic;
> +}
> +
> +.is-const {
> +  font-style: italic;
> +}
> +
> +.deprecated {
> +  text-decoration: line-through;
> +}
> +
> +.category.linked {
> +  font-weight: bold;
> +  opacity: 1;
> +}
> +
> +/* Colors for category based on categoryOrder in dartdoc_options.config.
> */
> +.category.cp-0 {
> +  background-color: #54b7c4
> +}
> +
> +.category.cp-1 {
> +  background-color: #54c47f
> +}
> +
> +.category.cp-2 {
> +  background-color: #c4c254
> +}
> +
> +.category.cp-3 {
> +  background-color: #c49f54
> +}
> +
> +.category.cp-4 {
> +  background-color: #c45465
> +}
> +
> +.category.cp-5 {
> +  background-color: #c454c4
> +}
> +
> +.category a {
> +  color: white;
> +}
> +
> +.category {
> +  padding: 2px 4px;
> +  font-size: 12px;
> +  border-radius: 4px;
> +  background-color: #999;
> +  text-transform: uppercase;
> +  color: white;
> +  opacity: .5;
> +}
> +
> +h1 .category {
> +  vertical-align: middle;
> +}
> +
> +.source-link {
> +  padding: 18px 4px;
> +  vertical-align: middle;
> +}
> +
> +.source-link .material-icons {
> +  font-size: 18px;
> +}
> +
> + at media (max-width: 768px) {
> +  .source-link {
> +    padding: 7px 2px;
> +    font-size: 10px;
>    }
>  }
>
> -[scrollbars]::-webkit-scrollbar {
> -  height: 8px;
> -  width: 8px;
> +#external-links {
> +  float: right;
>  }
>
> -[scrollbars]::-webkit-scrollbar-thumb {
> -  background: rgba(128,134,139,.26);
> -  border-radius: 8px;
> +.btn-group {
> +  position: relative;
> +  display: inline-flex;
> +  vertical-align: middle;
>  }
>
> -[no-horizontal-scrollbars]::-webkit-scrollbar {
> -  height: 0;
> -  width: 0;
> +p.firstline {
> +  font-weight: bold;
>  }
>
> -[scrollbars]::-webkit-scrollbar-corner {
> -  background: 0;
> +footer {
> +  color: #fff;
> +  background-color: #111111;
> +  width: 100%;
>  }
>
> -[background] h2 {
> +footer p {
> +  margin: 0;
> +}
> +
> +footer .no-break {
> +  white-space: nowrap;
> +}
> +
> +footer .container,
> +footer .container-fluid {
> +  padding-left: 0;
> +  padding-right: 0;
> +}
> +
> +footer a, footer a:hover {
>    color: #fff;
>  }
>
> - at media print {
> -  body,  html,  :link,  :visited,  h1,  h2,  h3,  h4,  h5,  h6 {
> -    color: #000 !important;
> -    padding-left: 0 !important;
> -    padding-right: 0 !important;
> +.markdown.desc {
> +  max-width: 700px;
> +}
> +
> +.markdown h1 {
> +  font-size: 24px;
> +  margin-bottom: 8px;
> +}
> +
> +.markdown h2 {
> +  font-size: 20px;
> +  margin-top: 24px;
> +  margin-bottom: 8px;
> +}
> +
> +.markdown h3 {
> +  font-size: 18px;
> +  margin-bottom: 8px;
> +}
> +
> +.markdown h4 {
> +  font-size: 16px;
> +  margin-bottom: 0;
> +}
> +
> +.markdown li p {
> +  margin: 0;
> +}
> +
> +.gt-separated {
> +  list-style: none;
> +  padding: 0;
> +  margin: 0;
> +}
> +
> +.gt-separated li {
> +  display: inline-block;
> +}
> +
> +.gt-separated li:before {
> +  background-image: url("data:image/svg+xml;utf8,<svg xmlns='
> http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16
> 16'><path fill='%23DDDDDD'
> d='M6.7,4L5.7,4.9L8.8,8l-3.1,3.1L6.7,12l4-4L6.7,4z'/></svg>");
> +  background-position: center;
> +  content: "\00a0";
> +  margin: 0 6px 0 4px;
> +  padding: 0 3px 0 0;
> +}
> +
> +.gt-separated.dark li:before {
> +  background-image: url("data:image/svg+xml;utf8,<svg xmlns='
> http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16
> 16'><path fill='%23727272'
> d='M6.7,4L5.7,4.9L8.8,8l-3.1,3.1L6.7,12l4-4L6.7,4z'/></svg>");
> +}
> +
> +.gt-separated li:first-child:before {
> +  background-image: none;
> +  content: "";
> +  margin: 0;
> +}
> +
> +/* The slug line under a declaration for things like "const",
> "read-only", etc. */
> +.features {
> +  font-style: italic;
> +  color: #727272;
> +}
> +
> +.multi-line-signature {
> +  font-size: 17px;
> +  color: #727272;
> +}
> +
> +.multi-line-signature .parameter {
> +  margin-left: 24px;
> +  display: block;
> +}
> +
> +.breadcrumbs {
> +  padding: 0;
> +  margin: 8px 0 8px 0;
> +  white-space: nowrap;
> +  line-height: 1;
> +}
> +
> + at media screen and (min-width: 768px) {
> +  nav ol.breadcrumbs {
> +    float: left;
>    }
> +}
>
> -  :link,  :visited {
> -    text-decoration: underline;
> + at media screen and (max-width: 768px) {
> +  .breadcrumbs {
> +    margin: 0 0 24px 0;
> +    overflow-x: hidden;
>    }
>  }
>
> - at page {
> -  margin: .75in;
> +.self-crumb {
> +  color: #555;
> +}
> +
> +.self-name {
> +  color: #555;
> +  display: none;
>  }
> +
> +.annotation-list {
> +  list-style: none;
> +  padding: 0;
> +  display: inline;
> +}
> +
> +.comma-separated {
> +  list-style: none;
> +  padding: 0;
> +  display: inline;
> +}
> +
> +.comma-separated li {
> +  display: inline;
> +}
> +
> +.comma-separated li:after {
> +  content: ", ";
> +}
> +
> +.comma-separated li:last-child:after {
> +  content: "";
> +}
> +
> +.end-with-period li:last-child:after {
> +  content: ".";
> +}
> +
> +.container > section:first-child {
> +  border: 0;
> +}
> +
> +.constructor-modifier {
> +  font-style: italic;
> +}
> +
> +section.multi-line-signature div.parameters {
> +  margin-left: 24px;
> +}
> +
> +/* subnav styles */
> +
> +ul.subnav {
> +  overflow: auto;
> +  white-space: nowrap;
> +  padding-left: 0;
> +  min-height: 25px;
> +}
> +
> +ul.subnav::-webkit-scrollbar {
> +  display: none;
> +}
> +
> +ul.subnav li {
> +  display: inline-block;
> +  text-transform: uppercase;
> +}
> +
> +ul.subnav li a {
> +  color: #111;
> +}
> +
> +ul.subnav li {
> +  margin-right: 24px;
> +}
> +
> +ul.subnav li:last-of-type {
> +  margin-right: 0;
> +}
> +
> + at media(max-width: 768px) {
> +  ul.subnav li {
> +    margin-right: 16px;
> +  }
> +}
> +
> +/* sidebar styles */
> +
> +.sidebar ol {
> +  list-style: none;
> +  line-height: 22px;
> +  margin-top: 0;
> +  margin-bottom: 0;
> +  padding: 0 0 15px 0;
> +}
> +
> +.sidebar h5 a,
> +.sidebar h5 a:hover {
> +  color: #727272;
> +}
> +
> +.sidebar h5,
> +.sidebar ol li {
> +  text-overflow: ellipsis;
> +  overflow: hidden;
> +  padding: 3px 0;
> +}
> +
> +.sidebar h5 {
> +  color: #727272;
> +  font-size: 18px;
> +  margin: 0 0 25px 0;
> +  padding-top: 0;
> +}
> +
> +.sidebar ol li.section-title {
> +  font-size: 18px;
> +  font-weight: normal;
> +  text-transform: uppercase;
> +  padding-top: 25px;
> +}
> +
> +.sidebar ol li.section-subtitle a {
> +  color: inherit;
> +}
> +
> +.sidebar ol li.section-subtitle {
> +  font-weight: 400;
> +  text-transform: uppercase;
> +}
> +
> +.sidebar ol li.section-subitem {
> +  margin-left: 12px;
> +}
> +
> +.sidebar ol li:first-child {
> +  padding-top: 0;
> +  margin-top: 0;
> +}
> +
> +button {
> +  padding: 0;
> +}
> +
> +#sidenav-left-toggle {
> +  display: none;
> +  vertical-align: text-bottom;
> +  padding: 0;
> +}
> +
> +/* left-nav disappears, and can transition in from the left */
> + at media screen and (max-width:768px) {
> +  #sidenav-left-toggle {
> +    display: inline;
> +    background: no-repeat url("data:image/svg+xml;utf8,<svg xmlns='
> http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24
> 24'><path fill='%23111' d='M3
> 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z'/></svg>");
> +    background-position: center;
> +    width: 24px;
> +    height: 24px;
> +    border: none;
> +    margin-right: 24px;
> +  }
> +
> +  #overlay-under-drawer.active {
> +    opacity: 0.4;
> +    height: 100%;
> +    z-index: 1999;
> +    position: fixed;
> +    top: 0;
> +    left: 0;
> +    right: 0;
> +    bottom: 0;
> +    background-color: black;
> +    display: block;
> +  }
> +
> +  .sidebar-offcanvas-left {
> +    left: -100%;
> +    position: fixed;
> +    -webkit-transition:all .25s ease-out;
> +    -o-transition:all .25s ease-out;
> +    transition:all .25s ease-out;
> +    z-index: 2000;
> +    top: 0;
> +    width: 280px; /* works all the way down to an iphone 4 */
> +    height: 90%;
> +    background-color: white;
> +    overflow-y: scroll; /* TODO: how to hide scroll bars? */
> +    padding: 10px;
> +    margin: 10px 10px;
> +    box-shadow: 5px 5px 5px 5px #444444;
> +    visibility: hidden; /* shown by Javascript after scroll position
> restore */
> +  }
> +
> +  ol#sidebar-nav {
> +    font-size: 18px;
> +    white-space: pre-line;
> +  }
> +
> +  .sidebar-offcanvas-left.active {
> +    left: 0; /* this animates our drawer into the page */
> +  }
> +
> +  .self-name {
> +    display: inline-block;
> +  }
> +}
> +
> +.sidebar-offcanvas-left h5 {
> +  margin-bottom: 10px;
> +}
> +
> +.sidebar-offcanvas-left h5:last-of-type {
> +  border: 0;
> +  margin-bottom: 25px;
> +}
> +
> +/* the right nav disappears out of view when the window shrinks */
> + at media screen and (max-width: 992px) {
> +  .sidebar-offcanvas-right {
> +     display: none;
> +   }
> +}
> +
> +#overlay-under-drawer {
> +  display: none;
> +}
> +
> +/* find-as-you-type search box */
> +
> +/* override bootstrap defaults */
> +.form-control {
> +  border-radius: 0;
> +  border: 0;
> +}
> +
> + at media screen and (max-width: 768px) {
> +  form.search {
> +    display: none;
> +  }
> +}
> +
> +.typeahead,
> +.tt-query,
> +.tt-hint {
> +  width: 200px;
> +  height: 20px;
> +  padding: 2px 7px 1px 7px;
> +  line-height: 20px;
> +  outline: none;
> +}
> +
> +.typeahead {
> +  background-color: #fff;
> +  border-radius: 2px;
> +}
> +
> +.tt-query {
> +  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
> +     -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
> +          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
> +}
> +
> +.tt-hint {
> +  color: #999
> +}
> +
> +.navbar-right .tt-menu {
> +  right:0;
> +  left: inherit !important;
> +  width: 422px;
> +  max-height: 250px;
> +  overflow-y: scroll;
> +}
> +
> +.tt-menu {
> +  font-size: 14px;
> +  margin: 0;
> +  padding: 8px 0;
> +  background-color: #fff;
> +  border: 1px solid #ccc;
> +  border: 1px solid rgba(0, 0, 0, 0.2);
> +  -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
> +     -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
> +          box-shadow: 0 5px 10px rgba(0,0,0,.2);
> +}
> +
> +.tt-suggestion {
> +  padding: 3px 20px;
> +  color: #212121;
> +}
> +
> +.tt-suggestion:hover {
> +  cursor: pointer;
> +  color: #fff;
> +  background-color: #0097cf;
> +}
> +
> +.tt-suggestion:hover .search-from-lib {
> +  color: #ddd;
> +}
> +
> +.tt-suggestion.tt-cursor {
> +  color: #fff;
> +  background-color: #0097cf;
> +}
> +
> +.tt-suggestion.tt-cursor .search-from-lib {
> +  color: #ddd;
> +}
> +
> +.tt-suggestion p {
> +  margin: 0;
> +}
> +
> +.search-from-lib {
> +  font-style: italic;
> +  color: gray;
> +}
> +
> +#search-box {
> +  background-color: #ffffff;
> +}
> +
> +.search-body {
> +  border: 1px solid #7f7f7f;
> +  max-width: 400px;
> +  box-shadow: 3px 3px 5px rgba(0,0,0,0.1);
> +}
> +
> +section#setter {
> +  border-top: 1px solid #ddd;
> +  padding-top: 36px;
> +}
> +
> +li.inherited a {
> +  opacity: 0.65;
> +  font-style: italic;
> +}
> +
> +#instance-methods dt.inherited .name,
> +#instance-properties dt.inherited .name,
> +#operators dt.inherited .name {
> +  font-weight: 300;
> +  font-style: italic;
> +}
> +
> +#instance-methods dt.inherited .signature,
> +#instance-properties dt.inherited .signature,
> +#operators dt.inherited .signature {
> +  font-weight: 300;
> +}
> +
> + at media print {
> +  .subnav, .sidebar {
> +    display:none;
> +  }
> +
> +  a[href]:after {
> +   content:"" !important;
> +  }
> +}
> \ No newline at end of file
>
> Modified: clang-tools-extra/trunk/clang-doc/assets/index.js
> URL:
> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/assets/index.js?rev=369139&r1=369138&r2=369139&view=diff
>
> ==============================================================================
> --- clang-tools-extra/trunk/clang-doc/assets/index.js (original)
> +++ clang-tools-extra/trunk/clang-doc/assets/index.js Fri Aug 16 11:38:11
> 2019
> @@ -39,7 +39,7 @@ function genLink(Ref, CurrentDirectory)
>    return ANode;
>  }
>
> -function genHTMLOfIndex(Index, CurrentDirectory) {
> +function genHTMLOfIndex(Index, CurrentDirectory, IsOutermostList) {
>    // Out will store the HTML elements that Index requires to be generated
>    var Out = [];
>    if (Index.Name) {
> @@ -50,24 +50,26 @@ function genHTMLOfIndex(Index, CurrentDi
>    }
>    if (Index.Children.length == 0)
>      return Out;
> -  var UlNode = document.createElement("ul");
> +  // Only the outermost list should use ol, the others should use ul
> +  var ListNodeName = IsOutermostList ? "ol" : "ul";
> +  var ListNode = document.createElement(ListNodeName);
>    for (Child of Index.Children) {
>      var LiNode = document.createElement("li");
> -    ChildNodes = genHTMLOfIndex(Child, CurrentDirectory);
> +    ChildNodes = genHTMLOfIndex(Child, CurrentDirectory, false);
>      for (Node of ChildNodes)
>        LiNode.appendChild(Node);
> -    UlNode.appendChild(LiNode);
> +    ListNode.appendChild(LiNode);
>    }
> -  Out.push(UlNode);
> +  Out.push(ListNode);
>    return Out;
>  }
>
>  function createIndex(Index) {
>    // Get the DOM element where the index will be created
> -  var IndexDiv = document.getElementById("index");
> +  var IndexDiv = document.getElementById("sidebar-left");
>    // Get the relative path of this file
>    CurrentDirectory = IndexDiv.getAttribute("path");
> -  var IndexNodes = genHTMLOfIndex(Index, CurrentDirectory);
> +  var IndexNodes = genHTMLOfIndex(Index, CurrentDirectory, true);
>    for (Node of IndexNodes)
>      IndexDiv.appendChild(Node);
>  }
>
> Modified: clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp?rev=369139&r1=369138&r2=369139&view=diff
>
> ==============================================================================
> --- clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp (original)
> +++ clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp Fri Aug 16
> 11:38:11 2019
> @@ -52,6 +52,10 @@ using namespace clang;
>  static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
>  static llvm::cl::OptionCategory ClangDocCategory("clang-doc options");
>
> +static llvm::cl::opt<std::string>
> +    ProjectName("project-name", llvm::cl::desc("Name of project."),
> +                llvm::cl::cat(ClangDocCategory));
> +
>  static llvm::cl::opt<bool> IgnoreMappingFailures(
>      "ignore-map-errors",
>      llvm::cl::desc("Continue if files are not mapped correctly."),
> @@ -205,6 +209,7 @@ int main(int argc, const char **argv) {
>
>    clang::doc::ClangDocContext CDCtx = {
>        Exec->get()->getExecutionContext(),
> +      ProjectName,
>        PublicOnly,
>        OutDirectory,
>        SourceRoot,
>
> Modified: clang-tools-extra/trunk/docs/clang-doc.rst
> URL:
> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-doc.rst?rev=369139&r1=369138&r2=369139&view=diff
>
> ==============================================================================
> --- clang-tools-extra/trunk/docs/clang-doc.rst (original)
> +++ clang-tools-extra/trunk/docs/clang-doc.rst Fri Aug 16 11:38:11 2019
> @@ -89,6 +89,7 @@ Options
>      --ignore-map-errors         - Continue if files are not mapped
> correctly.
>      --output=<string>           - Directory for outputting generated
> files.
>      -p=<string>                 - Build path
> +    --project-name=<string>     - Name of project.
>      --public                    - Document only public declarations.
>      --repository=<string>       -
>                                    URL of repository that hosts code.
>
> Modified: clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp?rev=369139&r1=369138&r2=369139&view=diff
>
> ==============================================================================
> --- clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp
> (original)
> +++ clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp Fri
> Aug 16 11:38:11 2019
> @@ -10,11 +10,15 @@
>  #include "Generators.h"
>  #include "Representation.h"
>  #include "Serialize.h"
> +#include "clang/Basic/Version.h"
>  #include "gtest/gtest.h"
>
>  namespace clang {
>  namespace doc {
>
> +static const std::string ClangDocVersion =
> +    clang::getClangToolFullVersion("clang-doc");
> +
>  std::unique_ptr<Generator> getHTMLGenerator() {
>    auto G = doc::findGeneratorByName("html");
>    if (!G)
> @@ -25,7 +29,8 @@ std::unique_ptr<Generator> getHTMLGenera
>  ClangDocContext
>  getClangDocContext(std::vector<std::string> UserStylesheets = {},
>                     StringRef RepositoryUrl = "") {
> -  ClangDocContext CDCtx{{}, {}, {}, {}, RepositoryUrl, UserStylesheets,
> {}};
> +  ClangDocContext CDCtx{
> +      {}, "test-project", {}, {}, {}, RepositoryUrl, UserStylesheets, {}};
>    CDCtx.UserStylesheets.insert(
>        CDCtx.UserStylesheets.begin(),
>        "../share/clang/clang-doc-default-stylesheet.css");
> @@ -61,67 +66,76 @@ TEST(HTMLGeneratorTest, emitNamespaceHTM
>  <link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>
>  <link rel="stylesheet" href="user-provided-stylesheet.css"/>
>  <script src="index.js"></script>
> -<div id="index" path=""></div>
> -<ul>
> -  <li>
> -    <span>
> -      <a href="#Namespaces">Namespaces</a>
> -    </span>
> -  </li>
> -  <li>
> -    <span>
> -      <a href="#Records">Records</a>
> -    </span>
> -  </li>
> -  <li>
> -    <span>
> -      <a href="#Functions">Functions</a>
> -    </span>
> +<header id="project-title">test-project</header>
> +<main>
> +  <div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2
> sidebar sidebar-offcanvas-left"></div>
> +  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
> +    <h1>namespace Namespace</h1>
> +    <h2 id="Namespaces">Namespaces</h2>
>      <ul>
>        <li>
> -        <span>
> -          <a
> href="#0000000000000000000000000000000000000000">OneFunction</a>
> -        </span>
> +        <a href="Namespace/ChildNamespace.html">ChildNamespace</a>
>        </li>
>      </ul>
> -  </li>
> -  <li>
> -    <span>
> -      <a href="#Enums">Enums</a>
> -    </span>
> +    <h2 id="Records">Records</h2>
>      <ul>
>        <li>
> -        <span>
> -          <a href="#0000000000000000000000000000000000000000">OneEnum</a>
> -        </span>
> +        <a href="Namespace/ChildStruct.html">ChildStruct</a>
>        </li>
>      </ul>
> -  </li>
> -</ul>
> -<div>
> -  <h1>namespace Namespace</h1>
> -  <h2 id="Namespaces">Namespaces</h2>
> -  <ul>
> -    <li>
> -      <a href="Namespace/ChildNamespace.html">ChildNamespace</a>
> -    </li>
> -  </ul>
> -  <h2 id="Records">Records</h2>
> -  <ul>
> -    <li>
> -      <a href="Namespace/ChildStruct.html">ChildStruct</a>
> -    </li>
> -  </ul>
> -  <h2 id="Functions">Functions</h2>
> -  <div>
> -    <h3 id="0000000000000000000000000000000000000000">OneFunction</h3>
> -    <p>OneFunction()</p>
> +    <h2 id="Functions">Functions</h2>
> +    <div>
> +      <h3 id="0000000000000000000000000000000000000000">OneFunction</h3>
> +      <p>OneFunction()</p>
> +    </div>
> +    <h2 id="Enums">Enums</h2>
> +    <div>
> +      <h3 id="0000000000000000000000000000000000000000">enum OneEnum</h3>
> +    </div>
>    </div>
> -  <h2 id="Enums">Enums</h2>
> -  <div>
> -    <h3 id="0000000000000000000000000000000000000000">enum OneEnum</h3>
> +  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar
> sidebar-offcanvas-right">
> +    <ol>
> +      <li>
> +        <span>
> +          <a href="#Namespaces">Namespaces</a>
> +        </span>
> +      </li>
> +      <li>
> +        <span>
> +          <a href="#Records">Records</a>
> +        </span>
> +      </li>
> +      <li>
> +        <span>
> +          <a href="#Functions">Functions</a>
> +        </span>
> +        <ul>
> +          <li>
> +            <span>
> +              <a
> href="#0000000000000000000000000000000000000000">OneFunction</a>
> +            </span>
> +          </li>
> +        </ul>
> +      </li>
> +      <li>
> +        <span>
> +          <a href="#Enums">Enums</a>
> +        </span>
> +        <ul>
> +          <li>
> +            <span>
> +              <a
> href="#0000000000000000000000000000000000000000">OneEnum</a>
> +            </span>
> +          </li>
> +        </ul>
> +      </li>
> +    </ol>
>    </div>
> -</div>
> +</main>
> +<footer>
> +  <span class="no-break">)raw" +
> +                         ClangDocVersion + R"raw(</span>
> +</footer>
>  )raw";
>
>    EXPECT_EQ(Expected, Actual.str());
> @@ -162,80 +176,89 @@ TEST(HTMLGeneratorTest, emitRecordHTML)
>  <title>class r</title>
>  <link rel="stylesheet" href="../../../clang-doc-default-stylesheet.css"/>
>  <script src="../../../index.js"></script>
> -<div id="index" path="X/Y/Z"></div>
> -<ul>
> -  <li>
> -    <span>
> -      <a href="#Members">Members</a>
> -    </span>
> -  </li>
> -  <li>
> -    <span>
> -      <a href="#Records">Records</a>
> -    </span>
> -  </li>
> -  <li>
> -    <span>
> -      <a href="#Functions">Functions</a>
> -    </span>
> +<header id="project-title">test-project</header>
> +<main>
> +  <div id="sidebar-left" path="X/Y/Z" class="col-xs-6 col-sm-3 col-md-2
> sidebar sidebar-offcanvas-left"></div>
> +  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
> +    <h1>class r</h1>
> +    <p>
> +      Defined at line
> +      <a href="http://www.repository.com/dir/test.cpp#10">10</a>
> +       of file
> +      <a href="http://www.repository.com/dir/test.cpp">test.cpp</a>
> +    </p>
> +    <p>
> +      Inherits from
> +      <a href="../../../path/to/F.html">F</a>
> +      , G
> +    </p>
> +    <h2 id="Members">Members</h2>
>      <ul>
>        <li>
> -        <span>
> -          <a
> href="#0000000000000000000000000000000000000000">OneFunction</a>
> -        </span>
> +        private
> +        <a href="../int.html">int</a>
> +         X
>        </li>
>      </ul>
> -  </li>
> -  <li>
> -    <span>
> -      <a href="#Enums">Enums</a>
> -    </span>
> +    <h2 id="Records">Records</h2>
>      <ul>
>        <li>
> -        <span>
> -          <a href="#0000000000000000000000000000000000000000">OneEnum</a>
> -        </span>
> +        <a href="r/ChildStruct.html">ChildStruct</a>
>        </li>
>      </ul>
> -  </li>
> -</ul>
> -<div>
> -  <h1>class r</h1>
> -  <p>
> -    Defined at line
> -    <a href="http://www.repository.com/dir/test.cpp#10">10</a>
> -     of file
> -    <a href="http://www.repository.com/dir/test.cpp">test.cpp</a>
> -  </p>
> -  <p>
> -    Inherits from
> -    <a href="../../../path/to/F.html">F</a>
> -    , G
> -  </p>
> -  <h2 id="Members">Members</h2>
> -  <ul>
> -    <li>
> -      private
> -      <a href="../int.html">int</a>
> -       X
> -    </li>
> -  </ul>
> -  <h2 id="Records">Records</h2>
> -  <ul>
> -    <li>
> -      <a href="r/ChildStruct.html">ChildStruct</a>
> -    </li>
> -  </ul>
> -  <h2 id="Functions">Functions</h2>
> -  <div>
> -    <h3 id="0000000000000000000000000000000000000000">OneFunction</h3>
> -    <p>public OneFunction()</p>
> +    <h2 id="Functions">Functions</h2>
> +    <div>
> +      <h3 id="0000000000000000000000000000000000000000">OneFunction</h3>
> +      <p>public OneFunction()</p>
> +    </div>
> +    <h2 id="Enums">Enums</h2>
> +    <div>
> +      <h3 id="0000000000000000000000000000000000000000">enum OneEnum</h3>
> +    </div>
>    </div>
> -  <h2 id="Enums">Enums</h2>
> -  <div>
> -    <h3 id="0000000000000000000000000000000000000000">enum OneEnum</h3>
> +  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar
> sidebar-offcanvas-right">
> +    <ol>
> +      <li>
> +        <span>
> +          <a href="#Members">Members</a>
> +        </span>
> +      </li>
> +      <li>
> +        <span>
> +          <a href="#Records">Records</a>
> +        </span>
> +      </li>
> +      <li>
> +        <span>
> +          <a href="#Functions">Functions</a>
> +        </span>
> +        <ul>
> +          <li>
> +            <span>
> +              <a
> href="#0000000000000000000000000000000000000000">OneFunction</a>
> +            </span>
> +          </li>
> +        </ul>
> +      </li>
> +      <li>
> +        <span>
> +          <a href="#Enums">Enums</a>
> +        </span>
> +        <ul>
> +          <li>
> +            <span>
> +              <a
> href="#0000000000000000000000000000000000000000">OneEnum</a>
> +            </span>
> +          </li>
> +        </ul>
> +      </li>
> +    </ol>
>    </div>
> -</div>
> +</main>
> +<footer>
> +  <span class="no-break">)raw" +
> +                         ClangDocVersion + R"raw(</span>
> +</footer>
>  )raw";
>
>    EXPECT_EQ(Expected, Actual.str());
> @@ -270,17 +293,25 @@ TEST(HTMLGeneratorTest, emitFunctionHTML
>  <title></title>
>  <link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>
>  <script src="index.js"></script>
> -<div id="index" path=""></div>
> -<div>
> -  <h3 id="0000000000000000000000000000000000000000">f</h3>
> -  <p>
> -    <a href="path/to/float.html">float</a>
> -     f(
> -    <a href="path/to/int.html">int</a>
> -     P)
> -  </p>
> -  <p>Defined at line 10 of file dir/test.cpp</p>
> -</div>
> +<header id="project-title">test-project</header>
> +<main>
> +  <div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2
> sidebar sidebar-offcanvas-left"></div>
> +  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
> +    <h3 id="0000000000000000000000000000000000000000">f</h3>
> +    <p>
> +      <a href="path/to/float.html">float</a>
> +       f(
> +      <a href="path/to/int.html">int</a>
> +       P)
> +    </p>
> +    <p>Defined at line 10 of file dir/test.cpp</p>
> +  </div>
> +  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar
> sidebar-offcanvas-right"></div>
> +</main>
> +<footer>
> +  <span class="no-break">)raw" +
> +                         ClangDocVersion + R"raw(</span>
> +</footer>
>  )raw";
>
>    EXPECT_EQ(Expected, Actual.str());
> @@ -309,19 +340,27 @@ TEST(HTMLGeneratorTest, emitEnumHTML) {
>  <title></title>
>  <link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>
>  <script src="index.js"></script>
> -<div id="index" path=""></div>
> -<div>
> -  <h3 id="0000000000000000000000000000000000000000">enum class e</h3>
> -  <ul>
> -    <li>X</li>
> -  </ul>
> -  <p>
> -    Defined at line
> -    <a href="https://www.repository.com/test.cpp#10">10</a>
> -     of file
> -    <a href="https://www.repository.com/test.cpp">test.cpp</a>
> -  </p>
> -</div>
> +<header id="project-title">test-project</header>
> +<main>
> +  <div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2
> sidebar sidebar-offcanvas-left"></div>
> +  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
> +    <h3 id="0000000000000000000000000000000000000000">enum class e</h3>
> +    <ul>
> +      <li>X</li>
> +    </ul>
> +    <p>
> +      Defined at line
> +      <a href="https://www.repository.com/test.cpp#10">10</a>
> +       of file
> +      <a href="https://www.repository.com/test.cpp">test.cpp</a>
> +    </p>
> +  </div>
> +  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar
> sidebar-offcanvas-right"></div>
> +</main>
> +<footer>
> +  <span class="no-break">)raw" +
> +                         ClangDocVersion + R"raw(</span>
> +</footer>
>  )raw";
>
>    EXPECT_EQ(Expected, Actual.str());
> @@ -386,19 +425,27 @@ TEST(HTMLGeneratorTest, emitCommentHTML)
>  <title></title>
>  <link rel="stylesheet" href="clang-doc-default-stylesheet.css"/>
>  <script src="index.js"></script>
> -<div id="index" path=""></div>
> -<div>
> -  <h3 id="0000000000000000000000000000000000000000">f</h3>
> -  <p>void f(int I, int J)</p>
> -  <p>Defined at line 10 of file test.cpp</p>
> -  <div>
> +<header id="project-title">test-project</header>
> +<main>
> +  <div id="sidebar-left" path="" class="col-xs-6 col-sm-3 col-md-2
> sidebar sidebar-offcanvas-left"></div>
> +  <div id="main-content" class="col-xs-12 col-sm-9 col-md-8 main-content">
> +    <h3 id="0000000000000000000000000000000000000000">f</h3>
> +    <p>void f(int I, int J)</p>
> +    <p>Defined at line 10 of file test.cpp</p>
>      <div>
> -      <p> Brief description.</p>
> -      <p> Extended description that continues onto the next line.</p>
> -      <p> Comment with html entities: &, <, >, ",
> '.</p>
> +      <div>
> +        <p> Brief description.</p>
> +        <p> Extended description that continues onto the next line.</p>
> +        <p> Comment with html entities: &, <, >, ",
> '.</p>
> +      </div>
>      </div>
>    </div>
> -</div>
> +  <div id="sidebar-right" class="col-xs-6 col-sm-6 col-md-2 sidebar
> sidebar-offcanvas-right"></div>
> +</main>
> +<footer>
> +  <span class="no-break">)raw" +
> +                         ClangDocVersion + R"raw(</span>
> +</footer>
>  )raw";
>
>    EXPECT_EQ(Expected, Actual.str());
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190816/d2c62aef/attachment-0001.html>


More information about the cfe-commits mailing list