Add support for member function pointers with ref-qualifiers

This commit is contained in:
William S Fulton 2017-09-05 18:44:00 +01:00
commit eb68e4375d
4 changed files with 195 additions and 45 deletions

View file

@ -544,10 +544,9 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
String *element = 0;
String *nextelement;
String *forwardelement;
String *member_const_function_element = 0;
SwigType *member_function_qualifiers = 0;
List *elements;
int nelements, i;
int member_const_function = 0;
if (id) {
/* stringify the id expanding templates, for example when the id is a fully qualified templated class name */
@ -578,14 +577,12 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
forwardelement = 0;
}
if (SwigType_isqualifier(element)) {
if (!member_const_function) {
if (!member_function_qualifiers) {
DOH *q = 0;
q = SwigType_parm(element);
Insert(result, 0, " ");
Insert(result, 0, q);
Delete(q);
} else {
member_const_function = 0;
}
} else if (SwigType_ispointer(element)) {
Insert(result, 0, "*");
@ -602,19 +599,27 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
Insert(result, 0, "(");
Append(result, ")");
}
if (SwigType_isqualifier(nextelement)) {
member_const_function_element = nextelement;
member_const_function = 1;
{
String *next3elements = NewStringEmpty();
int j;
for (j = i + 1; j < i + 4 && j < nelements; j++) {
Append(next3elements, Getitem(elements, j));
}
if (SwigType_isfunction(next3elements))
member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
Delete(next3elements);
}
Delete(q);
} else if (SwigType_isreference(element)) {
Insert(result, 0, "&");
if (!member_function_qualifiers)
Insert(result, 0, "&");
if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
Insert(result, 0, "(");
Append(result, ")");
}
} else if (SwigType_isrvalue_reference(element)) {
Insert(result, 0, "&&");
if (!member_function_qualifiers)
Insert(result, 0, "&&");
if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
Insert(result, 0, "(");
Append(result, ")");
@ -639,12 +644,13 @@ String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
Append(result, ",");
}
Append(result, ")");
if (member_const_function_element) {
String *p = SwigType_str(member_const_function_element, 0);
if (member_function_qualifiers) {
String *p = SwigType_str(member_function_qualifiers, 0);
Append(result, " ");
Append(result, p);
Delete(p);
member_const_function_element = 0;
Delete(member_function_qualifiers);
member_function_qualifiers = 0;
}
Delete(parms);
} else {
@ -678,7 +684,7 @@ SwigType *SwigType_ltype(const SwigType *s) {
int nelements, i;
int firstarray = 1;
int notypeconv = 0;
int memberpointer = 0;
int ignore_member_function_qualifiers = 0;
result = NewStringEmpty();
tc = Copy(s);
@ -705,6 +711,7 @@ SwigType *SwigType_ltype(const SwigType *s) {
tc = td;
}
}
elements = SwigType_split(tc);
nelements = Len(elements);
@ -714,18 +721,34 @@ SwigType *SwigType_ltype(const SwigType *s) {
/* when we see a function, we need to preserve the following types */
if (SwigType_isfunction(element)) {
notypeconv = 1;
ignore_member_function_qualifiers = 0;
}
if (SwigType_isqualifier(element)) {
if (memberpointer)
Append(result, element);
/* otherwise ignore */
if (ignore_member_function_qualifiers) {
/* cv-qualifiers and ref-qualifiers up until the f() element have already been added */
} else if (SwigType_isqualifier(element)) {
/* swallow cv-qualifiers */
} else if (SwigType_ispointer(element)) {
Append(result, element);
firstarray = 0;
} else if (SwigType_ismemberpointer(element)) {
Append(result, element);
{
String *next3elements = NewStringEmpty();
int j;
for (j = i + 1; j < i + 4 && j < nelements; j++) {
Append(next3elements, Getitem(elements, j));
}
if (SwigType_isfunction(next3elements)) {
SwigType *member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
/* compilers won't let us cast from a member function without qualifiers to one with qualifiers, so the qualifiers are kept in the ltype */
if (member_function_qualifiers)
Append(result, member_function_qualifiers);
Delete(member_function_qualifiers);
ignore_member_function_qualifiers = 1;
}
Delete(next3elements);
}
firstarray = 0;
memberpointer = 1;
} else if (SwigType_isreference(element)) {
if (notypeconv) {
Append(result, element);
@ -764,13 +787,14 @@ SwigType *SwigType_ltype(const SwigType *s) {
}
/* -----------------------------------------------------------------------------
* SwigType_lstr(DOH *s, DOH *id)
* SwigType_lstr()
*
* Produces a type-string that is suitable as a lvalue in an expression.
* That is, a type that can be freely assigned a value without violating
* any C assignment rules.
*
* - Qualifiers such as 'const' and 'volatile' are stripped.
* Except for member function cv-qualifiers and ref-qualifiers.
* - Arrays are converted into a *single* pointer (i.e.,
* double [][] becomes double *).
* - References are converted into a pointer.
@ -800,7 +824,7 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
String *element = 0;
String *nextelement;
String *forwardelement;
String *member_const_function_element = 0;
String *member_function_qualifiers = 0;
SwigType *td, *tc = 0;
const SwigType *rs;
List *elements;
@ -809,7 +833,6 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
int firstarray = 1;
int isreference = 0;
int isfunction = 0;
int member_const_function = 0;
result = NewStringEmpty();
@ -858,15 +881,13 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
forwardelement = 0;
}
if (SwigType_isqualifier(element)) {
if (!member_const_function) {
if (!member_function_qualifiers) {
DOH *q = 0;
q = SwigType_parm(element);
Insert(result, 0, " ");
Insert(result, 0, q);
Delete(q);
clear = 0;
} else {
member_const_function = 0;
}
} else if (SwigType_ispointer(element)) {
Insert(result, 0, "*");
@ -880,32 +901,42 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
Insert(result, 0, "::*");
q = SwigType_parm(element);
Insert(result, 0, q);
Delete(q);
if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
Insert(result, 0, "(");
Append(result, ")");
}
if (SwigType_isqualifier(nextelement)) {
member_const_function_element = nextelement;
member_const_function = 1;
{
String *next3elements = NewStringEmpty();
int j;
for (j = i + 1; j < i + 4 && j < nelements; j++) {
Append(next3elements, Getitem(elements, j));
}
if (SwigType_isfunction(next3elements))
member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements);
Delete(next3elements);
}
firstarray = 0;
Delete(q);
} else if (SwigType_isreference(element)) {
Insert(result, 0, "&");
if (!member_function_qualifiers) {
Insert(result, 0, "&");
if (!isfunction)
isreference = 1;
}
if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
Insert(result, 0, "(");
Append(result, ")");
}
if (!isfunction)
isreference = 1;
} else if (SwigType_isrvalue_reference(element)) {
Insert(result, 0, "&&");
if (!member_function_qualifiers) {
Insert(result, 0, "&&");
if (!isfunction)
isreference = 1;
}
if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
Insert(result, 0, "(");
Append(result, ")");
}
if (!isfunction)
isreference = 1;
clear = 0;
} else if (SwigType_isarray(element)) {
DOH *size;
@ -935,12 +966,13 @@ String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
}
Append(result, ")");
Delete(parms);
if (member_const_function_element) {
String *p = SwigType_str(member_const_function_element, 0);
if (member_function_qualifiers) {
String *p = SwigType_str(member_function_qualifiers, 0);
Append(result, " ");
Append(result, p);
Delete(p);
member_const_function_element = 0;
Delete(member_function_qualifiers);
member_function_qualifiers = 0;
clear = 0;
}
isfunction = 1;