On 2 October 2013 14:51, Vadim Zeitlin <vz-swig@zeitlins.org> 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 parameter-less "%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 -debug-tmsearch 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