diff --git a/Examples/test-suite/member_funcptr_galore.i b/Examples/test-suite/member_funcptr_galore.i index 27d7a386a..01857ff1a 100644 --- a/Examples/test-suite/member_funcptr_galore.i +++ b/Examples/test-suite/member_funcptr_galore.i @@ -6,6 +6,12 @@ %warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) pp3; %warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) pp5; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra2; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) ccextra3; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc2; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc3; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) cc5; + %{ #if defined(__SUNPRO_CC) #pragma error_messages (off, badargtype2w) /* Formal argument ... is being passed extern "C" ... */ @@ -191,7 +197,7 @@ int MemberFuncPtrs::qqq5(short (Funcs::* & qq5)(bool)) const { return 0; } int MemberFuncPtrs::qqq6(short (Funcs::* const qq6)(bool)) const { return 0; } int MemberFuncPtrs::qqq7(short (Funcs::* const& qq7)(bool)) const { return 0; } -// member function pointer variables +// member non-const function pointer variables short (Funcs::* pp1)(bool) = &Funcs::FF; short (Funcs::* const * extra2)(bool) = &pp1; @@ -204,4 +210,18 @@ short (Funcs::* *const& pp4)(bool) = extra4; short (Funcs::* & pp5)(bool) = pp1; short (Funcs::* const pp6)(bool) = &Funcs::FF; short (Funcs::* const& pp7)(bool) = pp1; + +// member const function pointer variables +short (Funcs::* cc1)(bool) const = &Funcs::CC; + +short (Funcs::* const * ccextra2)(bool) const = &cc1; +short (Funcs::* * ccextra3)(bool) const = &cc1; +short (Funcs::* *const ccextra4)(bool) const = &cc1; + +short (Funcs::* const *& cc2)(bool) const = ccextra2; +short (Funcs::* *& cc3)(bool) const = ccextra3; +short (Funcs::* *const& cc4)(bool) const = ccextra4; +short (Funcs::* & cc5)(bool) const = cc1; +short (Funcs::* const cc6)(bool) const = &Funcs::CC; +short (Funcs::* const& cc7)(bool) const = cc1; %} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 80ec8611e..bc12997be 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1432,22 +1432,39 @@ static void mark_nodes_as_extend(Node *n) { static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) { int is_pointer_to_member_function = 0; String *decl = Copy(type); + String *poppedtype = NewString(""); assert(qualifier); - if (SwigType_ismemberpointer(decl)) { - String *memberptr = SwigType_pop(decl); - if (SwigType_isfunction(decl)) { - assert(!SwigType_isqualifier(decl)); - SwigType_push(decl, qualifier); - SwigType_push(decl, memberptr); - is_pointer_to_member_function = 1; + + while (decl) { + if (SwigType_ismemberpointer(decl)) { + String *memberptr = SwigType_pop(decl); + if (SwigType_isfunction(decl)) { + is_pointer_to_member_function = 1; + SwigType_push(decl, qualifier); + SwigType_push(decl, memberptr); + Insert(decl, 0, poppedtype); + Delete(memberptr); + break; + } else { + Append(poppedtype, memberptr); + } + Delete(memberptr); } else { - Delete(decl); - decl = Copy(type); + String *popped = SwigType_pop(decl); + if (!popped) + break; + Append(poppedtype, popped); + Delete(popped); } - Delete(memberptr); } - if (!is_pointer_to_member_function) + + if (!is_pointer_to_member_function) { + Delete(decl); + decl = Copy(type); SwigType_push(decl, qualifier); + } + + Delete(poppedtype); return decl; } diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index 829005cd9..5cfa3e890 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -670,6 +670,7 @@ SwigType *SwigType_ltype(const SwigType *s) { int nelements, i; int firstarray = 1; int notypeconv = 0; + int memberpointer = 0; result = NewStringEmpty(); tc = Copy(s); @@ -707,13 +708,16 @@ SwigType *SwigType_ltype(const SwigType *s) { notypeconv = 1; } if (SwigType_isqualifier(element)) { - /* Do nothing. Ignore */ + if (memberpointer) + Append(result, element); + /* otherwise ignore */ } else if (SwigType_ispointer(element)) { Append(result, element); firstarray = 0; } else if (SwigType_ismemberpointer(element)) { Append(result, element); firstarray = 0; + memberpointer = 1; } else if (SwigType_isreference(element)) { if (notypeconv) { Append(result, element); diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c index b2832b6a9..5240927ef 100644 --- a/Source/Swig/typeobj.c +++ b/Source/Swig/typeobj.c @@ -48,7 +48,7 @@ * 'a(n).' = Array of size n [n] * 'f(..,..).' = Function with arguments (args) * 'q(str).' = Qualifier (such as const or volatile) (const, volatile) - * 'm(qual).' = Pointer to member (qual::*) + * 'm(cls).' = Pointer to member (cls::*) * * The complete type representation for varargs is: * 'v(...)'