================
@@ -67,10 +75,102 @@ class SerializationFormat {
 
   static EntityId makeEntityId(const size_t Index) { return EntityId(Index); }
 
+  /// Constructs an empty WPASuite. Bypasses the private default constructor
+  /// so that deserialization code can build a WPASuite incrementally.
+  static WPASuite makeWPASuite() { return WPASuite(); }
+
 #define FIELD(CLASS, FIELD_NAME)                                               
\
   static const auto &get##FIELD_NAME(const CLASS &X) { return X.FIELD_NAME; }  
\
   static auto &get##FIELD_NAME(CLASS &X) { return X.FIELD_NAME; }
 #include 
"clang/ScalableStaticAnalysisFramework/Core/Model/PrivateFieldNames.def"
+
+  /// Per-format plugin registry for analysis result (de)serializers.
+  ///
+  /// Each concrete format (e.g. JSONFormat) instantiates this template once
+  /// via a public \c using alias. Analysis authors register support with:
+  ///
+  ///   static MyFormat::AnalysisResultRegistry::Add<MyAnalysisResult>
+  ///       Reg(serializeFn, deserializeFn);
+  ///
+  /// The serializer receives \c const MyAnalysisResult & directly — the
+  /// \c Add wrapper handles the downcast from \c AnalysisResult internally.
+  ///
+  /// \p FormatT is otherwise unused — it exists because \c llvm::Registry
+  /// is keyed on the \c Entry type, so two formats that happen to share the
+  /// same serializer/deserializer signatures would collide without a
+  /// disambiguating template parameter.
+  ///
+  /// \c function_ref is non-owning, but \c llvm::Registry only stores
+  /// nullary factories (no captured state). Function-local statics inside
+  /// \c Add<T>::Add(...) give each analysis's \c function_ref values a
+  /// stable, program-lifetime home, and a local \c ConcreteEntry struct
+  /// reads them back when the registry instantiates the factory.
+  template <class FormatT, class SerializerFn, class DeserializerFn>
+  class AnalysisResultRegistryGenerator {
+  public:
+    struct Entry {
+      explicit Entry(SerializerFn Serialize, DeserializerFn Deserialize)
+          : Serialize(Serialize), Deserialize(Deserialize) {}
+      virtual ~Entry() = default;
+      SerializerFn Serialize;
+      DeserializerFn Deserialize;
+    };
+
+    using RegistryT = llvm::Registry<Entry>;
+
+    template <class AnalysisResultT> struct Add {
+      /// Extracts the typed serializer signature from \c SerializerFn.
+      /// Given \c function_ref<R(const AnalysisResult &, Args...)>, produces
+      /// a function-pointer type \c R(*)(const AnalysisResultT &, Args...) and
+      /// a static \c wrap() that downcasts and forwards.
+      template <class> struct SerializerAdapter;
+      template <class R, class... Args>
+      struct SerializerAdapter<
+          llvm::function_ref<R(const AnalysisResult &, Args...)>> {
+        using TypedFnPtr = R (*)(const AnalysisResultT &, Args...);
+        static inline TypedFnPtr Saved = nullptr;
+        static R wrap(const AnalysisResult &Base, Args... args) {
+          return Saved(static_cast<const AnalysisResultT &>(Base), args...);
+        }
+      };
+      using SA = SerializerAdapter<SerializerFn>;
+
+      Add(typename SA::TypedFnPtr TypedSerialize, DeserializerFn Deserialize) {
+        static bool Registered = false;
+        if (Registered) {
+          ErrorBuilder::fatal("support is already registered for analysis: 
{0}",
+                              AnalysisResultT::analysisName());
+        }
+        Registered = true;
+        SA::Saved = TypedSerialize;
+        static auto *SerializeWrap = &SA::wrap;
+        static SerializerFn SavedSerialize(SerializeWrap);
+        static DeserializerFn SavedDeserialize = Deserialize;
+
+        struct ConcreteEntry : Entry {
+          ConcreteEntry() : Entry(SavedSerialize, SavedDeserialize) {}
+        };
+
+        static std::string NameStr =
+            AnalysisResultT::analysisName().str().str();
+        static typename RegistryT::template Add<ConcreteEntry> Reg(NameStr, 
"");
+      }
+    };
+
+    static llvm::Expected<std::pair<SerializerFn, DeserializerFn>>
+    lookup(const AnalysisName &Name) {
----------------
aviralg wrote:

Changed to instantiate.

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

Reply via email to