From: William S Fulton <wsf@fu...>  20131002 21:57:17

On 2 October 2013 14:51, Vadim Zeitlin <vzswig@...> wrote: > Hello, > > This is another weird bug report which only I seem to be encountering (not > intentionally, believe me). Please consider this example: > > % cat n et.i > 1 %module et > 2 > 3 template <typename T> struct T {}; > 4 > 5 %naturalvar T<E>; > 6 %template(TE) T<E>; > 7 > 8 %inline { enum E { E1, E2, E3 }; } > 9 > 10 %typemap(csvarout, excode=SWIGEXCODE2) const T<E>& %{ > 11 get { > 12 // Intentionally don't use excode here to trigger a > warning if this > 13 // typemap is used. > 14 return $imcall; > 15 }%} > 16 > 17 %inline { > 18 struct S { > 19 T<E> ee; > 20 }; > 21 } > > This works as expected, i.e. > > % swig csharp c++ o wrap_et_csharp.cpp et.i > et.i:19: Warning 844: C# exception may not be thrown  no $excode > or excode attribute in 'csvarout' typemap. > > As the warning indicates, the typemap is used and everything is fine. > > Now exchange the line #8, with the enum declaration, and the line #6 and > rerun swig. Now the typemap is not used any more. And there doesn't seem to > be any way to make SWIG handle "ee" naturally if the enum declaration comes > before the %template line short of using either "naturalvar" command line > option or parameterless "%naturalvar" (which both result in other problems > elsewhere in my code and so I'd like to avoid them). > > I've tried all the possible orders of the different lines keeping the enum > declaration at the top (again, because this is where it appears in my real > code and it's not trivial to change this as enum comes from a header > included from another header from another module...) without success. I > also tried using "%naturalvar TE" in desperation but it doesn't work > neither (which is at least somewhat reassuring). Conversely, any order with > %template coming before the enum declaration does work. > > This definitely looks like a bug in SWIG to me, especially because if you > replace "enum E { ... }" with "struct E {}", everything works just fine, in > whatever order. But, as usual, I have absolutely no idea where to start > looking for it. > > Any hints/ideas? > > The debugtmsearch option is really useful for this kind of problem. In the first case, you'll see: example.i:22: Searching for a suitable 'csvarout' typemap for: T< E > const &S::ee Looking for: T< E > const &S::ee Looking for: T< E > const &ee Looking for: T< E > const & Using: %typemap(csvarout) T< E > const & indicating your typemap is being used as you observed. Swapping lines #6 and #8 gives: example.i:22: Searching for a suitable 'csvarout' typemap for: T< E > *S::ee Looking for: T< E > *S::ee Looking for: T< E > *ee Looking for: T< E > * Looking for: T *S::ee Looking for: T *ee Looking for: T * Looking for: T< enum E > *S::ee Looking for: T< enum E > *ee Looking for: T< enum E > * Looking for: T *S::ee Looking for: T *ee Looking for: T * Looking for: SWIGTYPE *S::ee Looking for: SWIGTYPE *ee Looking for: SWIGTYPE * Using: %typemap(csvarout) SWIGTYPE * Which should explain why your typemap is not being found  %naturalvar is not having any effect and it is looking for a different type. It gives a clue as to what to do to fix though, change line #10 to: %typemap(csvarout, excode=SWIGEXCODE2) const T<E>&, T<E>* %{ then you get a match, tada! example.i:22: Searching for a suitable 'csvarout' typemap for: T< E > *S::ee Looking for: T< E > *S::ee Looking for: T< E > *ee Looking for: T< E > * Using: %typemap(csvarout) T< E > * Quite why T<E>* is required instead of const T<E>& even though you have %naturalvar, is not clear to me without looking further into %naturalvar with enums. William 