python: Make standard Params::create() optional.
The *vast* majority of SimObjects use the standard boilerplate version of their Params::create() method which just returns new ClassName(*this); Rather than force every class to define this method, or annoy and frustrate users who forget and then get linker errors, this change automates the default while leaving the possibility of defining a custom create() method for non-default cases. The situations this mechanism handles can be first broken down by whether the SimObject class has a constructor of the normal form, ie one that takes a const Params reference as its only parameter. If no, then no default create() implementation is defined, and one *must* be defined by the user. If yes, then a default create() implementation is defined as a weak symbol. If the user still wants to define their own create method for some reason, perhaps to add debugging info, to keep track of instances in c++, etc., then they can and it will override the weak symbol and take precedence. The way this is implemented is not straightforward. A set of classes are defined which use SFINAE which either map in the real Params type or a dummy based on whether the normal constructor exists in the SimObject class. Then those classes are used to define *a* create method. Depending on how the SFINAE works out, that will either be *the* create method on the real Params struct, or a create method on a dummy class set up to just absorb the definition and then go away. In either case the create() method is a weak symbol, but in the dummy case it doesn't/shouldn't matter. Annoyingly the compiler insists that the weak symbol be visible. While that makes total sense normally, we don't actually care what happens to the weak symbol if it's attached to the dummy class. Unfortunately that means we need to make the dummy class globally visible, although we put it in a namespace to keep it from colliding with anything useful. Change-Id: I3767a8dc8dc03665a72d5e8c294550d96466f741 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35942 Reviewed-by: Gabe Black <gabe.black@gmail.com> Reviewed-by: Richard Cooper <richard.cooper@arm.com> Maintainer: Gabe Black <gabe.black@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -88,6 +88,35 @@ class ProbeManager;
|
||||
* depth-first traversal is performed (see descendants() in
|
||||
* SimObject.py). This has the effect of calling the method on the
|
||||
* parent node <i>before</i> its children.
|
||||
*
|
||||
* The python version of a SimObject class actually represents its Params
|
||||
* structure which holds all its parameter settings and its name. When python
|
||||
* needs to create a C++ instance of one of those classes, it uses the Params
|
||||
* struct's create() method which returns one instance, set up with the
|
||||
* parameters in the struct.
|
||||
*
|
||||
* When writing a SimObject class, there are three different cases as far as
|
||||
* what you need to do to support the create() method, for hypothetical class
|
||||
* Foo.
|
||||
*
|
||||
* If you have a constructor with a signature like this:
|
||||
*
|
||||
* Foo(const FooParams &)
|
||||
*
|
||||
* you don't have to do anything, a create method will be automatically
|
||||
* defined which will call your constructor and return that instance. You
|
||||
* should use this option most of the time.
|
||||
*
|
||||
* If you have a constructor with that signature but still want to define
|
||||
* your own create method for some reason, you can do that by providing an
|
||||
* alternative implementation which will override the default. It should have
|
||||
* this signature:
|
||||
*
|
||||
* Foo *FooParams::create() const;
|
||||
*
|
||||
* If you don't have a constructor with that signature at all, then you must
|
||||
* implement the create method with that signature which will build your
|
||||
* object in some other way.
|
||||
*/
|
||||
class SimObject : public EventManager, public Serializable, public Drainable,
|
||||
public Stats::Group
|
||||
|
||||
Reference in New Issue
Block a user