Change typemap matching rules for the default type (SWIGTYPE) to follow template partial specialization type deduction. Fixes some containers of const pointers. SWIGTYPE*& typemps removed and replaced with SWIGTYPE *const&.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11958 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2010-04-01 18:26:37 +00:00
commit bdb136d611
41 changed files with 477 additions and 122 deletions

View file

@ -3014,8 +3014,6 @@ Node *Language::classLookup(SwigType *s) {
Symtab *stab = 0;
SwigType *ty1 = SwigType_typedef_resolve_all(s);
SwigType *ty2 = SwigType_strip_qualifiers(ty1);
Delete(ty1);
ty1 = 0;
String *base = SwigType_base(ty2);
@ -3052,11 +3050,18 @@ Node *Language::classLookup(SwigType *s) {
if (n) {
/* Found a match. Look at the prefix. We only allow
the cases where where we want a proxy class for the particular type */
if ((Len(prefix) == 0) || // simple type (pass by value)
(Strcmp(prefix, "p.") == 0) || // pointer
(Strcmp(prefix, "r.") == 0) || // reference
(Strcmp(prefix, "r.p.") == 0) || // pointer by reference
SwigType_prefix_is_simple_1D_array(prefix)) { // Simple 1D array (not arrays of pointers/references)
bool acceptable_prefix =
(Len(prefix) == 0) || // simple type (pass by value)
(Strcmp(prefix, "p.") == 0) || // pointer
(Strcmp(prefix, "r.") == 0) || // reference
SwigType_prefix_is_simple_1D_array(prefix); // Simple 1D array (not arrays of pointers/references)
// Also accept pointer by const reference, not non-const pointer reference
if (!acceptable_prefix && (Strcmp(prefix, "r.p.") == 0)) {
Delete(prefix);
prefix = SwigType_prefix(ty1);
acceptable_prefix = (Strncmp(prefix, "r.q(const", 9) == 0);
}
if (acceptable_prefix) {
SwigType *cs = Copy(s);
Setattr(classtypes, cs, n);
Delete(cs);
@ -3064,9 +3069,10 @@ Node *Language::classLookup(SwigType *s) {
n = 0;
}
}
Delete(ty2);
Delete(base);
Delete(prefix);
Delete(base);
Delete(ty2);
Delete(ty1);
}
if (n && (GetFlag(n, "feature:ignore") || Getattr(n, "feature:onlychildren"))) {
n = 0;
@ -3092,10 +3098,6 @@ Node *Language::enumLookup(SwigType *s) {
SwigType *lt = SwigType_ltype(s);
SwigType *ty1 = SwigType_typedef_resolve_all(lt);
SwigType *ty2 = SwigType_strip_qualifiers(ty1);
Delete(lt);
Delete(ty1);
lt = 0;
ty1 = 0;
String *base = SwigType_base(ty2);
@ -3134,9 +3136,11 @@ Node *Language::enumLookup(SwigType *s) {
n = 0;
}
}
Delete(ty2);
Delete(base);
Delete(prefix);
Delete(base);
Delete(ty2);
Delete(ty1);
Delete(lt);
}
if (n && (GetFlag(n, "feature:ignore"))) {
n = 0;

View file

@ -492,6 +492,186 @@ SwigType *SwigType_default(SwigType *t) {
return def;
}
/* -----------------------------------------------------------------------------
* SwigType_default_create()
*
* Create the default type for this datatype. This takes a type and strips it
* down to a generic form first by resolving all typedefs.
*
* Rules:
* Pointers: p.SWIGTYPE
* References: r.SWIGTYPE
* Arrays no dimension: a().SWIGTYPE
* Arrays with dimension: a(ANY).SWIGTYPE
* Member pointer: m(CLASS).SWIGTYPE
* Function pointer: f(ANY).SWIGTYPE
* Enums: enum SWIGTYPE
* Types: SWIGTYPE
*
* Examples (also see SwigType_default_reduce):
*
* int [2][4]
* a(2).a(4).int
* a(ANY).a(ANY).SWIGTYPE
*
* struct A {};
* typedef A *Aptr;
* Aptr const &
* r.q(const).Aptr
* r.q(const).p.SWIGTYPE
*
* enum E {e1, e2};
* enum E const &
* r.q(const).enum E
* r.q(const).enum SWIGTYPE
* ----------------------------------------------------------------------------- */
SwigType *SwigType_default_create(SwigType *ty) {
SwigType *r = 0;
List *l;
Iterator it;
int numitems;
if (!SwigType_isvarargs(ty)) {
SwigType *t = SwigType_typedef_resolve_all(ty);
r = NewStringEmpty();
l = SwigType_split(t);
numitems = Len(l);
if (numitems >= 1) {
String *last_subtype = Getitem(l, numitems-1);
if (SwigType_isenum(last_subtype))
Setitem(l, numitems-1, NewString("enum SWIGTYPE"));
else
Setitem(l, numitems-1, NewString("SWIGTYPE"));
}
for (it = First(l); it.item; it = Next(it)) {
String *subtype = it.item;
if (SwigType_isarray(subtype)) {
if (Equal(subtype, "a()."))
Append(r, NewString("a()."));
else
Append(r, NewString("a(ANY)."));
} else if (SwigType_isfunction(subtype)) {
Append(r, NewString("f(ANY).SWIGTYPE"));
break;
} else if (SwigType_ismemberpointer(subtype)) {
Append(r, NewString("m(CLASS).SWIGTYPE"));
break;
} else {
Append(r, subtype);
}
}
Delete(l);
Delete(t);
}
return r;
}
/* -----------------------------------------------------------------------------
* SwigType_default_reduce()
*
* This function implements type reduction used in the typemap matching rules
* and is very close to the type reduction used in partial template specialization.
* SWIGTYPE is used as the generic type. The basic idea is to repeatedly call
* this function to reduce the type until it is reduced to nothing.
*
* The type t must have already been converted to the default type via a call to
* SwigType_default_create() before calling this function.
*
* Example reductions (matching the examples described in SwigType_default_create):
*
* a(ANY).a(ANY).SWIGTYPE
* a(ANY).a().SWIGTYPE
* a(ANY).p.SWIGTYPE
* a(ANY).SWIGTYPE
* a().SWIGTYPE
* p.SWIGTYPE
* SWIGTYPE
*
* r.q(const).p.SWIGTYPE
* r.q(const).SWIGTYPE
* r.SWIGTYPE
* SWIGTYPE
*
* r.q(const).enum SWIGTYPE
* r.enum SWIGTYPE
* r.SWIGTYPE
* SWIGTYPE
* ----------------------------------------------------------------------------- */
SwigType *SwigType_default_reduce(SwigType *t) {
SwigType *r = NewStringEmpty();
List *l;
Iterator it;
int numitems;
l = SwigType_split(t);
numitems = Len(l);
if (numitems >= 1) {
String *last_subtype = Getitem(l, numitems-1);
int is_enum = SwigType_isenum(last_subtype);
if (numitems >=2 ) {
String *subtype = Getitem(l, numitems-2); /* last but one */
if (SwigType_isarray(subtype)) {
if (is_enum) {
/* enum reduction, enum SWIGTYPE => SWIGTYPE */
Setitem(l, numitems-1, NewString("SWIGTYPE"));
} else {
/* array reduction, a(ANY). => a(). => p. */
String *reduced_subtype = 0;
if (Strcmp(subtype, "a().") == 0) {
reduced_subtype = NewString("p.");
} else if (Strcmp(subtype, "a(ANY).") == 0) {
reduced_subtype = NewString("a().");
} else {
assert(0);
}
Setitem(l, numitems-2, reduced_subtype);
}
} else if (SwigType_ismemberpointer(subtype)) {
/* member pointer reduction, m(CLASS). => p. */
Setitem(l, numitems-2, NewString("p."));
} else if (is_enum && !SwigType_isqualifier(subtype)) {
/* enum reduction, enum SWIGTYPE => SWIGTYPE */
Setitem(l, numitems-1, NewString("SWIGTYPE"));
} else {
/* simple type reduction, eg, r.p.p. => r.p. */
/* also function pointers eg, p.f(ANY). => p. */
Delitem(l, numitems-2);
}
} else {
if (is_enum) {
/* enum reduction, enum SWIGTYPE => SWIGTYPE */
Setitem(l, numitems-1, NewString("SWIGTYPE"));
} else {
/* delete the only item, we are done with reduction */
Delitem(l, 0);
}
}
} else {
assert(0);
}
for (it = First(l); it.item; it = Next(it)) {
Append(r, it.item);
}
if (Len(r) == 0) {
Delete(r);
r = 0;
}
Delete(l);
return r;
}
/* -----------------------------------------------------------------------------
* SwigType_namestr()
*

View file

@ -172,6 +172,8 @@ extern "C" {
extern void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep);
extern SwigType *SwigType_array_type(SwigType *t);
extern String *SwigType_default(SwigType *t);
extern SwigType *SwigType_default_create(SwigType *ty);
extern SwigType *SwigType_default_reduce(SwigType *t);
extern void SwigType_typename_replace(SwigType *t, String *pat, String *rep);
extern SwigType *SwigType_remove_global_scope_prefix(const SwigType *t);
extern SwigType *SwigType_alttype(SwigType *t, int ltmap);

View file

@ -674,7 +674,7 @@ static Hash *typemap_search_helper(int debug_display, Hash *tm, const String *tm
if (debug_display)
Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, 0));
if (tm) {
result = Getattr(tm, tm_method); /* See if there is simply a type match */
result = Getattr(tm, tm_method); /* See if there is simply a type without name match */
if (result && Getattr(result, "code"))
goto ret_result;
if (result)
@ -779,7 +779,7 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
/* Hmmm. Well, no match seems to be found at all. See if there is some kind of default (SWIGTYPE) mapping */
primitive = SwigType_default(type);
primitive = SwigType_default_create(type);
while (primitive) {
tm = get_typemap(ts, primitive);
result = typemap_search_helper(debug_display, tm, tm_method, primitive, cqualifiedname, cname, &backup);
@ -787,7 +787,7 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
goto ret_result;
{
SwigType *nprim = SwigType_default(primitive);
SwigType *nprim = SwigType_default_reduce(primitive);
Delete(primitive);
primitive = nprim;
}

View file

@ -50,6 +50,9 @@ char cvsroot_typeobj_c[] = "$Id$";
* 'q(str).' = Qualifier (such as const or volatile) (const, volatile)
* 'm(qual).' = Pointer to member (qual::*)
*
* The complete type representation for varargs is:
* 'v(...)'
*
* The encoding follows the order that you might describe a type in words.
* For example "p.a(200).int" is "A pointer to array of int's" and
* "p.q(const).char" is "a pointer to a const char".
@ -177,6 +180,9 @@ SwigType *SwigType_del_element(SwigType *t) {
* SwigType_pop()
*
* Pop one type element off the type.
* Example: t in: q(const).p.Integer
* t out: p.Integer
* result: q(const).
* ----------------------------------------------------------------------------- */
SwigType *SwigType_pop(SwigType *t) {