https://github.com/evelez7 updated https://github.com/llvm/llvm-project/pull/173297
>From f7e19f177e39e872a9dc63caf6f6629c792dc22b Mon Sep 17 00:00:00 2001 From: Erick Velez <[email protected]> Date: Tue, 9 Dec 2025 10:10:38 -0800 Subject: [PATCH] [clang-doc] Add navigation via namespaces --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 4 + clang-tools-extra/clang-doc/BitcodeWriter.cpp | 8 +- clang-tools-extra/clang-doc/BitcodeWriter.h | 2 + clang-tools-extra/clang-doc/JSONGenerator.cpp | 92 ++++++++++++++++++- .../clang-doc/Representation.cpp | 4 + clang-tools-extra/clang-doc/Representation.h | 14 +++ clang-tools-extra/clang-doc/Serialize.cpp | 29 ++++++ .../clang-doc/assets/clang-doc-mustache.css | 42 +++++++-- .../clang-doc/assets/navbar-template.mustache | 7 ++ .../clang-doc/basic-project.mustache.test | 12 +++ .../test/clang-doc/json/class.cpp | 11 +++ .../test/clang-doc/json/nested-namespace.cpp | 6 +- .../test/clang-doc/namespace.cpp | 32 ++++++- 13 files changed, 249 insertions(+), 14 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index 817981aa0d4a3..3a7126fd2a95e 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -159,6 +159,8 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, return decodeRecord(R, I->Name, Blob); case NAMESPACE_PATH: return decodeRecord(R, I->Path, Blob); + case NAMESPACE_PARENT_USR: + return decodeRecord(R, I->ParentUSR, Blob); default: return llvm::createStringError(llvm::inconvertibleErrorCode(), "invalid field for NamespaceInfo"); @@ -184,6 +186,8 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, return decodeRecord(R, I->IsTypeDef, Blob); case RECORD_MANGLED_NAME: return decodeRecord(R, I->MangledName, Blob); + case RECORD_PARENT_USR: + return decodeRecord(R, I->ParentUSR, Blob); default: return llvm::createStringError(llvm::inconvertibleErrorCode(), "invalid field for RecordInfo"); diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index 650501d1d7606..e4883eea6143d 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -174,6 +174,7 @@ static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor> {NAMESPACE_USR, {"USR", &genSymbolIdAbbrev}}, {NAMESPACE_NAME, {"Name", &genStringAbbrev}}, {NAMESPACE_PATH, {"Path", &genStringAbbrev}}, + {NAMESPACE_PARENT_USR, {"ParentUSR", &genSymbolIdAbbrev}}, {ENUM_USR, {"USR", &genSymbolIdAbbrev}}, {ENUM_NAME, {"Name", &genStringAbbrev}}, {ENUM_DEFLOCATION, {"DefLocation", &genLocationAbbrev}}, @@ -190,6 +191,7 @@ static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor> {RECORD_TAG_TYPE, {"TagType", &genIntAbbrev}}, {RECORD_IS_TYPE_DEF, {"IsTypeDef", &genBoolAbbrev}}, {RECORD_MANGLED_NAME, {"MangledName", &genStringAbbrev}}, + {RECORD_PARENT_USR, {"ParentUSR", &genSymbolIdAbbrev}}, {BASE_RECORD_USR, {"USR", &genSymbolIdAbbrev}}, {BASE_RECORD_NAME, {"Name", &genStringAbbrev}}, {BASE_RECORD_PATH, {"Path", &genStringAbbrev}}, @@ -269,12 +271,12 @@ static const std::vector<std::pair<BlockId, std::vector<RecordId>>> {TYPEDEF_USR, TYPEDEF_NAME, TYPEDEF_DEFLOCATION, TYPEDEF_IS_USING}}, // Namespace Block {BI_NAMESPACE_BLOCK_ID, - {NAMESPACE_USR, NAMESPACE_NAME, NAMESPACE_PATH}}, + {NAMESPACE_USR, NAMESPACE_NAME, NAMESPACE_PATH, NAMESPACE_PARENT_USR}}, // Record Block {BI_RECORD_BLOCK_ID, {RECORD_USR, RECORD_NAME, RECORD_PATH, RECORD_DEFLOCATION, RECORD_LOCATION, RECORD_TAG_TYPE, RECORD_IS_TYPE_DEF, - RECORD_MANGLED_NAME}}, + RECORD_MANGLED_NAME, RECORD_PARENT_USR}}, // BaseRecord Block {BI_BASE_RECORD_BLOCK_ID, {BASE_RECORD_USR, BASE_RECORD_NAME, BASE_RECORD_PATH, @@ -565,6 +567,7 @@ void ClangDocBitcodeWriter::emitBlock(const NamespaceInfo &I) { emitRecord(I.USR, NAMESPACE_USR); emitRecord(I.Name, NAMESPACE_NAME); emitRecord(I.Path, NAMESPACE_PATH); + emitRecord(I.ParentUSR, NAMESPACE_PARENT_USR); for (const auto &N : I.Namespace) emitBlock(N, FieldId::F_namespace); for (const auto &CI : I.Description) @@ -619,6 +622,7 @@ void ClangDocBitcodeWriter::emitBlock(const RecordInfo &I) { emitRecord(I.Name, RECORD_NAME); emitRecord(I.Path, RECORD_PATH); emitRecord(I.MangledName, RECORD_MANGLED_NAME); + emitRecord(I.ParentUSR, RECORD_PARENT_USR); for (const auto &N : I.Namespace) emitBlock(N, FieldId::F_namespace); for (const auto &CI : I.Description) diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.h b/clang-tools-extra/clang-doc/BitcodeWriter.h index 6d1b9e9a7ebf2..fe6e50f83a72b 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.h +++ b/clang-tools-extra/clang-doc/BitcodeWriter.h @@ -108,6 +108,7 @@ enum RecordId { NAMESPACE_USR, NAMESPACE_NAME, NAMESPACE_PATH, + NAMESPACE_PARENT_USR, ENUM_USR, ENUM_NAME, ENUM_DEFLOCATION, @@ -124,6 +125,7 @@ enum RecordId { RECORD_TAG_TYPE, RECORD_IS_TYPE_DEF, RECORD_MANGLED_NAME, + RECORD_PARENT_USR, BASE_RECORD_USR, BASE_RECORD_NAME, BASE_RECORD_PATH, diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp index 6dec347ed0bd0..6be55b58bbf3c 100644 --- a/clang-tools-extra/clang-doc/JSONGenerator.cpp +++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp @@ -321,6 +321,67 @@ serializeCommonAttributes(const Info &I, json::Object &Obj, Obj["Location"] = serializeLocation(Symbol->DefLoc.value(), RepositoryUrl); } + + if (!I.Contexts.empty()) { + json::Value ContextArray = json::Array(); + auto &ContextArrayRef = *ContextArray.getAsArray(); + ContextArrayRef.reserve(I.Contexts.size()); + + std::string CurrentRelativePath; + bool PreviousRecord = false; + for (const auto &Current : I.Contexts) { + json::Value ContextVal = Object(); + Object &Context = *ContextVal.getAsObject(); + serializeReference(Current, Context); + + if (ContextArrayRef.empty() && I.IT == InfoType::IT_record) { + // If the record's immediate context is a namespace, then the + // "index.html" is in the same directory. + if (Current.DocumentationFileName == "index") { + PreviousRecord = false; + Context["RelativePath"] = "./"; + } + // If the immediate context is a record, then the file is one level + // above + else { + PreviousRecord = true; + CurrentRelativePath += "../"; + Context["RelativePath"] = CurrentRelativePath; + } + ContextArrayRef.push_back(ContextVal); + continue; + } + + // If the previous Context was a record then we already went up a level, + // so the current namespace index is in the same directory. + if (PreviousRecord && (Current.DocumentationFileName == "index")) { + PreviousRecord = false; + } + // If the current Context is a record but the previous wasn't a record, + // then the namespace index is located one level above. + else if (Current.DocumentationFileName != "index") { + PreviousRecord = true; + CurrentRelativePath += "../"; + } + // The current Context is a namespace and so was the previous Context. + else { + PreviousRecord = false; + CurrentRelativePath += "../"; + // If this namespace is the global namespace, then its documentation + // name needs to be changed to link correctly. + if (Current.QualName == "GlobalNamespace" && + Current.RelativePath != "./") + Context["DocumentationFileName"] = + SmallString<16>("GlobalNamespace/index"); + } + Context["RelativePath"] = CurrentRelativePath; + ContextArrayRef.insert(ContextArrayRef.begin(), ContextVal); + } + + ContextArrayRef.back().getAsObject()->insert({"End", true}); + Obj["Contexts"] = ContextArray; + Obj["HasContexts"] = true; + } } static void serializeReference(const Reference &Ref, Object &ReferenceObj) { @@ -709,6 +770,32 @@ static Error serializeIndex(const ClangDocContext &CDCtx, StringRef RootDir) { return Error::success(); } +static void serializeContexts(Info *I, + StringMap<std::unique_ptr<Info>> &Infos) { + if (I->USR == GlobalNamespaceID) + return; + auto ParentUSR = I->ParentUSR; + + while (true) { + Info *ParentInfo = + Infos.at(llvm::toStringRef(llvm::toHex(ParentUSR)).str()).get(); + + if (ParentInfo->USR == GlobalNamespaceID) { + Context GlobalRef(ParentInfo->USR, "Global Namespace", + InfoType::IT_namespace, "GlobalNamespace", "", + SmallString<16>("index")); + I->Contexts.push_back(GlobalRef); + return; + } + + Context ParentRef(ParentInfo->USR, ParentInfo->Name, ParentInfo->IT, + ParentInfo->Name, ParentInfo->Path, + ParentInfo->DocumentationFileName); + I->Contexts.push_back(ParentRef); + ParentUSR = ParentInfo->ParentUSR; + } +} + Error JSONGenerator::generateDocumentation( StringRef RootDir, llvm::StringMap<std::unique_ptr<doc::Info>> Infos, const ClangDocContext &CDCtx, std::string DirName) { @@ -742,9 +829,12 @@ Error JSONGenerator::generateDocumentation( if (FileErr) return createFileError("cannot open file " + Group.getKey(), FileErr); - for (const auto &Info : Group.getValue()) + for (const auto &Info : Group.getValue()) { + if (Info->IT == InfoType::IT_record || Info->IT == InfoType::IT_namespace) + serializeContexts(Info, Infos); if (Error Err = generateDocForInfo(Info, InfoOS, CDCtx)) return Err; + } } return serializeIndex(CDCtx, RootDir); diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp index 8eab5fb992ebc..65a24f4e51ab1 100644 --- a/clang-tools-extra/clang-doc/Representation.cpp +++ b/clang-tools-extra/clang-doc/Representation.cpp @@ -272,6 +272,10 @@ void Info::mergeBase(Info &&Other) { llvm::sort(Description); auto Last = llvm::unique(Description); Description.erase(Last, Description.end()); + if (ParentUSR == EmptySID) + ParentUSR = Other.ParentUSR; + if (DocumentationFileName.empty()) + DocumentationFileName = Other.DocumentationFileName; } bool Info::mergeable(const Info &Other) { diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h index a3e779aa39bc4..7ecc47294c160 100644 --- a/clang-tools-extra/clang-doc/Representation.h +++ b/clang-tools-extra/clang-doc/Representation.h @@ -165,6 +165,15 @@ struct Reference { SmallString<16> DocumentationFileName; }; +// A Context is a reference that holds a relative path from a certain Info's +// location. +struct Context : public Reference { + Context(SymbolID USR, StringRef Name, InfoType IT, StringRef QualName, + StringRef Path, SmallString<16> DocumentationFileName) + : Reference(USR, Name, IT, QualName, Path, DocumentationFileName) {} + SmallString<128> RelativePath; +}; + // Holds the children of a record or namespace. struct ScopeChildren { // Namespaces and Records are references because they will be properly @@ -356,11 +365,16 @@ struct Info { // Unique identifier for the decl described by this Info. SymbolID USR = SymbolID(); + // Currently only used for namespaces and records. + SymbolID ParentUSR = SymbolID(); + // InfoType of this particular Info. InfoType IT = InfoType::IT_default; // Comment description of this decl. std::vector<CommentInfo> Description; + + SmallVector<Context, 4> Contexts; }; // Info for namespaces. diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp index 29f8faf94713d..98589acaa4b3e 100644 --- a/clang-tools-extra/clang-doc/Serialize.cpp +++ b/clang-tools-extra/clang-doc/Serialize.cpp @@ -697,10 +697,39 @@ static TemplateParamInfo convertTemplateArgToInfo(const clang::Decl *D, return TemplateParamInfo(Str); } +// Check if the DeclKind is one for which we support contextual relationships. +// There might be other ContextDecls, like blocks, that we currently don't +// handle at all. +static bool isSupportedContext(Decl::Kind DeclKind) { + if (DeclKind == Decl::Kind::Record || DeclKind == Decl::Kind::CXXRecord || + DeclKind == Decl::Kind::Namespace || + DeclKind == Decl::Kind::ClassTemplateSpecialization || + DeclKind == Decl::Kind::ClassTemplatePartialSpecialization) + return true; + return false; +} + +template <typename T> static void findParent(Info &I, const T *D) { + // Only walk up contexts if D is a record or namespace. + if (isSupportedContext(D->getKind())) { + const DeclContext *ParentCtx = dyn_cast<DeclContext>(D)->getLexicalParent(); + while (ParentCtx) { + if (isSupportedContext(ParentCtx->getDeclKind())) { + // Break when we reach the first record or namespace. + I.ParentUSR = getUSRForDecl(dyn_cast<Decl>(ParentCtx)); + break; + } + ParentCtx = ParentCtx->getParent(); + } + } +} + template <typename T> static void populateInfo(Info &I, const T *D, const FullComment *C, bool &IsInAnonymousNamespace) { I.USR = getUSRForDecl(D); + findParent(I, D); + if (auto ConversionDecl = dyn_cast_or_null<CXXConversionDecl>(D); ConversionDecl && ConversionDecl->getConversionType() .getTypePtr() diff --git a/clang-tools-extra/clang-doc/assets/clang-doc-mustache.css b/clang-tools-extra/clang-doc/assets/clang-doc-mustache.css index 67f11f77eae61..ab4135c79d9f4 100644 --- a/clang-tools-extra/clang-doc/assets/clang-doc-mustache.css +++ b/clang-tools-extra/clang-doc/assets/clang-doc-mustache.css @@ -112,7 +112,6 @@ body, html { width: 100%; top: 0; left: 0; - height: 60px; /* Adjust as needed */ color: white; display: flex; align-items: center; @@ -255,6 +254,38 @@ body, html { color:var(--text1) } +.navbar-breadcrumb-container { + position: absolute; + top: 60px; + left: 0; + width: 100%; + background: var(--surface2); + padding: 0.5rem 1rem; + display: flex; + gap: 0.5rem; + border-bottom: 1px solid var(--text2); + box-sizing: border-box; + border-top: 1px solid var(--text2); + border-bottom: 1px solid var(--text2); +} + +.navbar-breadcrumb-item { + padding: 0.25rem 0.75rem; + background: var(--surface1); + border: 1px solid var(--text2); + border-radius: 4px; + color: var(--text1); + font-size: 0.9rem; + white-space: nowrap; +} + +.navbar-breadcrumb-item:hover { + background: var(--brand); + color: var(--text1-inverse); + border-color: var(--brand); + cursor: pointer; +} + .hero__container { margin-top:1rem; display:flex; @@ -317,9 +348,7 @@ body, html { max-width: 2048px; margin-left:auto; margin-right:auto; - margin-top:0; margin-bottom: 1rem; - padding:1rem 2rem } @media(max-width:768px) { @@ -396,9 +425,9 @@ body, html { .sidebar { width: 250px; - top: 60px; left: 0; - height: 100%; + top: 60px; + bottom: 0; position: fixed; background-color: var(--surface1); display: flex; @@ -406,6 +435,7 @@ body, html { flex-direction: column; overflow-y: auto; scrollbar-width: thin; + flex-shrink: 0; } .sidebar h2 { @@ -439,8 +469,8 @@ body, html { /* Content */ .content { + top: 60px; background-color: var(--text1-inverse); - padding: 20px; left: 250px; position: relative; width: calc(100% - 250px); diff --git a/clang-tools-extra/clang-doc/assets/navbar-template.mustache b/clang-tools-extra/clang-doc/assets/navbar-template.mustache index 2767d5af86668..f2ed3804cc672 100644 --- a/clang-tools-extra/clang-doc/assets/navbar-template.mustache +++ b/clang-tools-extra/clang-doc/assets/navbar-template.mustache @@ -12,5 +12,12 @@ </li> </ul> </div> + {{#HasContexts}} + <div class="navbar-breadcrumb-container"> + {{#Contexts}} + <div class="navbar-breadcrumb-item"><a href="{{RelativePath}}{{DocumentationFileName}}.html">{{Name}}</a></div>{{^End}}→{{/End}} + {{/Contexts}} + </div> + {{/HasContexts}} </div> </nav> diff --git a/clang-tools-extra/test/clang-doc/basic-project.mustache.test b/clang-tools-extra/test/clang-doc/basic-project.mustache.test index 26e42280f3474..900fe239d105e 100644 --- a/clang-tools-extra/test/clang-doc/basic-project.mustache.test +++ b/clang-tools-extra/test/clang-doc/basic-project.mustache.test @@ -29,6 +29,9 @@ HTML-SHAPE: <a href="../index.html" class="navbar__link">Hom HTML-SHAPE: </li> HTML-SHAPE: </ul> HTML-SHAPE: </div> +HTML-SHAPE: <div class="navbar-breadcrumb-container"> +HTML-SHAPE: <div class="navbar-breadcrumb-item"><a href="./index.html">Global Namespace</a></div> +HTML-SHAPE: </div> HTML-SHAPE: </div> HTML-SHAPE: </nav> HTML-SHAPE: <main> @@ -136,6 +139,9 @@ HTML-CALC: <a href="../index.html" class="navbar__link">Home HTML-CALC: </li> HTML-CALC: </ul> HTML-CALC: </div> +HTML-CALC: <div class="navbar-breadcrumb-container"> +HTML-CALC: <div class="navbar-breadcrumb-item"><a href="./index.html">Global Namespace</a></div> +HTML-CALC: </div> HTML-CALC: </div> HTML-CALC: </nav> HTML-CALC: <main> @@ -337,6 +343,9 @@ HTML-RECTANGLE: <a href="../index.html" class="navbar__link" HTML-RECTANGLE: </li> HTML-RECTANGLE: </ul> HTML-RECTANGLE: </div> +HTML-RECTANGLE: <div class="navbar-breadcrumb-container"> +HTML-RECTANGLE: <div class="navbar-breadcrumb-item"><a href="./index.html">Global Namespace</a></div> +HTML-RECTANGLE: </div> HTML-RECTANGLE: </div> HTML-RECTANGLE: </nav> HTML-RECTANGLE: <main> @@ -452,6 +461,9 @@ HTML-CIRCLE: <a href="../index.html" class="navbar__link">Ho HTML-CIRCLE: </li> HTML-CIRCLE: </ul> HTML-CIRCLE: </div> +HTML-CIRCLE: <div class="navbar-breadcrumb-container"> +HTML-CIRCLE: <div class="navbar-breadcrumb-item"><a href="./index.html">Global Namespace</a></div> +HTML-CIRCLE: </div> HTML-CIRCLE: </div> HTML-CIRCLE: </nav> HTML-CIRCLE: <main> diff --git a/clang-tools-extra/test/clang-doc/json/class.cpp b/clang-tools-extra/test/clang-doc/json/class.cpp index 79ac20f954f7a..95c0e4762d275 100644 --- a/clang-tools-extra/test/clang-doc/json/class.cpp +++ b/clang-tools-extra/test/clang-doc/json/class.cpp @@ -35,6 +35,16 @@ struct MyClass { }; // CHECK: { +// CHECK-NEXT: "Contexts": [ +// CHECK-NEXT: { +// CHECK-NEXT: "DocumentationFileName": "index", +// CHECK-NEXT: "End": true, +// CHECK-NEXT: "Name": "Global Namespace", +// CHECK-NEXT: "QualName": "GlobalNamespace", +// CHECK-NEXT: "RelativePath": "./", +// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000" +// CHECK-NEXT: } +// CHECK-NEXT: ], // CHECK-NEXT: "Description": { // CHECK-NEXT: "BriefComments": [ // CHECK-NEXT: [ @@ -125,6 +135,7 @@ struct MyClass { // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: ], +// CHECK-NEXT: "HasContexts": true, // CHECK-NEXT: "HasEnums": true, // CHECK-NEXT: "HasPrivateMembers": true, // CHECK-NEXT: "HasPublicFunctions": true, diff --git a/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp b/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp index 5baca7f39b783..3ca63503a650c 100644 --- a/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp +++ b/clang-tools-extra/test/clang-doc/json/nested-namespace.cpp @@ -1,5 +1,6 @@ // RUN: rm -rf %t && mkdir -p %t // RUN: clang-doc --output=%t --format=json --executor=standalone %s +// RUN: clang-doc --output=%t --format=html --executor=standalone %s // RUN: FileCheck %s < %t/json/nested/index.json --check-prefix=NESTED // RUN: FileCheck %s < %t/json/nested/inner/index.json --check-prefix=INNER @@ -7,6 +8,7 @@ namespace nested { int Global; namespace inner { int InnerGlobal; + namespace inner_inner {} } // namespace inner } // namespace nested @@ -17,7 +19,7 @@ namespace nested { // NESTED-NEXT: "IsStatic": false, // NESTED-NEXT: "Location": { // NESTED-NEXT: "Filename": "{{.*}}nested-namespace.cpp", -// NESTED-NEXT: "LineNumber": 7 +// NESTED-NEXT: "LineNumber": 8 // NESTED-NEXT: }, // NESTED-NEXT: "Name": "Global", // NESTED-NEXT: "Namespace": [ @@ -31,7 +33,7 @@ namespace nested { // INNER-NEXT: "IsStatic": false, // INNER-NEXT: "Location": { // INNER-NEXT: "Filename": "{{.*}}nested-namespace.cpp", -// INNER-NEXT: "LineNumber": 9 +// INNER-NEXT: "LineNumber": 10 // INNER-NEXT: }, // INNER-NEXT: "Name": "InnerGlobal", // INNER-NEXT: "Namespace": [ diff --git a/clang-tools-extra/test/clang-doc/namespace.cpp b/clang-tools-extra/test/clang-doc/namespace.cpp index a8267d34efd59..d618676f51c66 100644 --- a/clang-tools-extra/test/clang-doc/namespace.cpp +++ b/clang-tools-extra/test/clang-doc/namespace.cpp @@ -63,6 +63,9 @@ class AnonClass {}; // MD-ANON-INDEX: ### anonFunction // MD-ANON-INDEX: *void anonFunction()* +// HTML-ANON-INDEX: <div class="navbar-breadcrumb-container"> +// HTML-ANON-INDEX: <div class="navbar-breadcrumb-item"><a href="../GlobalNamespace/index.html">Global Namespace</a></div> +// HTML-ANON-INDEX: </div> // HTML-ANON-INDEX: <h2>@nonymous_namespace</h2> // HTML-ANON-INDEX: <h2>Inner Classes</h2> // HTML-ANON-INDEX: <ul class="class-container"> @@ -90,6 +93,10 @@ class ClassInPrimaryNamespace {}; // MD-PRIMARY-CLASS: # class ClassInPrimaryNamespace // MD-PRIMARY-CLASS: Class in PrimaryNamespace +// HTML-PRIMARY-CLASS: <div class="navbar-breadcrumb-container"> +// HTML-PRIMARY-CLASS: <div class="navbar-breadcrumb-item"><a href="../GlobalNamespace/index.html">Global Namespace</a></div>→ +// HTML-PRIMARY-CLASS: <div class="navbar-breadcrumb-item"><a href="./index.html">PrimaryNamespace</a></div> +// HTML-PRIMARY-CLASS: </div> // HTML-PRIMARY-CLASS: <h1 class="hero__title-large">class ClassInPrimaryNamespace</h1> // Nested namespace @@ -107,6 +114,11 @@ class ClassInNestedNamespace {}; // MD-NESTED-CLASS: # class ClassInNestedNamespace // MD-NESTED-CLASS: Class in NestedNamespace +// HTML-NESTED-CLASS: <div class="navbar-breadcrumb-container"> +// HTML-NESTED-CLASS: <div class="navbar-breadcrumb-item"><a href="../../GlobalNamespace/index.html">Global Namespace</a></div>→ +// HTML-NESTED-CLASS: <div class="navbar-breadcrumb-item"><a href="../index.html">PrimaryNamespace</a></div>→ +// HTML-NESTED-CLASS: <div class="navbar-breadcrumb-item"><a href="./index.html">NestedNamespace</a></div> +// HTML-NESTED-CLASS: </div> // HTML-NESTED-CLASS: <h1 class="hero__title-large">class ClassInNestedNamespace</h1> } // namespace NestedNamespace @@ -119,6 +131,10 @@ class ClassInNestedNamespace {}; // MD-NESTED-INDEX: *void functionInNestedNamespace()* // MD-NESTED-INDEX: Function in NestedNamespace +// HTML-NESTED-INDEX: <div class="navbar-breadcrumb-container"> +// HTML-NESTED-INDEX: <div class="navbar-breadcrumb-item"><a href="../../GlobalNamespace/index.html">Global Namespace</a></div>→ +// HTML-NESTED-INDEX: <div class="navbar-breadcrumb-item"><a href="../index.html">PrimaryNamespace</a></div> +// HTML-NESTED-INDEX: </div> // HTML-NESTED-INDEX: <h2>NestedNamespace</h2> // HTML-NESTED-INDEX: <h2>Inner Classes</h2> // HTML-NESTED-INDEX: <ul class="class-container"> @@ -136,7 +152,7 @@ class ClassInNestedNamespace {}; // HTML-NESTED-INDEX: <p> Function in NestedNamespace</p> // HTML-NESTED-INDEX: </div> // HTML-NESTED-INDEX: </div> -// HTML-NESTED-INDEX: <p>Defined at line 98 of file {{.*}}namespace.cpp</p> +// HTML-NESTED-INDEX: <p>Defined at line 105 of file {{.*}}namespace.cpp</p> // HTML-NESTED-INDEX: </div> // HTML-NESTED-INDEX: </div> } // namespace PrimaryNamespace @@ -152,6 +168,9 @@ class ClassInNestedNamespace {}; // MD-PRIMARY-INDEX: *void functionInPrimaryNamespace()* // MD-PRIMARY-INDEX: Function in PrimaryNamespace +// HTML-PRIMARY-INDEX: <div class="navbar-breadcrumb-container"> +// HTML-PRIMARY-INDEX: <div class="navbar-breadcrumb-item"><a href="../GlobalNamespace/index.html">Global Namespace</a></div> +// HTML-PRIMARY-INDEX: </div> // HTML-PRIMARY-INDEX: <h2>PrimaryNamespace</h2> // HTML-PRIMARY-INDEX-NOT: <h2 id="Namespaces">Namespaces</h2> // HTML-PRIMARY-INDEX-NOT: <a href="NestedNamespace{{[\/]}}index.html">NestedNamespace</a> @@ -171,7 +190,7 @@ class ClassInNestedNamespace {}; // HTML-PRIMARY-INDEX: <p> Function in PrimaryNamespace</p> // HTML-PRIMARY-INDEX: </div> // HTML-PRIMARY-INDEX: </div> -// HTML-PRIMARY-INDEX: <p>Defined at line 81 of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p> +// HTML-PRIMARY-INDEX: <p>Defined at line 84 of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p> // HTML-PRIMARY-INDEX: </div> // HTML-PRIMARY-INDEX: </div> // AnotherNamespace @@ -189,6 +208,10 @@ class ClassInAnotherNamespace {}; // MD-ANOTHER-CLASS: # class ClassInAnotherNamespace // MD-ANOTHER-CLASS: Class in AnotherNamespace +// HTML-ANOTHER-CLASS: <div class="navbar-breadcrumb-container"> +// HTML-ANOTHER-CLASS: <div class="navbar-breadcrumb-item"><a href="../GlobalNamespace/index.html">Global Namespace</a></div>→ +// HTML-ANOTHER-CLASS: <div class="navbar-breadcrumb-item"><a href="./index.html">AnotherNamespace</a></div> +// HTML-ANOTHER-CLASS: </div> // HTML-ANOTHER-CLASS: <h1 class="hero__title-large">class ClassInAnotherNamespace</h1> } // namespace AnotherNamespace @@ -202,6 +225,9 @@ class ClassInAnotherNamespace {}; // MD-ANOTHER-INDEX: *void functionInAnotherNamespace()* // MD-ANOTHER-INDEX: Function in AnotherNamespace +// HTML-ANOTHER-INDEX: <div class="navbar-breadcrumb-container"> +// HTML-ANOTHER-INDEX: <div class="navbar-breadcrumb-item"><a href="../GlobalNamespace/index.html">Global Namespace</a></div> +// HTML-ANOTHER-INDEX: </div> // HTML-ANOTHER-INDEX: <h2>AnotherNamespace</h2> // HTML-ANOTHER-INDEX: <h2>Inner Classes</h2> // HTML-ANOTHER-INDEX: <ul class="class-container"> @@ -219,7 +245,7 @@ class ClassInAnotherNamespace {}; // HTML-ANOTHER-INDEX: <p> Function in AnotherNamespace</p> // HTML-ANOTHER-INDEX: </div> // HTML-ANOTHER-INDEX: </div> -// HTML-ANOTHER-INDEX: <p>Defined at line 180 of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p> +// HTML-ANOTHER-INDEX: <p>Defined at line 199 of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}namespace.cpp</p> // HTML-ANOTHER-INDEX: </div> // HTML-ANOTHER-INDEX: </div> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
