gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / registry.h
index 062a500936d173ec8ef17170e868d859dbce9915..09e2b67c938dbc8b6605bf247b67472910966d00 100644 (file)
@@ -1,7 +1,6 @@
 /* Macros for general registry objects.
 
-   Copyright (C) 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright (C) 2011-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,6 +20,8 @@
 #ifndef REGISTRY_H
 #define REGISTRY_H
 
+#include <type_traits>
+
 /* The macros here implement a template type and functions for
    associating some user data with a container object.
 
    
    - register_TAG_data_with_cleanup(TAG, SAVE, FREE)
    Get a new key for the container type TAG.
-   SAVE and FREE are defined as void (*) (struct TAG *, void *)
-   When the container is destroyed, first all registered SAVE
+   SAVE and FREE are defined as void (*) (struct TAG *object, void *data)
+   When the container object OBJECT is destroyed, first all registered SAVE
    functions are called.
    Then all FREE functions are called.
-   Either or both may be NULL.
+   Either or both may be NULL.  DATA is the data associated with the
+   container object OBJECT.
    
    - clear_TAG_data(TAG, OBJECT)
    Clear all the data associated with OBJECT.  Should be called by the
@@ -158,8 +160,6 @@ const struct TAG ## _data *                                         \
 register_ ## TAG ## _data_with_cleanup (void (*save) (struct TAG *, void *), \
                                        void (*free) (struct TAG *, void *)) \
 {                                                                      \
-  struct registry_data_registration **curr;                            \
-                                                                       \
   return (struct TAG ## _data *)                                       \
     register_data_with_cleanup (&TAG ## _data_registry,                        \
                                (registry_data_callback) save,          \
@@ -186,8 +186,6 @@ TAG ## registry_callback_adaptor (registry_data_callback func,              \
                                  void *data)                           \
 {                                                                      \
   struct TAG *tagged_container = (struct TAG *) container;             \
-  struct registry_fields *rdata                                                \
-    = &ACCESS (tagged_container)->registry_data;                       \
                                                                        \
   registry_ ## TAG ## _callback tagged_func                            \
     = (registry_ ## TAG ## _callback) func;                            \
@@ -247,11 +245,65 @@ typedef void (*registry_ ## TAG ## _callback) (struct TAG *, void *);     \
 extern const struct TAG ## _data *register_ ## TAG ## _data (void);    \
 extern const struct TAG ## _data *register_ ## TAG ## _data_with_cleanup \
  (registry_ ## TAG ## _callback save, registry_ ## TAG ## _callback free); \
-extern void clear_ ## TAG ## _data (struct TAG *);             \
-extern void set_ ## TAG ## _data (struct TAG *,                        \
-                                 const struct TAG ## _data *data, \
-                                 void *value);                 \
-extern void *TAG ## _data (struct TAG *,                       \
-                          const struct TAG ## _data *data);
+extern void clear_ ## TAG ## _data (struct TAG *);                     \
+extern void set_ ## TAG ## _data (struct TAG *,                                \
+                                 const struct TAG ## _data *data,      \
+                                 void *value);                         \
+extern void *TAG ## _data (struct TAG *,                               \
+                          const struct TAG ## _data *data);            \
+                                                                       \
+template<typename DATA, typename Deleter = std::default_delete<DATA>>  \
+class TAG ## _key                                                      \
+{                                                                      \
+public:                                                                        \
+                                                                       \
+  TAG ## _key ()                                                       \
+    : m_key (register_ ## TAG ## _data_with_cleanup (nullptr,          \
+                                                    cleanup))          \
+  {                                                                    \
+  }                                                                    \
+                                                                       \
+  DATA *get (struct TAG *obj) const                                    \
+  {                                                                    \
+    return (DATA *) TAG ## _data (obj, m_key);                         \
+  }                                                                    \
+                                                                       \
+  void set (struct TAG *obj, DATA *data) const                         \
+  {                                                                    \
+    set_ ## TAG ## _data (obj, m_key, data);                           \
+  }                                                                    \
+                                                                       \
+  template<typename Dummy = DATA *, typename... Args>                  \
+  typename std::enable_if<std::is_same<Deleter,                                \
+                                      std::default_delete<DATA>>::value, \
+                         Dummy>::type                                  \
+  emplace (struct TAG *obj, Args &&...args) const                      \
+  {                                                                    \
+    DATA *result = new DATA (std::forward<Args> (args)...);            \
+    set (obj, result);                                                 \
+    return result;                                                     \
+  }                                                                    \
+                                                                       \
+  void clear (struct TAG *obj) const                                   \
+  {                                                                    \
+    DATA *datum = get (obj);                                           \
+    if (datum != nullptr)                                              \
+      {                                                                        \
+       cleanup (obj, datum);                                           \
+       set (obj, nullptr);                                             \
+      }                                                                        \
+  }                                                                    \
+                                                                       \
+private:                                                               \
+                                                                       \
+  static void cleanup (struct TAG *obj, void *arg)                     \
+  {                                                                    \
+    DATA *datum = (DATA *) arg;                                                \
+    Deleter d;                                                         \
+    d (datum);                                                         \
+  }                                                                    \
+                                                                       \
+  const struct TAG ## _data *m_key;                                    \
+};
 
 #endif /* REGISTRY_H */
This page took 0.027395 seconds and 4 git commands to generate.