https://github.com/steakhal updated https://github.com/llvm/llvm-project/pull/179516
From f51136e476c265424f263493cf664b4eab8c3252 Mon Sep 17 00:00:00 2001 From: Balazs Benics <[email protected]> Date: Tue, 3 Feb 2026 17:49:12 +0100 Subject: [PATCH 1/2] [clang][ssaf] Add SerializationFormatRegistry [2/3] Add a registry infrastructure for SerializationFormat implementations, enabling registration and instantiation of different serialization formats. For example: ```c++ static SerializationFormatRegistry::Add<MyFormat> RegisterFormat("MyFormat", "Description"); ``` Formats can then be instantiated by name using `makeFormat()`. The patch also updates the SerializationFormat base class to accept FileSystem and OutputBackend parameters for virtualizing I/O operations. Assisted-by: claude --- .../Serialization/SerializationFormat.h | 7 ++ .../SerializationFormatRegistry.h | 70 +++++++++++++++++++ clang/lib/Analysis/Scalable/CMakeLists.txt | 1 + .../Serialization/SerializationFormat.cpp | 4 ++ .../SerializationFormatRegistry.cpp | 36 ++++++++++ .../Analysis/Scalable/CMakeLists.txt | 2 + .../Registries/MockSerializationFormat.cpp | 38 ++++++++++ .../Registries/MockSerializationFormat.h | 29 ++++++++ .../SerializationFormatRegistryTest.cpp | 29 ++++++++ 9 files changed, 216 insertions(+) create mode 100644 clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h create mode 100644 clang/lib/Analysis/Scalable/Serialization/SerializationFormatRegistry.cpp create mode 100644 clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp create mode 100644 clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.h create mode 100644 clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp diff --git a/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h index a53a315f461df..36efc6c273bd5 100644 --- a/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h +++ b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormat.h @@ -15,8 +15,10 @@ #define CLANG_ANALYSIS_SCALABLE_SERIALIZATION_SERIALIZATION_FORMAT_H #include "clang/Analysis/Scalable/Model/BuildNamespace.h" +#include "clang/Analysis/Scalable/TUSummary/TUSummary.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/VirtualFileSystem.h" #include <vector> namespace clang::ssaf { @@ -48,12 +50,17 @@ class SerializationFormat { getEntityNameNamespace(const EntityName &EN); public: + explicit SerializationFormat( + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS); virtual ~SerializationFormat() = default; virtual TUSummary readTUSummary(llvm::StringRef Path) = 0; virtual void writeTUSummary(const TUSummary &Summary, llvm::StringRef OutputDir) = 0; + +protected: + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; }; } // namespace clang::ssaf diff --git a/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h new file mode 100644 index 0000000000000..17f2610380266 --- /dev/null +++ b/clang/include/clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h @@ -0,0 +1,70 @@ +//===- SerializationFormatRegistry.h ----------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Registry for SerializationFormats, and some helper functions. +// To register some custom serialization format, insert this code: +// +// static SerializationFormatRegistry::Add<MyFormat> +// RegisterFormat("MyFormat", "My awesome serialization format"); +// +// Then implement the formatter for the specific analysis and register the +// format info for it: +// +// namespace { +// struct MyAnalysisFormatInfo : FormatInfo { +// MyAnalysisFormatInfo() : FormatInfo{ +// SummaryName("MyAnalysis"), +// serializeMyAnalysis, +// deserializeMyAnalysis, +// } {} +// }; +// } // namespace +// +// static llvm::Registry<FormatInfo>::Add<MyAnalysisFormatInfo> +// RegisterFormatInfo( +// "MyAnalysisFormatInfo", +// "The MyFormat format info implementation for MyAnalysis" +// ); +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_ANALYSIS_SCALABLE_SERIALIZATION_SERIALIZATION_FORMAT_REGISTRY_H +#define CLANG_ANALYSIS_SCALABLE_SERIALIZATION_SERIALIZATION_FORMAT_REGISTRY_H + +#include "clang/Analysis/Scalable/Serialization/SerializationFormat.h" +#include "clang/Support/Compiler.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Registry.h" + +namespace clang::ssaf { + +/// Check if a SerializationFormat was registered with a given name. +bool isFormatRegistered(llvm::StringRef FormatName); + +/// Try to instantiate a SerializationFormat with a given name. +/// This might return null if the construction of the desired +/// SerializationFormat failed. +/// It's a fatal error if there is no format registered with the name. +std::unique_ptr<SerializationFormat> +makeFormat(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, + llvm::StringRef FormatName); + +// Registry for adding new SerializationFormat implementations. +using SerializationFormatRegistry = + llvm::Registry<SerializationFormat, + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>>; + +} // namespace clang::ssaf + +namespace llvm { +extern template class CLANG_TEMPLATE_ABI + Registry<clang::ssaf::SerializationFormat, + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>>; +} // namespace llvm + +#endif // CLANG_ANALYSIS_SCALABLE_SERIALIZATION_SERIALIZATION_FORMAT_REGISTRY_H diff --git a/clang/lib/Analysis/Scalable/CMakeLists.txt b/clang/lib/Analysis/Scalable/CMakeLists.txt index 36365b1fb87e1..c8f959e274c6d 100644 --- a/clang/lib/Analysis/Scalable/CMakeLists.txt +++ b/clang/lib/Analysis/Scalable/CMakeLists.txt @@ -8,6 +8,7 @@ add_clang_library(clangAnalysisScalable Model/EntityIdTable.cpp Model/EntityName.cpp Serialization/SerializationFormat.cpp + Serialization/SerializationFormatRegistry.cpp TUSummary/ExtractorRegistry.cpp LINK_LIBS diff --git a/clang/lib/Analysis/Scalable/Serialization/SerializationFormat.cpp b/clang/lib/Analysis/Scalable/Serialization/SerializationFormat.cpp index ee155d22afa9b..6bb05747058fa 100644 --- a/clang/lib/Analysis/Scalable/Serialization/SerializationFormat.cpp +++ b/clang/lib/Analysis/Scalable/Serialization/SerializationFormat.cpp @@ -14,6 +14,10 @@ using namespace clang::ssaf; +SerializationFormat::SerializationFormat( + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) + : FS(FS) {} + EntityIdTable &SerializationFormat::getIdTableForDeserialization(TUSummary &S) { return S.IdTable; } diff --git a/clang/lib/Analysis/Scalable/Serialization/SerializationFormatRegistry.cpp b/clang/lib/Analysis/Scalable/Serialization/SerializationFormatRegistry.cpp new file mode 100644 index 0000000000000..f31a154866238 --- /dev/null +++ b/clang/lib/Analysis/Scalable/Serialization/SerializationFormatRegistry.cpp @@ -0,0 +1,36 @@ +//===- SerializationFormatRegistry.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 "clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h" +#include <memory> + +using namespace clang; +using namespace ssaf; + +// FIXME: LLVM_INSTANTIATE_REGISTRY can't be used here because it drops extra +// type parameters. +template class CLANG_EXPORT_TEMPLATE + llvm::Registry<clang::ssaf::SerializationFormat, + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>>; + +bool ssaf::isFormatRegistered(llvm::StringRef FormatName) { + for (const auto &Entry : SerializationFormatRegistry::entries()) + if (Entry.getName() == FormatName) + return true; + return false; +} + +std::unique_ptr<SerializationFormat> +ssaf::makeFormat(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, + llvm::StringRef FormatName) { + for (const auto &Entry : SerializationFormatRegistry::entries()) + if (Entry.getName() == FormatName) + return Entry.instantiate(std::move(FS)); + assert(false && "Unknown SerializationFormat name"); + return nullptr; +} diff --git a/clang/unittests/Analysis/Scalable/CMakeLists.txt b/clang/unittests/Analysis/Scalable/CMakeLists.txt index a21002e313ead..33e1dcc87deba 100644 --- a/clang/unittests/Analysis/Scalable/CMakeLists.txt +++ b/clang/unittests/Analysis/Scalable/CMakeLists.txt @@ -4,8 +4,10 @@ add_distinct_clang_unittest(ClangScalableAnalysisTests EntityIdTest.cpp EntityIdTableTest.cpp EntityNameTest.cpp + Registries/MockSerializationFormat.cpp Registries/MockSummaryExtractor1.cpp Registries/MockSummaryExtractor2.cpp + Registries/SerializationFormatRegistryTest.cpp Registries/SummaryExtractorRegistryTest.cpp SummaryNameTest.cpp diff --git a/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp b/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp new file mode 100644 index 0000000000000..d9f5eebce1f0e --- /dev/null +++ b/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.cpp @@ -0,0 +1,38 @@ +//===- MockSerializationFormat.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/Model/BuildNamespace.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/StringRef.h" +#include <cassert> + +using namespace clang; +using namespace ssaf; + +MockSerializationFormat::MockSerializationFormat( + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) + : SerializationFormat(FS) {} + +TUSummary MockSerializationFormat::readTUSummary(llvm::StringRef Path) { + // TODO: Implement this. + BuildNamespace NS(BuildNamespaceKind::CompilationUnit, "Mock.cpp"); + TUSummary Summary(NS); + return Summary; +} + +void MockSerializationFormat::writeTUSummary(const TUSummary &Summary, + llvm::StringRef OutputDir) { + // TODO: Implement this. +} + +static SerializationFormatRegistry::Add<MockSerializationFormat> + RegisterFormat("MockSerializationFormat", + "A serialization format for testing"); diff --git a/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.h b/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.h new file mode 100644 index 0000000000000..318c8ac26502d --- /dev/null +++ b/clang/unittests/Analysis/Scalable/Registries/MockSerializationFormat.h @@ -0,0 +1,29 @@ +//===- MockSerializationFormat.h --------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_UNITTESTS_ANALYSIS_SCALABLE_REGISTRIES_MOCKSERIALIZATIONFORMAT_H +#define LLVM_CLANG_UNITTESTS_ANALYSIS_SCALABLE_REGISTRIES_MOCKSERIALIZATIONFORMAT_H + +#include "clang/Analysis/Scalable/Serialization/SerializationFormat.h" + +namespace clang::ssaf { + +class MockSerializationFormat final : public SerializationFormat { +public: + explicit MockSerializationFormat( + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS); + + TUSummary readTUSummary(llvm::StringRef Path) override; + + void writeTUSummary(const TUSummary &Summary, + llvm::StringRef OutputDir) override; +}; + +} // namespace clang::ssaf + +#endif // LLVM_CLANG_UNITTESTS_ANALYSIS_SCALABLE_REGISTRIES_MOCKSERIALIZATIONFORMAT_H diff --git a/clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp b/clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp new file mode 100644 index 0000000000000..261d1dae21893 --- /dev/null +++ b/clang/unittests/Analysis/Scalable/Registries/SerializationFormatRegistryTest.cpp @@ -0,0 +1,29 @@ +//===- SummaryExtractorRegistryTest.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 "clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h" +#include "llvm/ADT/StringRef.h" +#include "gtest/gtest.h" + +using namespace clang; +using namespace ssaf; + +namespace { + +TEST(SerializationFormatRegistryTest, isFormatRegistered) { + EXPECT_FALSE(isFormatRegistered("Non-existent-format")); + EXPECT_TRUE(isFormatRegistered("MockSerializationFormat")); +} + +TEST(SerializationFormatRegistryTest, EnumeratingRegistryEntries) { + auto Formats = SerializationFormatRegistry::entries(); + ASSERT_EQ(std::distance(Formats.begin(), Formats.end()), 1U); + EXPECT_EQ(Formats.begin()->getName(), "MockSerializationFormat"); +} + +} // namespace From 0c75c1554e8aed06f0a3ea269138b8c8be6af023 Mon Sep 17 00:00:00 2001 From: Balazs Benics <[email protected]> Date: Wed, 4 Feb 2026 13:36:01 +0100 Subject: [PATCH 2/2] 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> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
