[llvm-branch-commits] [clang] [clang][ssaf] Add FormatInfo sub-registry and tests [2/2] (PR #179517)
Balázs Benics via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Feb 5 01:58:06 PST 2026
https://github.com/steakhal updated https://github.com/llvm/llvm-project/pull/179517
>From 0c75c1554e8aed06f0a3ea269138b8c8be6af023 Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Wed, 4 Feb 2026 13:36:01 +0100
Subject: [PATCH 1/8] Satisfy clang-format
---
.../Analysis/Scalable/Registries/MockSerializationFormat.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp b/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp
index d9f5eebce1f0e..69afa0fc439f0 100644
--- a/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp
+++ b/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp
@@ -30,7 +30,7 @@ TUSummary MockSerializationFormat::readTUSummary(llvm::StringRef Path) {
void MockSerializationFormat::writeTUSummary(const TUSummary &Summary,
llvm::StringRef OutputDir) {
- // TODO: Implement this.
+ // TODO: Implement this.
}
static SerializationFormatRegistry::Add<MockSerializationFormat>
>From 3fcdac9224dcd4b736e5d5769e6235ea6714f424 Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Tue, 3 Feb 2026 18:55:24 +0100
Subject: [PATCH 2/8] [clang][ssaf] Add FormatInfo sub-registry and tests [3/3]
Add `FormatInfoEntry` template to support per-analysis-type serialization
within a `SerializationFormat`.
This allows to implement different formats for the different analyses in
a decoupled way.
For testing, this patch also implements the MockSerializationFormat
demonstrating the FormatInfo sub-registry pattern.
Assisted-by: claude
---
.../Serialization/SerializationFormat.h | 17 ++-
.../Serialization/SerializationFormat.cpp | 9 ++
.../Analysis/Scalable/CMakeLists.txt | 1 +
.../Scalable/Registries/FancyAnalysisData.cpp | 87 ++++++++++++++
.../Registries/MockSerializationFormat.cpp | 107 +++++++++++++++++-
.../Registries/MockSerializationFormat.h | 15 +++
.../SerializationFormatRegistryTest.cpp | 64 +++++++++++
7 files changed, 295 insertions(+), 5 deletions(-)
create mode 100644 clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
diff --git a/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h
index 36efc6c273bd5..d648ba60fc160 100644
--- a/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h
+++ b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h
@@ -15,6 +15,7 @@
#define CLANG_ANALYSIS_SCALABLE_SERIALIZATION_SERIALIZATION_FORMAT_H
#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "clang/Analysis/Scalable/Model/SummaryName.h"
#include "clang/Analysis/Scalable/TUSummary/TUSummary.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
@@ -26,8 +27,7 @@ namespace clang::ssaf {
class EntityId;
class EntityIdTable;
class EntityName;
-class TUSummary;
-class TUSummaryData;
+class EntitySummary;
/// Abstract base class for serialization formats.
class SerializationFormat {
@@ -48,6 +48,8 @@ class SerializationFormat {
static const llvm::SmallString<16> &getEntityNameSuffix(const EntityName &EN);
static const NestedBuildNamespace &
getEntityNameNamespace(const EntityName &EN);
+ static decltype(TUSummary::Data) &getData(TUSummary &S);
+ static const decltype(TUSummary::Data) &getData(const TUSummary &S);
public:
explicit SerializationFormat(
@@ -63,6 +65,17 @@ class SerializationFormat {
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
};
+template <class SerializerFn, class DeserializerFn> struct FormatInfoEntry {
+ FormatInfoEntry(SummaryName ForSummary, SerializerFn Serialize,
+ DeserializerFn Deserialize)
+ : ForSummary(ForSummary), Serialize(Serialize), Deserialize(Deserialize) {
+ }
+
+ SummaryName ForSummary;
+ SerializerFn Serialize;
+ DeserializerFn Deserialize;
+};
+
} // namespace clang::ssaf
#endif // CLANG_ANALYSIS_SCALABLE_SERIALIZATION_SERIALIZATION_FORMAT_H
diff --git a/clang/lib/Analysis/Scalable/Serialization/SerializationFormat.cpp b/clang/lib/Analysis/Scalable/Serialization/SerializationFormat.cpp
index 6bb05747058fa..224ad0c40cc2d 100644
--- a/clang/lib/Analysis/Scalable/Serialization/SerializationFormat.cpp
+++ b/clang/lib/Analysis/Scalable/Serialization/SerializationFormat.cpp
@@ -63,3 +63,12 @@ const NestedBuildNamespace &
SerializationFormat::getEntityNameNamespace(const EntityName &EN) {
return EN.Namespace;
}
+
+const decltype(TUSummary::Data) &
+SerializationFormat::getData(const TUSummary &S) {
+ return S.Data;
+}
+
+decltype(TUSummary::Data) &SerializationFormat::getData(TUSummary &S) {
+ return S.Data;
+}
diff --git a/clang/unittests/Analysis/Scalable/CMakeLists.txt b/clang/unittests/Analysis/Scalable/CMakeLists.txt
index 33e1dcc87deba..601845b4ab77a 100644
--- a/clang/unittests/Analysis/Scalable/CMakeLists.txt
+++ b/clang/unittests/Analysis/Scalable/CMakeLists.txt
@@ -4,6 +4,7 @@ add_distinct_clang_unittest(ClangScalableAnalysisTests
EntityIdTest.cpp
EntityIdTableTest.cpp
EntityNameTest.cpp
+ Registries/FancyAnalysisData.cpp
Registries/MockSerializationFormat.cpp
Registries/MockSummaryExtractor1.cpp
Registries/MockSummaryExtractor2.cpp
diff --git a/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp b/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
new file mode 100644
index 0000000000000..ca506df2aa885
--- /dev/null
+++ b/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
@@ -0,0 +1,87 @@
+//===- FancyAnalysisData.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 "Registries/MockSerializationFormat.h"
+#include "clang/Analysis/Scalable/TUSummary/EntitySummary.h"
+#include "llvm/Support/Registry.h"
+#include <vector>
+
+using namespace clang;
+using namespace ssaf;
+
+using SpecialFileRepresentation =
+ MockSerializationFormat::SpecialFileRepresentation;
+using FormatInfo = MockSerializationFormat::FormatInfo;
+
+namespace {
+struct FancyAnalysisData : EntitySummary {
+ FancyAnalysisData() : EntitySummary(SummaryName("FancyAnalysis")) {}
+
+ std::vector<std::string> SomeInternalList;
+};
+} // namespace
+
+static SpecialFileRepresentation
+serializeFancyAnalysis(const EntitySummary &Data,
+ MockSerializationFormat &Format) {
+ const auto &FancyAnalysis = static_cast<const FancyAnalysisData &>(Data);
+
+ std::string Buffer;
+ llvm::raw_string_ostream OS(Buffer);
+ OS << "FancyAnalysisData{\n";
+ OS << " SomeInternalList: ";
+ llvm::interleaveComma(FancyAnalysis.SomeInternalList, OS);
+ OS << "\n";
+ OS << "}\n";
+
+ return SpecialFileRepresentation{/*MockRepresentation=*/std::move(Buffer)};
+}
+
+static std::unique_ptr<EntitySummary>
+deserializeFancyAnalysis(const SpecialFileRepresentation &Obj,
+ EntityIdTable &Table) {
+ auto Result = std::make_unique<FancyAnalysisData>();
+
+ llvm::StringRef Cursor = Obj.MockRepresentation;
+ if (!Cursor.consume_front("FancyAnalysisData{\n SomeInternalList: "))
+ return nullptr;
+
+ auto IsNewLine = [](char C) { return C == '\n'; };
+ llvm::StringRef SomeInternalListStr = Cursor.take_until(IsNewLine);
+ llvm::SmallVector<llvm::StringRef> Parts;
+ SomeInternalListStr.split(Parts, ", ");
+ for (llvm::StringRef Part : Parts) {
+ Result->SomeInternalList.push_back(Part.str());
+ }
+
+ Cursor = Cursor.drop_front(SomeInternalListStr.size());
+
+ if (!Cursor.consume_front("\n}\n"))
+ return nullptr;
+
+ if (!Cursor.empty())
+ return nullptr;
+
+ return std::move(Result);
+}
+
+namespace {
+struct FancyAnalysisFormatInfo : FormatInfo {
+ FancyAnalysisFormatInfo()
+ : FormatInfo{
+ SummaryName("FancyAnalysis"),
+ serializeFancyAnalysis,
+ deserializeFancyAnalysis,
+ } {}
+};
+} // namespace
+
+static llvm::Registry<FormatInfo>::Add<FancyAnalysisFormatInfo>
+ RegisterFormatInfo("FancyAnalysisData",
+ "Format info for FancyAnalysisData for the "
+ "MockSerializationFormat1 format");
diff --git a/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp b/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp
index 69afa0fc439f0..44904d53d2412 100644
--- a/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp
+++ b/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp
@@ -8,29 +8,130 @@
#include "Registries/MockSerializationFormat.h"
#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/Analysis/Scalable/Model/SummaryName.h"
#include "clang/Analysis/Scalable/Serialization/SerializationFormat.h"
#include "clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h"
#include "clang/Analysis/Scalable/TUSummary/TUSummary.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
#include <cassert>
+#include <functional>
+#include <memory>
+#include <set>
using namespace clang;
using namespace ssaf;
MockSerializationFormat::MockSerializationFormat(
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS)
- : SerializationFormat(FS) {}
+ : SerializationFormat(FS) {
+ for (const auto &FormatInfoEntry : llvm::Registry<FormatInfo>::entries()) {
+ std::unique_ptr<FormatInfo> Info = FormatInfoEntry.instantiate();
+ bool Inserted = FormatInfos.try_emplace(Info->ForSummary, *Info).second;
+ if (!Inserted) {
+ llvm::report_fatal_error(
+ "Format info was already registered for summary name: " +
+ Info->ForSummary.str());
+ }
+ }
+}
TUSummary MockSerializationFormat::readTUSummary(llvm::StringRef Path) {
- // TODO: Implement this.
BuildNamespace NS(BuildNamespaceKind::CompilationUnit, "Mock.cpp");
TUSummary Summary(NS);
+
+ auto ManifestFile = FS->getBufferForFile(Path + "/analyses.txt");
+ assert(ManifestFile); // TODO Handle error.
+ llvm::StringRef ManifestFileContent = (*ManifestFile)->getBuffer();
+
+ llvm::SmallVector<llvm::StringRef, 5> Analyses;
+ ManifestFileContent.split(Analyses, /*Separator=*/"\n", /*MaxSplit=*/-1,
+ /*KeepEmpty=*/false);
+
+ for (llvm::StringRef Analysis : Analyses) {
+ SummaryName Name(Analysis.str());
+ auto InputFile = FS->getBufferForFile(Path + "/" + Name.str() + ".special");
+ assert(InputFile);
+ auto InfoIt = FormatInfos.find(Name);
+ if (InfoIt == FormatInfos.end()) {
+ llvm::report_fatal_error(
+ "No FormatInfo was registered for summary name: " + Name.str());
+ }
+ const auto &InfoEntry = InfoIt->second;
+ assert(InfoEntry.ForSummary == Name);
+
+ SpecialFileRepresentation Repr{(*InputFile)->getBuffer().str()};
+ auto &Table = getIdTableForDeserialization(Summary);
+
+ std::unique_ptr<EntitySummary> Result = InfoEntry.Deserialize(Repr, Table);
+ if (!Result) // TODO: Handle error.
+ continue;
+
+ EntityId FooId = Table.getId(EntityName{"c:@F at foo", "", /*Namespace=*/{}});
+ auto &IdMappings = getData(Summary).try_emplace(Name).first->second;
+ [[maybe_unused]] bool Inserted =
+ IdMappings.try_emplace(FooId, std::move(Result)).second;
+ assert(Inserted);
+ }
+
return Summary;
}
void MockSerializationFormat::writeTUSummary(const TUSummary &Summary,
llvm::StringRef OutputDir) {
- // TODO: Implement this.
+ std::error_code EC;
+
+ // Check if output directory exists, create if needed
+ if (!llvm::sys::fs::exists(OutputDir)) {
+ EC = llvm::sys::fs::create_directories(OutputDir);
+ if (EC) {
+ llvm::report_fatal_error("Failed to create output directory '" +
+ OutputDir + "': " + EC.message());
+ }
+ }
+
+ std::set<SummaryName> Analyses;
+ for (const auto &[SummaryName, EntityMappings] : getData(Summary)) {
+ [[maybe_unused]] bool Inserted = Analyses.insert(SummaryName).second;
+ assert(Inserted);
+ for (const auto &Data : llvm::make_second_range(EntityMappings)) {
+ auto InfoIt = FormatInfos.find(SummaryName);
+ if (InfoIt == FormatInfos.end()) {
+ llvm::report_fatal_error(
+ "There was no FormatInfo registered for summary name '" +
+ SummaryName.str() + "'");
+ }
+ const auto &InfoEntry = InfoIt->second;
+ assert(InfoEntry.ForSummary == SummaryName);
+
+ auto Output = InfoEntry.Serialize(*Data, *this);
+
+ std::string AnalysisFilePath =
+ (OutputDir + "/" + SummaryName.str() + ".special").str();
+ llvm::raw_fd_ostream AnalysisOutputFile(AnalysisFilePath, EC);
+ if (EC) {
+ llvm::report_fatal_error("Failed to create file '" + AnalysisFilePath +
+ "': " + llvm::StringRef(EC.message()));
+ }
+ AnalysisOutputFile << Output.MockRepresentation;
+ }
+ }
+
+ std::string ManifestFilePath = (OutputDir + "/analyses.txt").str();
+ llvm::raw_fd_ostream ManifestFile(ManifestFilePath, EC);
+ if (EC) {
+ llvm::report_fatal_error("Failed to create manifest file '" +
+ ManifestFilePath +
+ "': " + llvm::StringRef(EC.message()));
+ }
+
+ interleave(map_range(Analyses, std::mem_fn(&SummaryName::str)), ManifestFile,
+ "\n");
+ ManifestFile << "\n";
}
static SerializationFormatRegistry::Add<MockSerializationFormat>
diff --git a/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.h b/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.h
index 318c8ac26502d..a106e53fc20ac 100644
--- a/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.h
+++ b/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.h
@@ -9,7 +9,10 @@
#ifndef LLVM_CLANG_UNITTESTS_ANALYSIS_SCALABLE_REGISTRIES_MOCKSERIALIZATIONFORMAT_H
#define LLVM_CLANG_UNITTESTS_ANALYSIS_SCALABLE_REGISTRIES_MOCKSERIALIZATIONFORMAT_H
+#include "clang/Analysis/Scalable/Model/SummaryName.h"
#include "clang/Analysis/Scalable/Serialization/SerializationFormat.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
+#include <string>
namespace clang::ssaf {
@@ -22,6 +25,18 @@ class MockSerializationFormat final : public SerializationFormat {
void writeTUSummary(const TUSummary &Summary,
llvm::StringRef OutputDir) override;
+
+ struct SpecialFileRepresentation {
+ std::string MockRepresentation;
+ };
+
+ using SerializerFn = llvm::function_ref<SpecialFileRepresentation(
+ const EntitySummary &, MockSerializationFormat &)>;
+ using DeserializerFn = llvm::function_ref<std::unique_ptr<EntitySummary>(
+ const SpecialFileRepresentation &, EntityIdTable &)>;
+
+ using FormatInfo = FormatInfoEntry<SerializerFn, DeserializerFn>;
+ std::map<SummaryName, FormatInfo> FormatInfos;
};
} // namespace clang::ssaf
diff --git a/clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp b/clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp
index 261d1dae21893..11c98155dd136 100644
--- a/clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp
+++ b/clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp
@@ -7,12 +7,43 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h"
+#include "clang/Analysis/Scalable/TUSummary/TUSummary.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "gtest/gtest.h"
+#include <memory>
+using namespace llvm;
using namespace clang;
using namespace ssaf;
+// Returns the file name and content in a map.
+static std::map<std::string, std::string> readFilesFromDir(StringRef DirPath) {
+ std::map<std::string, std::string> Result;
+ std::error_code EC;
+
+ for (sys::fs::directory_iterator It(DirPath, EC), End; It != End && !EC;
+ It.increment(EC)) {
+ StringRef FilePath = It->path();
+
+ if (sys::fs::is_directory(FilePath))
+ continue;
+
+ auto BufferOrErr = MemoryBuffer::getFile(FilePath);
+ if (!BufferOrErr)
+ continue;
+
+ // Store only the filename (relative to DirPath).
+ StringRef FileName = sys::path::filename(FilePath);
+ Result[FileName.str()] = BufferOrErr.get()->getBuffer().str();
+ }
+
+ return Result;
+}
namespace {
TEST(SerializationFormatRegistryTest, isFormatRegistered) {
@@ -26,4 +57,37 @@ TEST(SerializationFormatRegistryTest, EnumeratingRegistryEntries) {
EXPECT_EQ(Formats.begin()->getName(), "MockSerializationFormat");
}
+TEST(SerializationFormatRegistryTest, Roundtrip) {
+ StringLiteral FancyAnalysisFileData = "FancyAnalysisData{\n"
+ " SomeInternalList: zed, vayne, lux\n"
+ "}\n";
+
+ auto Inputs = makeIntrusiveRefCnt<vfs::InMemoryFileSystem>();
+ Inputs->addFile("input/analyses.txt", /*ModificationTime=*/{},
+ MemoryBuffer::getMemBufferCopy("FancyAnalysis\n"));
+ Inputs->addFile("input/FancyAnalysis.special", /*ModificationTime=*/{},
+ MemoryBuffer::getMemBufferCopy(FancyAnalysisFileData));
+
+ std::unique_ptr<SerializationFormat> Format =
+ makeFormat(Inputs, "MockSerializationFormat");
+ ASSERT_TRUE(Format);
+
+ TUSummary LoadedSummary = Format->readTUSummary("input");
+
+ // Create a temporary output directory
+ SmallString<128> OutputDir;
+ std::error_code EC = sys::fs::createUniqueDirectory("ssaf-test", OutputDir);
+ ASSERT_FALSE(EC) << "Failed to create temporary directory: " << EC.message();
+ llvm::scope_exit CleanupOnExit(
+ [&] { sys::fs::remove_directories(OutputDir); });
+
+ Format->writeTUSummary(LoadedSummary, OutputDir);
+
+ EXPECT_EQ(readFilesFromDir(OutputDir),
+ (std::map<std::string, std::string>{
+ {"analyses.txt", "FancyAnalysis\n"},
+ {"FancyAnalysis.special", FancyAnalysisFileData.str()},
+ }));
+}
+
} // namespace
>From a7891b2d5ec3a8708b79c69f5882171ae75837e0 Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Thu, 5 Feb 2026 10:43:20 +0100
Subject: [PATCH 3/8] Apply suggested simplifications
---
.../Scalable/Registries/FancyAnalysisData.cpp | 39 +++----------------
1 file changed, 5 insertions(+), 34 deletions(-)
diff --git a/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp b/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
index ca506df2aa885..0c2f6bde56f40 100644
--- a/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
+++ b/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
@@ -22,7 +22,7 @@ namespace {
struct FancyAnalysisData : EntitySummary {
FancyAnalysisData() : EntitySummary(SummaryName("FancyAnalysis")) {}
- std::vector<std::string> SomeInternalList;
+ std::string Text;
};
} // namespace
@@ -30,43 +30,14 @@ static SpecialFileRepresentation
serializeFancyAnalysis(const EntitySummary &Data,
MockSerializationFormat &Format) {
const auto &FancyAnalysis = static_cast<const FancyAnalysisData &>(Data);
-
- std::string Buffer;
- llvm::raw_string_ostream OS(Buffer);
- OS << "FancyAnalysisData{\n";
- OS << " SomeInternalList: ";
- llvm::interleaveComma(FancyAnalysis.SomeInternalList, OS);
- OS << "\n";
- OS << "}\n";
-
- return SpecialFileRepresentation{/*MockRepresentation=*/std::move(Buffer)};
+ return SpecialFileRepresentation{/*MockRepresentation=*/FancyAnalysis.Text};
}
static std::unique_ptr<EntitySummary>
-deserializeFancyAnalysis(const SpecialFileRepresentation &Obj,
- EntityIdTable &Table) {
+deserializeFancyAnalysis(const SpecialFileRepresentation &File,
+ EntityIdTable &) {
auto Result = std::make_unique<FancyAnalysisData>();
-
- llvm::StringRef Cursor = Obj.MockRepresentation;
- if (!Cursor.consume_front("FancyAnalysisData{\n SomeInternalList: "))
- return nullptr;
-
- auto IsNewLine = [](char C) { return C == '\n'; };
- llvm::StringRef SomeInternalListStr = Cursor.take_until(IsNewLine);
- llvm::SmallVector<llvm::StringRef> Parts;
- SomeInternalListStr.split(Parts, ", ");
- for (llvm::StringRef Part : Parts) {
- Result->SomeInternalList.push_back(Part.str());
- }
-
- Cursor = Cursor.drop_front(SomeInternalListStr.size());
-
- if (!Cursor.consume_front("\n}\n"))
- return nullptr;
-
- if (!Cursor.empty())
- return nullptr;
-
+ Result->Text = File.MockRepresentation;
return std::move(Result);
}
>From 3eb4b937cd54043baf86cf5dc0850ab746dd8299 Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Thu, 5 Feb 2026 10:49:29 +0100
Subject: [PATCH 4/8] Also simplify the unittest file input
---
.../Registries/SerializationFormatRegistryTest.cpp | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp b/clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp
index 11c98155dd136..484c38309e3d8 100644
--- a/clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp
+++ b/clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp
@@ -58,15 +58,11 @@ TEST(SerializationFormatRegistryTest, EnumeratingRegistryEntries) {
}
TEST(SerializationFormatRegistryTest, Roundtrip) {
- StringLiteral FancyAnalysisFileData = "FancyAnalysisData{\n"
- " SomeInternalList: zed, vayne, lux\n"
- "}\n";
-
auto Inputs = makeIntrusiveRefCnt<vfs::InMemoryFileSystem>();
Inputs->addFile("input/analyses.txt", /*ModificationTime=*/{},
MemoryBuffer::getMemBufferCopy("FancyAnalysis\n"));
Inputs->addFile("input/FancyAnalysis.special", /*ModificationTime=*/{},
- MemoryBuffer::getMemBufferCopy(FancyAnalysisFileData));
+ MemoryBuffer::getMemBufferCopy("Some FancyAnalysisData..."));
std::unique_ptr<SerializationFormat> Format =
makeFormat(Inputs, "MockSerializationFormat");
@@ -86,7 +82,7 @@ TEST(SerializationFormatRegistryTest, Roundtrip) {
EXPECT_EQ(readFilesFromDir(OutputDir),
(std::map<std::string, std::string>{
{"analyses.txt", "FancyAnalysis\n"},
- {"FancyAnalysis.special", FancyAnalysisFileData.str()},
+ {"FancyAnalysis.special", "Some FancyAnalysisData..."},
}));
}
>From 75d12b4babdeb4ab9512944aab8081ef13a97853 Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Thu, 5 Feb 2026 10:52:41 +0100
Subject: [PATCH 5/8] Remove unused include
---
.../unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp b/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
index 0c2f6bde56f40..ffc299e599a1a 100644
--- a/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
+++ b/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
@@ -9,7 +9,6 @@
#include "Registries/MockSerializationFormat.h"
#include "clang/Analysis/Scalable/TUSummary/EntitySummary.h"
#include "llvm/Support/Registry.h"
-#include <vector>
using namespace clang;
using namespace ssaf;
>From bf096a737bb99d506a9a0fb45bbf082e5a067faf Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Thu, 5 Feb 2026 10:53:12 +0100
Subject: [PATCH 6/8] Fix typo in Description string
---
.../Analysis/Scalable/Registries/FancyAnalysisData.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp b/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
index ffc299e599a1a..73fca2715cc4d 100644
--- a/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
+++ b/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
@@ -54,4 +54,4 @@ struct FancyAnalysisFormatInfo : FormatInfo {
static llvm::Registry<FormatInfo>::Add<FancyAnalysisFormatInfo>
RegisterFormatInfo("FancyAnalysisData",
"Format info for FancyAnalysisData for the "
- "MockSerializationFormat1 format");
+ "MockSerializationFormat format");
>From 0e90d0e3d246ecf3b33f4b22907c5086e52ee1c7 Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Thu, 5 Feb 2026 10:53:34 +0100
Subject: [PATCH 7/8] Move the FormatInfo alias closer to where it matters
---
.../Analysis/Scalable/Registries/FancyAnalysisData.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp b/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
index 73fca2715cc4d..0f06ed7e159b5 100644
--- a/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
+++ b/clang/unittests/Analysis/Scalable/Registries/FancyAnalysisData.cpp
@@ -15,7 +15,6 @@ using namespace ssaf;
using SpecialFileRepresentation =
MockSerializationFormat::SpecialFileRepresentation;
-using FormatInfo = MockSerializationFormat::FormatInfo;
namespace {
struct FancyAnalysisData : EntitySummary {
@@ -41,6 +40,7 @@ deserializeFancyAnalysis(const SpecialFileRepresentation &File,
}
namespace {
+using FormatInfo = MockSerializationFormat::FormatInfo;
struct FancyAnalysisFormatInfo : FormatInfo {
FancyAnalysisFormatInfo()
: FormatInfo{
>From d61e4112db60761bc4119728309a3bfe876ae6cf Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Thu, 5 Feb 2026 10:57:21 +0100
Subject: [PATCH 8/8] Update the SerializationFormatRegistry with the
FormatInfo alias
---
.../Scalable/Serialization/SerializationFormatRegistry.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h
index 17f2610380266..40281d549b402 100644
--- a/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h
+++ b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h
@@ -16,6 +16,7 @@
// format info for it:
//
// namespace {
+// using FormatInfo = MyFormat::FormatInfo;
// struct MyAnalysisFormatInfo : FormatInfo {
// MyAnalysisFormatInfo() : FormatInfo{
// SummaryName("MyAnalysis"),
More information about the llvm-branch-commits
mailing list