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}}&rarr;{{/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>&rarr;
+// 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>&rarr;
+// HTML-NESTED-CLASS:     <div class="navbar-breadcrumb-item"><a 
href="../index.html">PrimaryNamespace</a></div>&rarr;
+// 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>&rarr;
+// 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>&rarr;
+// 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

Reply via email to