================
@@ -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)
----------------
kikairoya wrote:

I think it would be better to migrate later, in subsequent patches.

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

Reply via email to