Index: clang-tools-extra/clang-doc/Generators.h =================================================================== --- clang-tools-extra/clang-doc/Generators.h +++ clang-tools-extra/clang-doc/Generators.h @@ -25,8 +25,11 @@ public: virtual ~Generator() = default; + static Index genIndex(const std::vector> &Infos); + // Write out the decl info in the specified format. - virtual llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) = 0; + virtual llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, + const ClangDocContext &CDCtx) = 0; }; typedef llvm::Registry GeneratorRegistry; Index: clang-tools-extra/clang-doc/Generators.cpp =================================================================== --- clang-tools-extra/clang-doc/Generators.cpp +++ clang-tools-extra/clang-doc/Generators.cpp @@ -13,6 +13,30 @@ namespace clang { namespace doc { +Index Generator::genIndex(const std::vector> &Infos) { + Index Idx; + for (const auto &Info : Infos) { + Index *I = &Idx; + for (auto R = Info->Namespace.rbegin(), E = Info->Namespace.rend(); R != E; + ++R) { + auto It = std::find(I->Children.begin(), I->Children.end(), R->USR); + if (It != I->Children.end()) + I = &*It; + else { + I->Children.emplace_back(R->USR, R->Name, R->RefType, R->Path); + I = &I->Children.back(); + } + } + auto It = std::find(I->Children.begin(), I->Children.end(), Info->USR); + if (It == I->Children.end()) + I->Children.emplace_back(Info->USR, Info->Name, Info->IT, Info->Path); + else if (It->Path.empty()) + It->Path = I->Path; + } + Idx.sort(); + return Idx; +} + llvm::Expected> findGeneratorByName(llvm::StringRef Format) { for (auto I = GeneratorRegistry::begin(), E = GeneratorRegistry::end(); Index: clang-tools-extra/clang-doc/HTMLGenerator.cpp =================================================================== --- clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -24,16 +24,17 @@ public: // Any other tag can be added if required enum TagType { - TAG_META, - TAG_TITLE, + TAG_A, TAG_DIV, TAG_H1, TAG_H2, TAG_H3, + TAG_LI, + TAG_META, TAG_P, + TAG_SPAN, + TAG_TITLE, TAG_UL, - TAG_LI, - TAG_A, }; HTMLTag() = default; @@ -115,15 +116,16 @@ switch (Value) { case HTMLTag::TAG_META: return true; - case HTMLTag::TAG_TITLE: + case HTMLTag::TAG_A: case HTMLTag::TAG_DIV: case HTMLTag::TAG_H1: case HTMLTag::TAG_H2: case HTMLTag::TAG_H3: + case HTMLTag::TAG_LI: case HTMLTag::TAG_P: + case HTMLTag::TAG_SPAN: + case HTMLTag::TAG_TITLE: case HTMLTag::TAG_UL: - case HTMLTag::TAG_LI: - case HTMLTag::TAG_A: return false; } llvm_unreachable("Unhandled HTMLTag::TagType"); @@ -131,13 +133,14 @@ bool HTMLTag::HasInlineChildren() const { switch (Value) { - case HTMLTag::TAG_META: - case HTMLTag::TAG_TITLE: + case HTMLTag::TAG_A: case HTMLTag::TAG_H1: case HTMLTag::TAG_H2: case HTMLTag::TAG_H3: case HTMLTag::TAG_LI: - case HTMLTag::TAG_A: + case HTMLTag::TAG_META: + case HTMLTag::TAG_SPAN: + case HTMLTag::TAG_TITLE: return true; case HTMLTag::TAG_DIV: case HTMLTag::TAG_P: @@ -149,10 +152,8 @@ llvm::SmallString<16> HTMLTag::ToString() const { switch (Value) { - case HTMLTag::TAG_META: - return llvm::SmallString<16>("meta"); - case HTMLTag::TAG_TITLE: - return llvm::SmallString<16>("title"); + case HTMLTag::TAG_A: + return llvm::SmallString<16>("a"); case HTMLTag::TAG_DIV: return llvm::SmallString<16>("div"); case HTMLTag::TAG_H1: @@ -161,14 +162,18 @@ return llvm::SmallString<16>("h2"); case HTMLTag::TAG_H3: return llvm::SmallString<16>("h3"); + case HTMLTag::TAG_LI: + return llvm::SmallString<16>("li"); + case HTMLTag::TAG_META: + return llvm::SmallString<16>("meta"); case HTMLTag::TAG_P: return llvm::SmallString<16>("p"); + case HTMLTag::TAG_SPAN: + return llvm::SmallString<16>("span"); + case HTMLTag::TAG_TITLE: + return llvm::SmallString<16>("title"); case HTMLTag::TAG_UL: return llvm::SmallString<16>("ul"); - case HTMLTag::TAG_LI: - return llvm::SmallString<16>("li"); - case HTMLTag::TAG_A: - return llvm::SmallString<16>("a"); } llvm_unreachable("Unhandled HTMLTag::TagType"); } @@ -362,6 +367,37 @@ "Defined at line " + std::to_string(L.LineNumber) + " of " + L.Filename); } +static std::vector> +genCommonFileNodes(StringRef Title) { + std::vector> Out; + auto MetaNode = llvm::make_unique(HTMLTag::TAG_META); + MetaNode->Attributes.try_emplace("charset", "utf-8"); + Out.emplace_back(std::move(MetaNode)); + Out.emplace_back(llvm::make_unique(HTMLTag::TAG_TITLE, Title)); + return Out; +} + +static std::vector> genHTML(const Index &Index, + StringRef InfoPath) { + std::vector> Out; + if (!Index.Name.empty()) { + Out.emplace_back(llvm::make_unique(HTMLTag::TAG_SPAN)); + auto &SpanBody = Out.back(); + SpanBody->Children.emplace_back(genTypeReference(Index, InfoPath)); + } + if (Index.Children.empty()) + return Out; + Out.emplace_back(llvm::make_unique(HTMLTag::TAG_UL)); + const auto &UlBody = Out.back(); + for (const auto &C : Index.Children) { + auto LiBody = llvm::make_unique(HTMLTag::TAG_LI); + std::vector> Nodes = genHTML(C, InfoPath); + AppendVector(std::move(Nodes), LiBody->Children); + UlBody->Children.emplace_back(std::move(LiBody)); + } + return Out; +} + static std::unique_ptr genHTML(const CommentInfo &I) { if (I.Kind == "FullComment") { auto FullComment = llvm::make_unique(HTMLTag::TAG_DIV); @@ -548,20 +584,16 @@ public: static const char *Format; - llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override; + llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, + const ClangDocContext &CDCtx) override; }; const char *HTMLGenerator::Format = "html"; -llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) { +llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS, + const ClangDocContext &CDCtx) { HTMLFile F; - - auto MetaNode = llvm::make_unique(HTMLTag::TAG_META); - MetaNode->Attributes.try_emplace("charset", "utf-8"); - F.Children.emplace_back(std::move(MetaNode)); - std::string InfoTitle; - Info CastedInfo; auto MainContentNode = llvm::make_unique(HTMLTag::TAG_DIV); switch (I->IT) { case InfoType::IT_namespace: { @@ -593,8 +625,11 @@ llvm::inconvertibleErrorCode()); } - F.Children.emplace_back( - llvm::make_unique(HTMLTag::TAG_TITLE, InfoTitle)); + std::vector> BasicNodes = + genCommonFileNodes(InfoTitle); + AppendVector(std::move(BasicNodes), F.Children); + std::vector> Index = genHTML(CDCtx.Idx, I->Path); + AppendVector(std::move(Index), F.Children); F.Children.emplace_back(std::move(MainContentNode)); F.Render(OS); Index: clang-tools-extra/clang-doc/MDGenerator.cpp =================================================================== --- clang-tools-extra/clang-doc/MDGenerator.cpp +++ clang-tools-extra/clang-doc/MDGenerator.cpp @@ -250,12 +250,14 @@ public: static const char *Format; - llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override; + llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, + const ClangDocContext &CDCtx) override; }; const char *MDGenerator::Format = "md"; -llvm::Error MDGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) { +llvm::Error MDGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS, + const ClangDocContext &CDCtx) { switch (I->IT) { case InfoType::IT_namespace: genMarkdown(*static_cast(I), OS); Index: clang-tools-extra/clang-doc/Representation.h =================================================================== --- clang-tools-extra/clang-doc/Representation.h +++ clang-tools-extra/clang-doc/Representation.h @@ -338,6 +338,18 @@ llvm::SmallVector, 4> Members; // List of enum members. }; +struct Index : public Reference { + Index() = default; + Index(SymbolID USR, StringRef Name, InfoType IT, StringRef Path) + : Reference(USR, Name, IT, Path) {} + bool operator==(const SymbolID &Other) const { return USR == Other; } + bool operator<(const Index &Other) const { return Name < Other.Name; } + + std::vector Children; + + void sort(); +}; + // TODO: Add functionality to include separate markdown pages. // A standalone function to call to merge a vector of infos into one. @@ -347,8 +359,12 @@ mergeInfos(std::vector> &Values); struct ClangDocContext { + ClangDocContext() = default; + ClangDocContext(tooling::ExecutionContext *ECtx, bool PublicOnly) + : ECtx(ECtx), PublicOnly(PublicOnly) {} tooling::ExecutionContext *ECtx; bool PublicOnly; + Index Idx; }; } // namespace doc Index: clang-tools-extra/clang-doc/Representation.cpp =================================================================== --- clang-tools-extra/clang-doc/Representation.cpp +++ clang-tools-extra/clang-doc/Representation.cpp @@ -229,5 +229,11 @@ return llvm::SmallString<16>(""); } +void Index::sort() { + std::sort(Children.begin(), Children.end()); + for (auto &C : Children) + C.sort(); +} + } // namespace doc } // namespace clang Index: clang-tools-extra/clang-doc/YAMLGenerator.cpp =================================================================== --- clang-tools-extra/clang-doc/YAMLGenerator.cpp +++ clang-tools-extra/clang-doc/YAMLGenerator.cpp @@ -243,12 +243,14 @@ public: static const char *Format; - llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override; + llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, + const ClangDocContext &CDCtx) override; }; const char *YAMLGenerator::Format = "yaml"; -llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) { +llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS, + const ClangDocContext &CDCtx) { llvm::yaml::Output InfoYAML(OS); switch (I->IT) { case InfoType::IT_namespace: Index: clang-tools-extra/clang-doc/tool/ClangDocMain.cpp =================================================================== --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -214,16 +214,23 @@ // First reducing phase (reduce all decls into one info per decl). llvm::outs() << "Reducing " << USRToInfos.size() << " infos...\n"; + std::vector> ReducedInfos; for (auto &Group : USRToInfos) { auto Reduced = doc::mergeInfos(Group.getValue()); if (!Reduced) { llvm::errs() << llvm::toString(Reduced.takeError()); continue; } + ReducedInfos.emplace_back(std::move(Reduced.get())); + } + + llvm::outs() << "Constructing index...\n"; + CDCtx.Idx = clang::doc::Generator::genIndex(ReducedInfos); - doc::Info *I = Reduced.get().get(); - auto InfoPath = getInfoOutputFile(OutDirectory, I->Path, I->extractName(), - "." + Format); + llvm::outs() << "Generating docs...\n"; + for (auto &Info : ReducedInfos) { + auto InfoPath = getInfoOutputFile(OutDirectory, Info->Path, + Info->extractName(), "." + Format); if (!InfoPath) { llvm::errs() << toString(InfoPath.takeError()) << "\n"; return 1; @@ -235,7 +242,7 @@ continue; } - if (auto Err = G->get()->generateDocForInfo(I, InfoOS)) + if (auto Err = G->get()->generateDocForInfo(Info.get(), InfoOS, CDCtx)) llvm::errs() << toString(std::move(Err)) << "\n"; } Index: clang-tools-extra/unittests/clang-doc/CMakeLists.txt =================================================================== --- clang-tools-extra/unittests/clang-doc/CMakeLists.txt +++ clang-tools-extra/unittests/clang-doc/CMakeLists.txt @@ -12,6 +12,7 @@ add_extra_unittest(ClangDocTests BitcodeTest.cpp ClangDocTest.cpp + GeneratorTest.cpp HTMLGeneratorTest.cpp MDGeneratorTest.cpp MergeTest.cpp Index: clang-tools-extra/unittests/clang-doc/ClangDocTest.h =================================================================== --- clang-tools-extra/unittests/clang-doc/ClangDocTest.h +++ clang-tools-extra/unittests/clang-doc/ClangDocTest.h @@ -44,6 +44,8 @@ void CheckNamespaceInfo(NamespaceInfo *Expected, NamespaceInfo *Actual); void CheckRecordInfo(RecordInfo *Expected, RecordInfo *Actual); +void CheckIndex(Index &Expected, Index &Actual); + } // namespace doc } // namespace clang Index: clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp =================================================================== --- clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp +++ clang-tools-extra/unittests/clang-doc/ClangDocTest.cpp @@ -63,6 +63,7 @@ void CheckReference(Reference &Expected, Reference &Actual) { EXPECT_EQ(Expected.Name, Actual.Name); EXPECT_EQ(Expected.RefType, Actual.RefType); + EXPECT_EQ(Expected.Path, Actual.Path); } void CheckTypeInfo(TypeInfo *Expected, TypeInfo *Actual) { @@ -180,5 +181,12 @@ CheckEnumInfo(&Expected->ChildEnums[Idx], &Actual->ChildEnums[Idx]); } +void CheckIndex(Index &Expected, Index &Actual) { + CheckReference(Expected, Actual); + ASSERT_EQ(Expected.Children.size(), Actual.Children.size()); + for (size_t Idx = 0; Idx < Actual.Children.size(); ++Idx) + CheckIndex(Expected.Children[Idx], Actual.Children[Idx]); +} + } // namespace doc } // namespace clang Index: clang-tools-extra/unittests/clang-doc/GeneratorTest.cpp =================================================================== --- /dev/null +++ clang-tools-extra/unittests/clang-doc/GeneratorTest.cpp @@ -0,0 +1,70 @@ +//===-- clang-doc/GeneratorTest.cpp ---------------------------------------===// +// +// 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 "ClangDocTest.h" +#include "Generators.h" +#include "Representation.h" +#include "Serialize.h" +#include "gtest/gtest.h" + +namespace clang { +namespace doc { + +TEST(GeneratorTest, emitIndex) { + std::vector> Infos; + Infos.emplace_back(llvm::make_unique()); + Info *InfoA = Infos.back().get(); + InfoA->Name = "A"; + InfoA->USR = serialize::hashUSR("1"); + Infos.emplace_back(llvm::make_unique()); + Info *InfoC = Infos.back().get(); + InfoC->Name = "C"; + InfoC->USR = serialize::hashUSR("3"); + Reference RefB = Reference("B"); + RefB.USR = serialize::hashUSR("2"); + InfoC->Namespace = {std::move(RefB)}; + Infos.emplace_back(llvm::make_unique()); + Info *InfoD = Infos.back().get(); + InfoD->Name = "D"; + InfoD->USR = serialize::hashUSR("4"); + Infos.emplace_back(llvm::make_unique()); + Info *InfoF = Infos.back().get(); + InfoF->Name = "F"; + InfoF->USR = serialize::hashUSR("6"); + Reference RefD = Reference("D"); + RefD.USR = serialize::hashUSR("4"); + Reference RefE = Reference("E"); + RefE.USR = serialize::hashUSR("5"); + InfoF->Namespace = {std::move(RefE), std::move(RefD)}; + Index Idx = Generator::genIndex(Infos); + + Index ExpectedIdx; + Index IndexA; + IndexA.Name = "A"; + ExpectedIdx.Children.emplace_back(std::move(IndexA)); + Index IndexB; + IndexB.Name = "B"; + Index IndexC; + IndexC.Name = "C"; + IndexB.Children.emplace_back(std::move(IndexC)); + ExpectedIdx.Children.emplace_back(std::move(IndexB)); + Index IndexD; + IndexD.Name = "D"; + Index IndexE; + IndexE.Name = "E"; + Index IndexF; + IndexF.Name = "F"; + IndexE.Children.emplace_back(std::move(IndexF)); + IndexD.Children.emplace_back(std::move(IndexE)); + ExpectedIdx.Children.emplace_back(std::move(IndexD)); + + CheckIndex(ExpectedIdx, Idx); +} + +} // 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 @@ -9,6 +9,7 @@ #include "ClangDocTest.h" #include "Generators.h" #include "Representation.h" +#include "Serialize.h" #include "gtest/gtest.h" namespace clang { @@ -38,7 +39,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw( @@ -96,7 +97,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); SmallString<16> PathToF; llvm::sys::path::native("../../../path/to/F.html", PathToF); @@ -161,7 +162,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); SmallString<16> PathToFloat; llvm::sys::path::native("path/to/float.html", PathToFloat); @@ -204,7 +205,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw( @@ -264,7 +265,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw( @@ -293,5 +294,64 @@ EXPECT_EQ(Expected, Actual.str()); } +TEST(HTMLGeneratorTest, emitIndexHTML) { + RecordInfo I; + I.Path = ""; + ClangDocContext CDCtx; + std::vector> Infos; + Infos.emplace_back(llvm::make_unique()); + Info *InfoA = Infos.back().get(); + InfoA->Name = "A"; + InfoA->USR = serialize::hashUSR("1"); + Infos.emplace_back(llvm::make_unique()); + Info *InfoC = Infos.back().get(); + InfoC->Name = "C"; + InfoC->USR = serialize::hashUSR("3"); + Reference RefB = Reference("B"); + RefB.USR = serialize::hashUSR("2"); + InfoC->Namespace = {std::move(RefB)}; + Infos.emplace_back(llvm::make_unique()); + Info *InfoD = Infos.back().get(); + InfoD->Name = "D"; + InfoD->USR = serialize::hashUSR("4"); + Infos.emplace_back(llvm::make_unique()); + Info *InfoF = Infos.back().get(); + InfoF->Name = "F"; + InfoF->USR = serialize::hashUSR("6"); + Reference RefD = Reference("D"); + RefD.USR = serialize::hashUSR("4"); + Reference RefE = Reference("E"); + RefE.USR = serialize::hashUSR("5"); + InfoF->Namespace = {std::move(RefE), std::move(RefD)}; + CDCtx.Idx = Generator::genIndex(Infos); + + auto G = getHTMLGenerator(); + assert(G); + std::string Buffer; + llvm::raw_string_ostream Actual(Buffer); + auto Err = G->generateDocForInfo(&I, Actual, CDCtx); + assert(!Err); + std::string Expected = R"raw( + +struct +
    +
  • A
  • +
  • B
      +
    • C
    • +
  • +
  • D
      +
    • E
        +
      • F
      • +
    • +
  • +
+
+

struct

+
+)raw"; + + EXPECT_EQ(Expected, Actual.str()); +} + } // namespace doc } // namespace clang Index: clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp =================================================================== --- clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp +++ clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp @@ -38,7 +38,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw(# namespace Namespace @@ -101,7 +101,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw(# class r @@ -162,7 +162,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw(### f @@ -190,7 +190,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw(| enum class e | @@ -320,7 +320,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw(### f Index: clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp =================================================================== --- clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp +++ clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp @@ -40,7 +40,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw(--- @@ -94,7 +94,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw(--- @@ -158,7 +158,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw(--- @@ -206,7 +206,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw(--- @@ -343,7 +343,7 @@ assert(G); std::string Buffer; llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual); + auto Err = G->generateDocForInfo(&I, Actual, ClangDocContext()); assert(!Err); std::string Expected = R"raw(---