Improve ref-qualifier implementation

Internally, handle function ref-qualifiers in the function decl type string.
Needed for a whole host of things to work like %feature and %rename.
Add %feature %rename and %ignore testing for ref-qualifiers.
This commit is contained in:
William S Fulton 2017-08-23 09:07:12 +01:00
commit 1cf599bccb
11 changed files with 265 additions and 52 deletions

View file

@ -1689,18 +1689,23 @@ String *Swig_name_str(Node *n) {
String *Swig_name_decl(Node *n) {
String *qname;
String *decl;
String *refqualifier = Getattr(n, "refqualifier");
qname = Swig_name_str(n);
decl = NewStringf("%s", qname);
if (checkAttribute(n, "kind", "variable"))
decl = NewStringf("%s", qname);
else
decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : "");
if (refqualifier) {
String *rq = SwigType_str(refqualifier, 0);
Printv(decl, " ", rq, NIL);
Delete(rq);
if (!checkAttribute(n, "kind", "variable")) {
String *d = Getattr(n, "decl");
Printv(decl, "(", ParmList_errorstr(Getattr(n, "parms")), ")", NIL);
if (SwigType_isfunction(d)) {
SwigType *decl_temp = Copy(d);
SwigType *qualifiers = SwigType_pop_function_qualifiers(decl_temp);
if (qualifiers) {
String *qualifiers_string = SwigType_str(qualifiers, 0);
Printv(decl, " ", qualifiers_string, NIL);
Delete(qualifiers_string);
}
Delete(decl_temp);
}
}
Delete(qname);

View file

@ -44,7 +44,7 @@
* 'z.' = Rvalue reference (&&)
* 'a(n).' = Array of size n [n]
* 'f(..,..).' = Function with arguments (args)
* 'q(str).' = Qualifier (such as const or volatile) (const, volatile)
* 'q(str).' = Qualifier, such as const or volatile (cv-qualifier)
* 'm(cls).' = Pointer to member (cls::*)
*
* The encoding follows the order that you might describe a type in words.
@ -64,11 +64,19 @@
*
* More examples:
*
* String Encoding C++ Example
* --------------- -----------
* p.f(bool).q(const).long const long (*)(bool)
* m(Funcs).q(const).f(bool).long long (Funcs::*)(bool) const
* r.q(const).m(Funcs).f(int).long long (Funcs::*const &)(int)
* String Encoding C++ Example
* --------------- -----------
* p.f(bool).r.q(const).long const long & (*)(bool)
* m(Funcs).q(const).f(bool).long long (Funcs::*)(bool) const
* r.q(const).m(Funcs).f(int).long long (Funcs::*const &)(int)
* m(Funcs).z.q(const).f(bool).long long (Funcs::*)(bool) const &&
*
* Function decl examples:
*
* f(bool). long a(bool);
* r.f(bool). long b(bool) &;
* z.f(bool). long c(bool) &&;
* z.q(const).f(bool). long d(bool) const &&;
*
* For the most part, this module tries to minimize the use of special
* characters (*, [, <, etc...) in its type encoding. One reason for this

View file

@ -136,6 +136,7 @@ extern "C" {
extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms);
extern SwigType *SwigType_add_template(SwigType *t, ParmList *parms);
extern SwigType *SwigType_pop_function(SwigType *t);
extern SwigType *SwigType_pop_function_qualifiers(SwigType *t);
extern ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node);
extern List *SwigType_split(const SwigType *t);
extern String *SwigType_pop(SwigType *t);

View file

@ -43,11 +43,11 @@
* All type constructors are denoted by a trailing '.':
*
* 'p.' = Pointer (*)
* 'r.' = Reference (&)
* 'z.' = Rvalue reference (&&)
* 'r.' = Reference or ref-qualifier (&)
* 'z.' = Rvalue reference or ref-qualifier (&&)
* 'a(n).' = Array of size n [n]
* 'f(..,..).' = Function with arguments (args)
* 'q(str).' = Qualifier (such as const or volatile) (const, volatile)
* 'q(str).' = Qualifier, such as const or volatile (cv-qualifier)
* 'm(cls).' = Pointer to member (cls::*)
*
* The complete type representation for varargs is:
@ -183,9 +183,10 @@ 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).
* For example:
* t in: q(const).p.Integer
* t out: p.Integer
* result: q(const).
* ----------------------------------------------------------------------------- */
SwigType *SwigType_pop(SwigType *t) {
@ -771,7 +772,6 @@ SwigType *SwigType_array_type(const SwigType *ty) {
* Functions
*
* SwigType_add_function()
* SwigType_del_function()
* SwigType_isfunction()
* SwigType_pop_function()
*
@ -795,14 +795,36 @@ SwigType *SwigType_add_function(SwigType *t, ParmList *parms) {
return t;
}
/* -----------------------------------------------------------------------------
* SwigType_pop_function()
*
* Pop and return the function from the input type leaving the function's return
* type, if any.
* For example:
* t in: q(const).f().p.
* t out: p.
* result: q(const).f().
* ----------------------------------------------------------------------------- */
SwigType *SwigType_pop_function(SwigType *t) {
SwigType *f = 0;
SwigType *g = 0;
char *c = Char(t);
if (strncmp(c, "q(", 2) == 0) {
if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
/* Remove ref-qualifier */
f = SwigType_pop(t);
c = Char(t);
}
if (strncmp(c, "q(", 2) == 0) {
/* Remove cv-qualifier */
String *qual = SwigType_pop(t);
if (f) {
SwigType_push(qual, f);
Delete(f);
}
f = qual;
c = Char(t);
}
if (strncmp(c, "f(", 2)) {
printf("Fatal error. SwigType_pop_function applied to non-function.\n");
abort();
@ -814,14 +836,55 @@ SwigType *SwigType_pop_function(SwigType *t) {
return g;
}
/* -----------------------------------------------------------------------------
* SwigType_pop_function_qualifiers()
*
* Pop and return the function qualifiers from the input type leaving the rest of
* function declaration. Returns NULL if no qualifiers.
* For example:
* t in: r.q(const).f().p.
* t out: f().p.
* result: r.q(const)
* ----------------------------------------------------------------------------- */
SwigType *SwigType_pop_function_qualifiers(SwigType *t) {
SwigType *qualifiers = 0;
char *c = Char(t);
if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
/* Remove ref-qualifier */
String *qual = SwigType_pop(t);
qualifiers = qual;
c = Char(t);
}
if (strncmp(c, "q(", 2) == 0) {
/* Remove cv-qualifier */
String *qual = SwigType_pop(t);
if (qualifiers) {
SwigType_push(qual, qualifiers);
Delete(qualifiers);
}
qualifiers = qual;
c = Char(t);
}
assert(strncmp(c, "f(", 2) == 0);
return qualifiers;
}
int SwigType_isfunction(const SwigType *t) {
char *c;
if (!t) {
return 0;
}
c = Char(t);
if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) {
/* Might be a function with a ref-qualifier, skip over */
c += 2;
if (!*c)
return 0;
}
if (strncmp(c, "q(", 2) == 0) {
/* Might be a 'const' function. Try to skip over the 'const' */
/* Might be a function with a cv-qualifier, skip over */
c = strchr(c, '.');
if (c)
c++;