On 06/28/10 21:16, Tom Tromey wrote: [snip] > > I think we should be clear that the need to write a mark function for a > new type is a drawback of this approach. Perhaps gengtype could still > write the functions for ordinary types in GCC, just not (templatized) > containers. [snip]
An alternate way to generate the needed information is to wrap each garbage collected pointer within a smart pointer, say gcptr<T>, and the CTOR for that gcptr<T> was instrumented to report the offset of it's this pointer w.r.t. some global pointer, say: char* start_object=0; and that start_object was pointing to the beginning of the object, say of type U, containing the gcptr<T>, then that would give you the same information as currently done by gengtype for a particular type, U. Of course start_object could be set by some function before "artificially" creating an object of type U. Say: template<U> void artificially_create(void) { char buf[sizeof(U)]; start_object=buf; //Initailize some sort of "data store" //for recording the location of gcptrs //pointers in U. //Call this gcptr_locations<U>. // new (buf) U; // //Close "data store" gcptr_locations<U>. // start_object=0;//indicate to gcptr *not* to record offsets. } And gcptr could be something like: template<T> struct gcptr { T*ptr; gcptr() { if (start_object) { void*voidp_me=this; char*charp_me=static_cast<char*>(voidp_me); unsigned offset_me=start_object-charp_me; // //Store offset_me in gcptr_locations<U>. // } } ... //other member functions }; The gcptr_locations<U> could then be used to generate a mark function, specialized on U: template<typename T>void mark(T&); template<>void mark(U& u) { // use gcptr_locations<U> to mark gcptr<T>'s within u. } Of course, the 'if (start_object){...}' could be surrounded by an: #if GC_OFFSET_CALC #endif which would be disabled during actually running the compiler instead of calculating the offsets. Of course this would save much time since it would just eliminate 1 test; however, it might make the code clearer. This #if .. #endif would also surround the start_object declaration since that wouldn't be needed at runtime either. One disadvantage of this (besides the need for the 'if (start_object)' in all gcptr CTOR's), is that any struct, X, which contains (via inheritance or member variables) another struct, Y, which contains gcptrs, would duplicate the gcptr information in Y instead of just referring to it via some call like: mark(u.y) where, within X there's the member declaration: Y y; Such a scheme was implemented years ago. Code is located here: https://svn.boost.org/trac/boost/browser/sandbox-branches/cppljevans/boost/fields_visitor/ However, fields_visitor code does not use gcptr. Instead, IIRC, the template name is a template parameter. Also, to handle something like std::vector<T>, which may gcptr's within T, the code in the container_extern directory would be used. Unfortunately, the code has not been maintained; however, if there's any interest, I'd revive it. -regards, Larry