On Wed, Nov 17, 2010 at 03:40:39AM +0100, Paolo Bonzini wrote: > True, but you can hide that cast in a base class. For example you > can use a hierarchy > > Target // abstract base > TargetImplBase<TargetI386> // provides strong typing > TargetI386 // actual implementation > > The Target class would indeed take a void *, but the middle class > would let TargetI386 think in terms of TargetI386::CumulativeArgs > with something like > > void f(void *x) { > // T needs to provide void T::f(T::CumulativeArgs *) > f(static_cast<T::CumulativeArgs *> (x)); > } > > The most similar thing in C (though not suitable for multitarget) is > a struct, which is why I suggest using that now rather than void * > (which would be an implementation detail).
I am admittedly a C++ newbie; the first thing I thought of was: class gcc::cumulative_args { virtual void advance (...) = 0; virtual rtx arg (...) = 0; virtual rtx incoming_arg (...) { return this->arg (...); }; virtual int arg_partial_bytes (...) = 0; // ...and so on for many of the hooks that take CUMULATIVE_ARGS * // possibly with default implementations instead of pure virtual // functions. }; class i386::cumulative_args : gcc::cumulative_args { // concrete implementations of virtual functions }; // the hook interface is then solely for the backend to return // `cumulative_args *' things (the current INIT_*_ARGS macros), which // are then manipulated via the virtual functions above. AFAICS, this eliminates the casting issues Joern described. What are the advantages of the scheme you describe above? (Honest question.) Or are we talking about the same thing in slightly different terms? -Nathan