Author: Paul Kirth
Date: 2026-03-04T13:56:23-08:00
New Revision: 9d1b6214fc0c2ec9794f61a562ed27d914df412d

URL: 
https://github.com/llvm/llvm-project/commit/9d1b6214fc0c2ec9794f61a562ed27d914df412d
DIFF: 
https://github.com/llvm/llvm-project/commit/9d1b6214fc0c2ec9794f61a562ed27d914df412d.diff

LOG: [clang-doc] Sort index and avoid non-determinism (#184675)

Consolidate logic to get sorted children from  StringMap. 
Using the new API makes it more natural to not miss cases
where we missed sorting the children directly.

This also allows us to remove -DAG checks from tests and have
deterministic ordering.

Added: 
    

Modified: 
    clang-tools-extra/clang-doc/JSONGenerator.cpp
    clang-tools-extra/clang-doc/MDGenerator.cpp
    clang-tools-extra/clang-doc/Representation.cpp
    clang-tools-extra/clang-doc/Representation.h
    clang-tools-extra/test/clang-doc/namespace.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp 
b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index fccdd81cfbd6c..354bbf63d62a2 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -829,13 +829,14 @@ static std::vector<Index> preprocessCDCtxIndex(Index 
CDCtxIndex) {
   CDCtxIndex.sort();
   std::vector<Index> Processed;
   Processed.reserve(CDCtxIndex.Children.size());
-  for (auto &Entry : CDCtxIndex.Children) {
-    auto NewPath = Entry.second.getRelativeFilePath("");
+  for (const auto *Idx : CDCtxIndex.getSortedChildren()) {
+    Index NewIdx = *Idx;
+    auto NewPath = NewIdx.getRelativeFilePath("");
     sys::path::native(NewPath, sys::path::Style::posix);
     sys::path::append(NewPath, sys::path::Style::posix,
-                      Entry.second.getFileBaseName() + ".md");
-    Entry.second.Path = NewPath;
-    Processed.push_back(Entry.second);
+                      NewIdx.getFileBaseName() + ".md");
+    NewIdx.Path = NewPath;
+    Processed.push_back(NewIdx);
   }
 
   return Processed;
@@ -884,11 +885,7 @@ static Error serializeIndex(const ClangDocContext &CDCtx, 
StringRef RootDir,
     IndexArrayRef.reserve(CDCtx.Idx.Children.size());
   }
 
-  llvm::SmallVector<const Index *> Children;
-  Children.reserve(IndexCopy.Children.size());
-  for (const auto &[_, Idx] : IndexCopy.Children)
-    Children.push_back(&Idx);
-  llvm::sort(Children, [](const Index *A, const Index *B) { return *A < *B; });
+  auto Children = IndexCopy.getSortedChildren();
 
   for (const auto *Idx : Children) {
     if (Idx->Children.empty())

diff  --git a/clang-tools-extra/clang-doc/MDGenerator.cpp 
b/clang-tools-extra/clang-doc/MDGenerator.cpp
index f94690632895c..5487ca2794769 100644
--- a/clang-tools-extra/clang-doc/MDGenerator.cpp
+++ b/clang-tools-extra/clang-doc/MDGenerator.cpp
@@ -339,12 +339,7 @@ static llvm::Error serializeIndex(ClangDocContext &CDCtx) {
     OS << " for " << CDCtx.ProjectName;
   OS << "\n\n";
 
-  std::vector<const Index *> Children;
-  Children.reserve(CDCtx.Idx.Children.size());
-  for (const auto &[_, C] : CDCtx.Idx.Children)
-    Children.push_back(&C);
-  llvm::sort(Children, [](const Index *A, const Index *B) { return *A < *B; });
-
+  std::vector<const Index *> Children = CDCtx.Idx.getSortedChildren();
   for (const auto *C : Children)
     serializeReference(OS, *C, 0);
 
@@ -363,11 +358,7 @@ static llvm::Error genIndex(ClangDocContext &CDCtx) {
                                        FileErr.message());
   CDCtx.Idx.sort();
   OS << "# " << CDCtx.ProjectName << " C/C++ Reference\n\n";
-  std::vector<const Index *> Children;
-  Children.reserve(CDCtx.Idx.Children.size());
-  for (const auto &[_, C] : CDCtx.Idx.Children)
-    Children.push_back(&C);
-  llvm::sort(Children, [](const Index *A, const Index *B) { return *A < *B; });
+  std::vector<const Index *> Children = CDCtx.Idx.getSortedChildren();
   for (const auto *C : Children) {
     if (!C->Children.empty()) {
       const char *Type;

diff  --git a/clang-tools-extra/clang-doc/Representation.cpp 
b/clang-tools-extra/clang-doc/Representation.cpp
index 18a9ca9f7f000..7436b114eb9cb 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -472,6 +472,16 @@ bool Index::operator<(const Index &Other) const {
   return Name.size() < Other.Name.size();
 }
 
+std::vector<const Index *> Index::getSortedChildren() const {
+  std::vector<const Index *> SortedChildren;
+  SortedChildren.reserve(Children.size());
+  for (const auto &[_, C] : Children)
+    SortedChildren.push_back(&C);
+  llvm::sort(SortedChildren,
+             [](const Index *A, const Index *B) { return *A < *B; });
+  return SortedChildren;
+}
+
 void Index::sort() {
   for (auto &[_, C] : Children)
     C.sort();

diff  --git a/clang-tools-extra/clang-doc/Representation.h 
b/clang-tools-extra/clang-doc/Representation.h
index c28434e0b9442..fbcc2cfbecc4a 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -616,6 +616,7 @@ struct Index : public Reference {
   std::optional<SmallString<16>> JumpToSection;
   llvm::StringMap<Index> Children;
 
+  std::vector<const Index *> getSortedChildren() const;
   void sort();
 };
 

diff  --git a/clang-tools-extra/test/clang-doc/namespace.cpp 
b/clang-tools-extra/test/clang-doc/namespace.cpp
index bb7f23adb0da3..1d7337d60f69c 100644
--- a/clang-tools-extra/test/clang-doc/namespace.cpp
+++ b/clang-tools-extra/test/clang-doc/namespace.cpp
@@ -363,12 +363,11 @@ class ClassInAnotherNamespace {};
 // MD-ALL-FILES: ## [GlobalNamespace](GlobalNamespace{{[\/]}}index.md)
 // MD-ALL-FILES: ## [PrimaryNamespace](PrimaryNamespace{{[\/]}}index.md)
 
-// COM: FIXME: The output from the sorted index should be deterministic.
 // MD-MUSTACHE-ALL-FILES: # All Files
-// MD-MUSTACHE-ALL-FILES-DAG: ## 
[GlobalNamespace](GlobalNamespace{{[\/]}}index.md)
-// MD-MUSTACHE-ALL-FILES-DAG: ## 
[PrimaryNamespace](PrimaryNamespace{{[\/]}}index.md)
-// MD-MUSTACHE-ALL-FILES-DAG: ## 
[@nonymous_namespace](@nonymous_namespace{{[\/]}}index.md)
-// MD-MUSTACHE-ALL-FILES-DAG: ## 
[AnotherNamespace](AnotherNamespace{{[\/]}}index.md)
+// MD-MUSTACHE-ALL-FILES: ## 
[@nonymous_namespace](@nonymous_namespace{{[\/]}}index.md)
+// MD-MUSTACHE-ALL-FILES: ## 
[AnotherNamespace](AnotherNamespace{{[\/]}}index.md)
+// MD-MUSTACHE-ALL-FILES: ## [GlobalNamespace](GlobalNamespace{{[\/]}}index.md)
+// MD-MUSTACHE-ALL-FILES: ## 
[PrimaryNamespace](PrimaryNamespace{{[\/]}}index.md)
 
 // MD-INDEX: #  C/C++ Reference
 // MD-INDEX: * Namespace: [@nonymous_namespace](@nonymous_namespace)


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to