================
@@ -155,23 +176,81 @@ template <typename T, typename... CtorParamTypes> class
Registry {
} // end namespace llvm
-#ifdef _WIN32
-/// Instantiate a registry class.
-#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS)
\
+// Helper macros to instantiate registry class.
+//
+// To provide a `Registry` interface, follow these steps:
+//
+// 1.Define your plugin base interface. The interface must have a virtual
+// destructor and the appropriate dllexport/dllimport/visibility annotation.
+//
+// namespace your_ns {
+// class YOURLIB_API SomethingPluginBase {
+// virtual ~SomethingPluginBase() = default;
+// virtual void TheInterface() = 0;
+// };
+//
+// 2.Declare an alias to your `Registry` for convenience.
+//
+// namespace your_ns {
+// using YourRegistry = llvm::Registry<SomethingPluginBase>;
+// }
+//
+// 3.Declare the specialization of the `Registry`, in the global namespace.
+// The declaration must be placed before any use of the `YourRegistry`.
+//
+// LLVM_DECLARE_REGISTRY(your_ns::YourRegistry)
+//
+// 4.In a .cpp file, define the specialization in the global namespace.
+//
+// LLVM_DEFINE_REGISTRY(your_ns::YourRegistry)
+//
+// Technically, these macros don't instantiate `Registry` despite the name.
+// They handle underlying storage that used by `Registry` indirectly, enforcing
+// proper declarations/definitions by compilers or linkers. If you forget to
+// place `LLVM_DEFINE_REGISTRY`, your linker will complain about a missing
+// `getRegistryLinkListInstance` definiton.
+#define LLVM_DECLARE_REGISTRY(REGISTRY_CLASS)
\
+ namespace llvm::detail {
\
+ template <>
\
+ struct RegistryLinkListDeclarationMarker<REGISTRY_CLASS> : std::true_type {
\
+ };
\
+ template <>
\
+ RegistryLinkListStorage<REGISTRY_CLASS> &
\
+ getRegistryLinkListInstance<REGISTRY_CLASS>();
\
+ }
+#define LLVM_DEFINE_REGISTRY(REGISTRY_CLASS)
\
+ namespace llvm::detail {
\
+ static_assert(RegistryLinkListDeclarationMarker<REGISTRY_CLASS>::value,
\
+ "Missing matching registry delcaration of " #REGISTRY_CLASS
\
+ ". Place `LLVM_DECLARE_REGISTRY(" #REGISTRY_CLASS
\
+ ")` in a header.");
\
+ template <>
\
+ LLVM_ABI_EXPORT RegistryLinkListStorage<REGISTRY_CLASS> &
\
+ getRegistryLinkListInstance<REGISTRY_CLASS>() {
\
+ static RegistryLinkListStorage<REGISTRY_CLASS> Instance;
\
+ return Instance;
\
+ }
\
+ }
+
+#define LLVM_DETAIL_INSTANTIATE_REGISTRY_1(ABITAG, REGISTRY_CLASS)
\
+ LLVM_DECLARE_REGISTRY(REGISTRY_CLASS)
\
+ LLVM_DEFINE_REGISTRY(REGISTRY_CLASS)
\
namespace llvm {
\
- template class LLVM_ABI_EXPORT Registry<REGISTRY_CLASS::type>;
\
+ template class ABITAG Registry<REGISTRY_CLASS::type>;
\
static_assert(!REGISTRY_CLASS::HasCtorParamTypes,
\
"LLVM_INSTANTIATE_REGISTRY can't be used with extra "
\
- "constructor parameter types");
\
+ "constructor parameter types. Use "
\
+ "LLVM_DECLARE/DEFINE_REGISTRY istead.");
\
}
+
+/// Old style helper macro to instantiate registry class.
+///
+#ifdef _WIN32
+#define LLVM_INSTANTIATE_REGISTRY(REGISTRY_CLASS)
\
+ LLVM_DETAIL_INSTANTIATE_REGISTRY_1(LLVM_ABI_EXPORT, REGISTRY_CLASS)
----------------
steakhal wrote:
Should we just remove these, and migrate their uses?
https://github.com/llvm/llvm-project/pull/185141
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits