Convert struct target_ops to C++
I.e., use C++ virtual methods and inheritance instead of tables of
function pointers.
Unfortunately, there's no way to do a smooth transition. ALL native
targets in the tree must be converted at the same time. I've tested
all I could with cross compilers and with help from GCC compile farm,
but naturally I haven't been able to test many of the ports. Still, I
made a best effort to port everything over, and while I expect some
build problems due to typos and such, which should be trivial to fix,
I don't expect any design problems. Since the patch would be too big
to review and manage as a single unit, I split it in many chunks.
This patch contains the core changes. The following patches that have
"target_ops/C++:" in their subject line each converts some target or
targets over. For pushing, all the "target_ops/C++:" patches must be
squashed into this patch and pushed together, to avoid breaking the
build (as much as possible). I also haven't written ChangeLog entries
for this part of the series yet, because it's going to be very
mechanical, and I'd rather send this out sooner than later, in order
to hopefuly get some help with testing on native ports that I don't
have access to.
* Implementation notes:
- The flattened current_target is gone. References to current_target
or current_target.beneath are replaced to references to target_stack
(the top of the stack) directly.
- To keep "set debug target" working, This adds a new debug_stratum
layer that sits on top of the stack, prints the debug, and delegates
to the target beneath.
In addition, this makes the shortname and longname properties of
target_ops be virtual methods instead of data fields, and makes the
debug target defer those to the target beneath. This is so that
debug code sprinkled around that does "if (debugtarget) ..." can
transparently print the name of the target beneath.
A patch later in the series actually splits out the
shortname/longname methods to a separate structure, but I preferred
to keep that chance separate as it is associated with changing a bit
the design of how targets are registered and open.
- Since you can't check whether a C++ virtual method is overriden, the
old method of checking whether a target_ops implements a method by
comparing the function pointer must be replaced with something else.
This is fixed by adding a parallel "can_do_foo" target_ops methods.
E.g.,:
+ for (t = target_stack; t != NULL; t = t->beneath)
{
- if (t->to_create_inferior != NULL)
+ if (t->can_create_inferior ())
break;
}
- make-target-delegates was adjusted to generate C++ classes and
methods.
It needed tweaks to grok "virtual" in front of the target method
name, and for the fact that methods are no longer function pointers.
(In particular, the current code parsing the return type was simple
because it could simply parse up until the '(' in '(*to_foo)'.
It now generates a couple C++ classes that inherit target_ops:
dummy_target and debug_target.
Since we need to generate the class declarations as well, i.e., we
need to emit methods twice, we now generate the code in two passes.
- We can no longer use functions like x86_use_watchpoints to install
custom methods on an arbitrary base target.
The patch (actually patches until it's all squashed before pushing)
replaces instances of such a pattern with template mixins. A case
seen in this patch in isolation is memory_breakpoint_target defined
in target.h.
gdb/ChangeLog:
2018-04-18 Pedro Alves <palves@redhat.com>
John Baldwin <jhb@freebsd.org>
# TBD