From: John L. <jl...@ma...> - 2007-09-05 05:46:52
|
On 09/03/2007 09:01 PM, mark gossage wrote: > Hello All, > > I just tried this on my copy, it gets real interesting. > > =========== > %module templ > > %inline %{ > > typedef int s32; > > template<class T> class Dim { > public: > Dim( T w_, T h_ ) > : w(w_), h(h_) > {} > virtual ~Dim() {} > T w, h; > }; > > template<class T> class Point { > public: > Point( T x_, T y_ ) > : x(x_), y(y_) > {} > Point<T> operator+( const Dim<T>& other ) const > { > return Point<T>( x + other.w, y + other.h ); > } > virtual ~Point() {} > T x, y; > }; > > %} > > %template(s32Point) Point<s32>; > %template(s32Dim) Dim<s32>; > ====================== > > Now this works, but it you swap the two %template() directives about, they don't. > (Go figure). It also works ok if you comment out the operator+ (no idea why). > The issue looks like its in the SwigType stuff, and this is one chunk of code I don't like to look at. > > Any of the SWIG core developers have any insight on this? > Ok, I have attempted a fix I just committed in revision 9933. Reading through the code again, I remember why there is that nasty warning in typesys.c not to modify the code... Please test with all the different modules that exposed this bug... I have just tested with the above simple templ module. See if that fixed it. The issue was the types in r_ltype were getting overwritten when multiple different ltypes mapped to the same mangled type. The entry that was added in r_ltype was dependent on the order that SwigType_remember was called. So the reason changing the order mattered, is because when building Point<s32>, it called SwigType_remember when it reached the Dim<T> in the operator+ function definition (which is also why removing the operator+ changes things too... you could have used any function in which Dim<T> appeared as a parameter... because when parsing Point<> it wasn't calling SwigType_remember on Dim<T>... thus changing the order). Each call to SwigType_remember overwrote the value in r_ltype so whatever parameters happened to be the last call to SwigType_remember is what got stored in r_ltype. This seems to only be a problem in the case of typemaps where the inner type is typedefed... normally calls to SwigType_remember have the same type so it normally doesn't matter that we overwrite r_ltype. So I modified r_ltype to be a list (actually a hashtable because I didn't want to deal with duplicates). WARNING!! This change has not been extensively tested. Since I made a somewhat fundamental change to the type system, this needs more testing. Running all the test suites for the different languages should be enough, but I haven't yet set up the devel environments for all the languages so haven't yet been able to run them. I will try and get all the test suites running (for the languages that use the type system) so this gets tested, but anyone else try SVN after 9933 and look for errors in the type table or type system. John |