================
@@ -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) {
----------------
steakhal wrote:
It was weird to see `lookup` instantiating something when it matches something
and error when it doesn't.
Usually `lookup` on containers default constructs on failure, and returns the
thing from the container on hit.
https://github.com/llvm/llvm-project/pull/187403
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits