+/* Deleter for std::unique_ptr. See comments in
+ target_ops::~target_ops and target_ops::close about heap-allocated
+ targets. */
+struct target_ops_deleter
+{
+ void operator() (target_ops *target)
+ {
+ target->close ();
+ }
+};
+
+/* A unique pointer for target_ops. */
+typedef std::unique_ptr<target_ops, target_ops_deleter> target_ops_up;
+
+/* Decref a target and close if, if there are no references left. */
+extern void decref_target (target_ops *t);
+
+/* A policy class to interface gdb::ref_ptr with target_ops. */
+
+struct target_ops_ref_policy
+{
+ static void incref (target_ops *t)
+ {
+ t->incref ();
+ }
+
+ static void decref (target_ops *t)
+ {
+ decref_target (t);
+ }
+};
+
+/* A gdb::ref_ptr pointer to a target_ops. */
+typedef gdb::ref_ptr<target_ops, target_ops_ref_policy> target_ops_ref;
+
+/* Native target backends call this once at initialization time to
+ inform the core about which is the target that can respond to "run"
+ or "attach". Note: native targets are always singletons. */
+extern void set_native_target (target_ops *target);
+
+/* Get the registered native target, if there's one. Otherwise return
+ NULL. */
+extern target_ops *get_native_target ();
+
+/* Type that manages a target stack. See description of target stacks
+ and strata at the top of the file. */
+
+class target_stack
+{
+public:
+ target_stack () = default;
+ DISABLE_COPY_AND_ASSIGN (target_stack);
+
+ /* Push a new target into the stack of the existing target
+ accessors, possibly superseding some existing accessor. */
+ void push (target_ops *t);
+
+ /* Remove a target from the stack, wherever it may be. Return true
+ if it was removed, false otherwise. */
+ bool unpush (target_ops *t);
+
+ /* Returns true if T is pushed on the target stack. */
+ bool is_pushed (target_ops *t) const
+ { return at (t->stratum ()) == t; }
+
+ /* Return the target at STRATUM. */
+ target_ops *at (strata stratum) const { return m_stack[stratum]; }
+
+ /* Return the target at the top of the stack. */
+ target_ops *top () const { return at (m_top); }