Nathan Froyd <froy...@codesourcery.com> writes: > 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?
The scheme that Paolo describes avoids virtual functions. But for this usage I personally would prefer virtual functions, since there is no efficiency cost compared to a target hook. Ian