Typemap change for templates

For templates only, the template parameters are fully resolved when
handling typemaps. Without this, it is too hard to have decent rules
to apply typemaps when parameter types are typedef'd and template
parameters have default values.

Fixes %clear for typedefs in templates, eg:

  %typemap("in") XXX<int>::Long "..."
  template typename<T> struct XXX {
    typedef long Long;
  };
  %clear XXX<int>::Long;

as the typemap was previously incorrectly stored as a typemap for long
instead of XXX<int>::Long.
This commit is contained in:
William S Fulton 2017-07-17 07:23:23 +01:00
parent f5cb0420f3
commit aa2932f409
3 changed files with 132 additions and 2 deletions

View File

@ -0,0 +1,32 @@
from typemap_template_typedef import *
def check(got, expected):
if got != expected:
raise RuntimeError("got: " + str(got) + " expected: " + str(expected))
x = XXXInt()
check(x.aa1(0), 0)
check(x.aa2(0), 55)
check(x.aa3(0), 0)
check(aa1(0), 0)
check(aa2(0), 0)
check(x.bb1(0), 0)
check(x.bb2(0), 66)
check(x.bb3(0), 0)
check(bb1(0), 0)
check(bb2(0), 0)
check(x.cc1(0), 0)
check(x.cc2(0), 77)
check(x.cc3(0), 77)
check(cc1(0), 0)
check(cc2(0), 0)
check(x.dd1(0), 0)
check(x.dd2(0), 88)
check(x.dd3(0), 0)
check(dd1(0), 0)
check(dd2(0), 0)

View File

@ -0,0 +1,66 @@
%module typemap_template_typedef
//%module("templatereduce") typemap_template_typedef
%typemap(in) int TMAP55 %{ $1 = 55; /* int TMAP55 typemap */ %}
%typemap(in) int TMAP66 %{ $1 = 66; /* int TMAP66 typemap */ %}
%typemap(in) int TMAP77 %{ $1 = 77; /* int TMAP77 typemap */ %}
%typemap(in) int TMAP88 %{ $1 = 88; /* int TMAP88 typemap */ %}
%apply int TMAP77 { XXX<int>::Long cc }
%inline %{
typedef int Integer;
template<typename T> struct XXX {
#ifdef SWIG
// In swig-3.0.12 'Long aa' was actually stored as 'long aa' in typemap table instead of 'XXX<int>::Long aa'
%apply int TMAP55 { Long aa }
%apply int TMAP66 { XXX<int>::Long bb }
%apply int TMAP88 { XXX<Integer>::Long dd }
#endif
typedef long Long;
long aa1(long aa) { return aa; }
long aa2(Long aa) { return aa; }
long bb1(long bb) { return bb; }
long bb2(Long bb) { return bb; }
long cc1(long cc) { return cc; }
long cc2(Long cc) { return cc; }
long dd1(long dd) { return dd; }
long dd2(Long dd) { return dd; }
#ifdef SWIG
%clear Long aa;
%clear XXX<int>::Long bb;
%clear XXX<Integer>::Long dd;
#endif
long aa3(Long aa) { return aa; }
long bb3(Long bb) { return bb; }
long cc3(Long cc) { return cc; }
long dd3(Long dd) { return dd; }
};
%}
%template(XXXInt) XXX<Integer>;
%clear XXX<int>::Long cc;
%inline %{
long aa1(XXX<int>::Long aa) { return aa; }
long aa2(long aa) { return aa; }
long bb1(XXX<int>::Long bb) { return bb; }
long bb2(long bb) { return bb; }
long cc1(XXX<int>::Long cc) { return cc; }
long cc2(long cc) { return cc; }
long dd1(XXX<Integer>::Long dd) { return dd; }
long dd2(long dd) { return dd; }
%}
%inline %{
typedef Integer INTEGER;
template<typename T1, typename T2 = INTEGER> struct YYY {
void meff(T1 t1, T2 t2) {}
};
%}
%template(YYYIntInt) YYY<INTEGER>;
%inline %{
void whyohwhy(YYY<INTEGER> yy) {}
%}

View File

@ -61,13 +61,44 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper
static Hash *typemaps;
/* -----------------------------------------------------------------------------
* typemap_identifier_fix()
*
* Create a type that can be used as a hash key lookup independent of the various
* ways a template parameter list can be defined. This is achieved by fully
* resolving the template parameters.
*
* This is a copy and modification of feature_identifier_fix in parser.y.
* ----------------------------------------------------------------------------- */
static SwigType *typemap_identifier_fix(const SwigType *s) {
String *tp = SwigType_istemplate_templateprefix(s);
if (tp) {
String *ts, *ta, *tq, *tr;
ts = SwigType_templatesuffix(s);
ta = SwigType_templateargs(s);
tq = Swig_symbol_type_qualify(ta, 0);
tr = SwigType_typedef_resolve_all(ta);
Append(tp,tr);
Append(tp,ts);
Delete(ts);
Delete(ta);
Delete(tq);
Delete(tr);
return tp;
} else {
return NewString(s);
}
}
static Hash *get_typemap(const SwigType *type) {
Hash *tm = 0;
SwigType *dtype = 0;
SwigType *hashtype;
if (SwigType_istemplate(type)) {
String *ty = Swig_symbol_template_deftype(type, 0);
SwigType *rty = typemap_identifier_fix(type);
String *ty = Swig_symbol_template_deftype(rty, 0);
dtype = Swig_symbol_type_qualify(ty, 0);
type = dtype;
Delete(ty);
@ -88,7 +119,7 @@ static void set_typemap(const SwigType *type, Hash **tmhash) {
Hash *new_tm = 0;
assert(*tmhash == 0);
if (SwigType_istemplate(type)) {
SwigType *rty = SwigType_typedef_resolve_all(type);
SwigType *rty = typemap_identifier_fix(type);
String *ty = Swig_symbol_template_deftype(rty, 0);
String *tyq = Swig_symbol_type_qualify(ty, 0);
hashtype = SwigType_remove_global_scope_prefix(tyq);
@ -733,6 +764,7 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
SwigType *oldctype = ctype;
ctype = SwigType_typedef_resolve(ctype_unstripped);
Delete(oldctype);
Delete(ctype_unstripped);
ctype_unstripped = Copy(ctype);
}
}