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:
parent
eeab152901
commit
1cf599bccb
11 changed files with 265 additions and 52 deletions
|
|
@ -1,16 +1,76 @@
|
||||||
%module cpp11_ref_qualifiers
|
%module cpp11_ref_qualifiers
|
||||||
|
|
||||||
%inline %{
|
%include <std_string.i>
|
||||||
class Host {
|
|
||||||
public:
|
|
||||||
void h1() & {}
|
|
||||||
void h2() const & {}
|
|
||||||
void h3() && {}
|
|
||||||
void h4() const && {}
|
|
||||||
|
|
||||||
void h() & {}
|
%ignore Host::h() const &;
|
||||||
void h() const & {}
|
|
||||||
void h() && {}
|
// Basic testing
|
||||||
void h() const && {}
|
%inline %{
|
||||||
|
using std::string;
|
||||||
|
class Host {
|
||||||
|
string s;
|
||||||
|
public:
|
||||||
|
string h1() & { return string(); }
|
||||||
|
string h2() const & { return string(); }
|
||||||
|
string h3() && { return std::move(string()); }
|
||||||
|
string h4() const && { return std::move(string()); }
|
||||||
|
string h5() const { return string(); }
|
||||||
|
string h6() volatile const & { return string(); }
|
||||||
|
string h7() const volatile & { return string(); }
|
||||||
|
string h8() volatile const && { return std::move(string()); }
|
||||||
|
string h9() const volatile && { return std::move(string()); }
|
||||||
|
|
||||||
|
string h() & { return string(); }
|
||||||
|
string h() const & { return string(); }
|
||||||
|
string h() && { return std::move(string()); }
|
||||||
|
string h() const && { return std::move(string()); }
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
// %feature testing
|
||||||
|
%feature("except") F1() & %{ result = "F1"; %}
|
||||||
|
%feature("except") F2 %{ result = "F2"; %}
|
||||||
|
%feature("except") F3 %{ result = "F3"; %}
|
||||||
|
%feature("except") F3() %{ _should_not_be_used_ %}
|
||||||
|
|
||||||
|
%feature("except") C1(int i) const & %{ result = "C1"; %}
|
||||||
|
%feature("except") C2 %{ result = "C2"; %}
|
||||||
|
%feature("except") C3 %{ result = "C3"; %}
|
||||||
|
%feature("except") C3(int i) %{ _should_not_be_used_ %}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct Features {
|
||||||
|
string F1() & { return string(); }
|
||||||
|
string F2() & { return string(); }
|
||||||
|
string F3() & { return string(); }
|
||||||
|
|
||||||
|
string C1(int i) const & { return string(); }
|
||||||
|
string C2(int i) const & { return string(); }
|
||||||
|
string C3(int i) const & { return string(); }
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
// %rename testing
|
||||||
|
%rename(RR1) R1;
|
||||||
|
%rename(RR2) R2() &;
|
||||||
|
%rename(RR3) R3;
|
||||||
|
%rename(RR3Bad) R3();
|
||||||
|
|
||||||
|
%rename(SS1) S1;
|
||||||
|
%rename(SS2) S2(int i) const &;
|
||||||
|
%rename(SS3) S3;
|
||||||
|
%rename(SS3Bad) S3(int i);
|
||||||
|
%rename(SS3BadConst) S3(int i) const;
|
||||||
|
%rename(SS3BadLValue) S3(int i) &;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct Renames {
|
||||||
|
string R1() & { return string(); }
|
||||||
|
string R2() & { return string(); }
|
||||||
|
string R3() & { return string(); }
|
||||||
|
|
||||||
|
string S1(int i) const & { return string(); }
|
||||||
|
string S2(int i) const & { return string(); }
|
||||||
|
string S3(int i) const & { return string(); }
|
||||||
};
|
};
|
||||||
%}
|
%}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
%module cpp_refqualifier
|
%module cpp_refqualifier
|
||||||
|
|
||||||
%ignore Host::h_ignored;
|
%ignore Host::h_ignored;
|
||||||
|
%ignore Host::i_ignored() &&;
|
||||||
|
%ignore Host::j_ignored() const &&;
|
||||||
|
|
||||||
class Host {
|
class Host {
|
||||||
public:
|
public:
|
||||||
|
|
@ -15,4 +17,6 @@ public:
|
||||||
void h() const &&;
|
void h() const &&;
|
||||||
|
|
||||||
void h_ignored() &&;
|
void h_ignored() &&;
|
||||||
|
void i_ignored() &&;
|
||||||
|
void j_ignored() const &&;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
cpp_refqualifier.i:9: Warning 405: Method with rvalue ref-qualifier ignored h3() &&.
|
cpp_refqualifier.i:11: Warning 405: Method with rvalue ref-qualifier h3() && ignored.
|
||||||
cpp_refqualifier.i:10: Warning 405: Method with rvalue ref-qualifier ignored h4() const &&.
|
cpp_refqualifier.i:12: Warning 405: Method with rvalue ref-qualifier h4() const && ignored.
|
||||||
cpp_refqualifier.i:14: Warning 405: Method with rvalue ref-qualifier ignored h() &&.
|
cpp_refqualifier.i:16: Warning 405: Method with rvalue ref-qualifier h() && ignored.
|
||||||
cpp_refqualifier.i:15: Warning 405: Method with rvalue ref-qualifier ignored h() const &&.
|
cpp_refqualifier.i:17: Warning 405: Method with rvalue ref-qualifier h() const && ignored.
|
||||||
cpp_refqualifier.i:13: Warning 512: Overloaded method Host::h() const & ignored,
|
cpp_refqualifier.i:15: Warning 512: Overloaded method Host::h() const & ignored,
|
||||||
cpp_refqualifier.i:12: Warning 512: using non-const method Host::h() & instead.
|
cpp_refqualifier.i:14: Warning 512: using non-const method Host::h() & instead.
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,34 @@ public class cpp11_ref_qualifiers_runme {
|
||||||
|
|
||||||
public static void main(String argv[]) {
|
public static void main(String argv[]) {
|
||||||
Host h = new Host();
|
Host h = new Host();
|
||||||
|
|
||||||
|
// Basic testing
|
||||||
h.h1();
|
h.h1();
|
||||||
h.h2();
|
h.h2();
|
||||||
|
h.h6();
|
||||||
|
h.h7();
|
||||||
|
|
||||||
h.h();
|
h.h();
|
||||||
|
|
||||||
|
// %feature testing
|
||||||
|
Features f = new Features();
|
||||||
|
if (!f.F1().equals("F1")) throw new RuntimeException("Fail");
|
||||||
|
if (!f.F2().equals("F2")) throw new RuntimeException("Fail");
|
||||||
|
if (!f.F3().equals("F3")) throw new RuntimeException("Fail");
|
||||||
|
|
||||||
|
if (!f.C1(0).equals("C1")) throw new RuntimeException("Fail");
|
||||||
|
if (!f.C2(0).equals("C2")) throw new RuntimeException("Fail");
|
||||||
|
if (!f.C3(0).equals("C3")) throw new RuntimeException("Fail");
|
||||||
|
|
||||||
|
// %rename testing
|
||||||
|
Renames r = new Renames();
|
||||||
|
r.RR1();
|
||||||
|
r.RR2();
|
||||||
|
r.RR3();
|
||||||
|
|
||||||
|
r.SS1(0);
|
||||||
|
r.SS2(0);
|
||||||
|
r.SS3(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,37 @@
|
||||||
import cpp11_ref_qualifiers
|
import cpp11_ref_qualifiers
|
||||||
|
|
||||||
h = cpp11_ref_qualifiers.Host()
|
h = cpp11_ref_qualifiers.Host()
|
||||||
|
|
||||||
|
# Basic testing
|
||||||
h.h1()
|
h.h1()
|
||||||
h.h2()
|
h.h2()
|
||||||
|
h.h6()
|
||||||
|
h.h7()
|
||||||
|
|
||||||
h.h()
|
h.h()
|
||||||
|
|
||||||
|
# %feature testing
|
||||||
|
f = cpp11_ref_qualifiers.Features()
|
||||||
|
if f.F1() != "F1":
|
||||||
|
raise RuntimeException("Fail")
|
||||||
|
if f.F2() != "F2":
|
||||||
|
raise RuntimeException("Fail")
|
||||||
|
if f.F3() != "F3":
|
||||||
|
raise RuntimeException("Fail")
|
||||||
|
|
||||||
|
if f.C1(0) != "C1":
|
||||||
|
raise RuntimeException("Fail")
|
||||||
|
if f.C2(0) != "C2":
|
||||||
|
raise RuntimeException("Fail")
|
||||||
|
if f.C3(0) != "C3":
|
||||||
|
raise RuntimeException("Fail")
|
||||||
|
|
||||||
|
# %rename testing
|
||||||
|
r = cpp11_ref_qualifiers.Renames()
|
||||||
|
r.RR1()
|
||||||
|
r.RR2()
|
||||||
|
r.RR3()
|
||||||
|
|
||||||
|
r.SS1(0)
|
||||||
|
r.SS2(0)
|
||||||
|
r.SS3(0)
|
||||||
|
|
|
||||||
|
|
@ -487,16 +487,16 @@ static void add_symbols(Node *n) {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
String *refqualifier = Getattr(n, "refqualifier");
|
String *refqualifier = Getattr(n, "refqualifier");
|
||||||
if (SwigType_isrvalue_reference(refqualifier) && strncmp(Char(symname), "$ignore", 7) != 0) {
|
if (SwigType_isrvalue_reference(refqualifier) && Strcmp(symname, "$ignore") != 0) {
|
||||||
SWIG_WARN_NODE_BEGIN(n);
|
SWIG_WARN_NODE_BEGIN(n);
|
||||||
Swig_warning(WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED, Getfile(n), Getline(n),
|
Swig_warning(WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED, Getfile(n), Getline(n),
|
||||||
"Method with rvalue ref-qualifier ignored %s.\n", Swig_name_decl(n));
|
"Method with rvalue ref-qualifier %s ignored.\n", Swig_name_decl(n));
|
||||||
SWIG_WARN_NODE_END(n);
|
SWIG_WARN_NODE_END(n);
|
||||||
SetFlag(n, "feature:ignore");
|
SetFlag(n, "feature:ignore");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (only_csymbol || GetFlag(n,"feature:ignore") || strncmp(Char(symname),"$ignore",7) == 0) {
|
if (only_csymbol || GetFlag(n, "feature:ignore") || Strncmp(symname, "$ignore", 7) == 0) {
|
||||||
/* Only add to C symbol table and continue */
|
/* Only add to C symbol table and continue */
|
||||||
Swig_symbol_add(0, n);
|
Swig_symbol_add(0, n);
|
||||||
if (!only_csymbol && !GetFlag(n, "feature:ignore")) {
|
if (!only_csymbol && !GetFlag(n, "feature:ignore")) {
|
||||||
|
|
@ -1421,10 +1421,12 @@ static void mark_nodes_as_extend(Node *n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* add_qualifier_to_declarator
|
* add_qualifier_to_declarator()
|
||||||
*
|
*
|
||||||
|
* Normally the qualifier is pushed on to the front of the type.
|
||||||
* Adding a qualifier to a pointer to member function is a special case.
|
* Adding a qualifier to a pointer to member function is a special case.
|
||||||
* For example : typedef double (Cls::*pmf)(void) const;
|
* For example : typedef double (Cls::*pmf)(void) const;
|
||||||
|
* The qualifier is : q(const).
|
||||||
* The declarator is : m(Cls).f(void).
|
* The declarator is : m(Cls).f(void).
|
||||||
* We need : m(Cls).q(const).f(void).
|
* We need : m(Cls).q(const).f(void).
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
@ -5875,10 +5877,12 @@ cv_ref_qualifier : type_qualifier {
|
||||||
| type_qualifier ref_qualifier {
|
| type_qualifier ref_qualifier {
|
||||||
$$.qualifier = $1;
|
$$.qualifier = $1;
|
||||||
$$.refqualifier = $2;
|
$$.refqualifier = $2;
|
||||||
|
SwigType_push($$.qualifier, $2);
|
||||||
}
|
}
|
||||||
| ref_qualifier {
|
| ref_qualifier {
|
||||||
$$.qualifier = 0;
|
$$.qualifier = NewStringEmpty();
|
||||||
$$.refqualifier = $1;
|
$$.refqualifier = $1;
|
||||||
|
SwigType_push($$.qualifier, $1);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -231,9 +231,21 @@ List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
|
||||||
}
|
}
|
||||||
if (!differ) {
|
if (!differ) {
|
||||||
/* See if declarations differ by const only */
|
/* See if declarations differ by const only */
|
||||||
String *d1 = Getattr(nodes[i].n, "decl");
|
String *decl1 = Getattr(nodes[i].n, "decl");
|
||||||
String *d2 = Getattr(nodes[j].n, "decl");
|
String *decl2 = Getattr(nodes[j].n, "decl");
|
||||||
if (d1 && d2) {
|
if (decl1 && decl2) {
|
||||||
|
/* Remove ref-qualifiers. Note that rvalue ref-qualifiers are already ignored and
|
||||||
|
* it is illegal to overload a function with and without ref-qualifiers. So with
|
||||||
|
* all the combinations of ref-qualifiers and cv-qualifiers, we just detect
|
||||||
|
* the cv-qualifier (const) overloading. */
|
||||||
|
String *d1 = Copy(decl1);
|
||||||
|
String *d2 = Copy(decl2);
|
||||||
|
if (SwigType_isreference(d1) || SwigType_isrvalue_reference(d1)) {
|
||||||
|
Delete(SwigType_pop(d1));
|
||||||
|
}
|
||||||
|
if (SwigType_isreference(d2) || SwigType_isrvalue_reference(d2)) {
|
||||||
|
Delete(SwigType_pop(d2));
|
||||||
|
}
|
||||||
String *dq1 = Copy(d1);
|
String *dq1 = Copy(d1);
|
||||||
String *dq2 = Copy(d2);
|
String *dq2 = Copy(d2);
|
||||||
if (SwigType_isconst(d1)) {
|
if (SwigType_isconst(d1)) {
|
||||||
|
|
|
||||||
|
|
@ -1689,18 +1689,23 @@ String *Swig_name_str(Node *n) {
|
||||||
String *Swig_name_decl(Node *n) {
|
String *Swig_name_decl(Node *n) {
|
||||||
String *qname;
|
String *qname;
|
||||||
String *decl;
|
String *decl;
|
||||||
String *refqualifier = Getattr(n, "refqualifier");
|
|
||||||
|
|
||||||
qname = Swig_name_str(n);
|
qname = Swig_name_str(n);
|
||||||
|
|
||||||
if (checkAttribute(n, "kind", "variable"))
|
|
||||||
decl = NewStringf("%s", qname);
|
decl = NewStringf("%s", qname);
|
||||||
else
|
|
||||||
decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : "");
|
if (!checkAttribute(n, "kind", "variable")) {
|
||||||
if (refqualifier) {
|
String *d = Getattr(n, "decl");
|
||||||
String *rq = SwigType_str(refqualifier, 0);
|
Printv(decl, "(", ParmList_errorstr(Getattr(n, "parms")), ")", NIL);
|
||||||
Printv(decl, " ", rq, NIL);
|
if (SwigType_isfunction(d)) {
|
||||||
Delete(rq);
|
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);
|
Delete(qname);
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
* 'z.' = Rvalue reference (&&)
|
* 'z.' = Rvalue reference (&&)
|
||||||
* 'a(n).' = Array of size n [n]
|
* 'a(n).' = Array of size n [n]
|
||||||
* 'f(..,..).' = Function with arguments (args)
|
* '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::*)
|
* 'm(cls).' = Pointer to member (cls::*)
|
||||||
*
|
*
|
||||||
* The encoding follows the order that you might describe a type in words.
|
* The encoding follows the order that you might describe a type in words.
|
||||||
|
|
@ -66,9 +66,17 @@
|
||||||
*
|
*
|
||||||
* String Encoding C++ Example
|
* String Encoding C++ Example
|
||||||
* --------------- -----------
|
* --------------- -----------
|
||||||
* p.f(bool).q(const).long const long (*)(bool)
|
* p.f(bool).r.q(const).long const long & (*)(bool)
|
||||||
* m(Funcs).q(const).f(bool).long long (Funcs::*)(bool) const
|
* m(Funcs).q(const).f(bool).long long (Funcs::*)(bool) const
|
||||||
* r.q(const).m(Funcs).f(int).long long (Funcs::*const &)(int)
|
* 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
|
* For the most part, this module tries to minimize the use of special
|
||||||
* characters (*, [, <, etc...) in its type encoding. One reason for this
|
* characters (*, [, <, etc...) in its type encoding. One reason for this
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@ extern "C" {
|
||||||
extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms);
|
extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms);
|
||||||
extern SwigType *SwigType_add_template(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(SwigType *t);
|
||||||
|
extern SwigType *SwigType_pop_function_qualifiers(SwigType *t);
|
||||||
extern ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node);
|
extern ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node);
|
||||||
extern List *SwigType_split(const SwigType *t);
|
extern List *SwigType_split(const SwigType *t);
|
||||||
extern String *SwigType_pop(SwigType *t);
|
extern String *SwigType_pop(SwigType *t);
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,11 @@
|
||||||
* All type constructors are denoted by a trailing '.':
|
* All type constructors are denoted by a trailing '.':
|
||||||
*
|
*
|
||||||
* 'p.' = Pointer (*)
|
* 'p.' = Pointer (*)
|
||||||
* 'r.' = Reference (&)
|
* 'r.' = Reference or ref-qualifier (&)
|
||||||
* 'z.' = Rvalue reference (&&)
|
* 'z.' = Rvalue reference or ref-qualifier (&&)
|
||||||
* 'a(n).' = Array of size n [n]
|
* 'a(n).' = Array of size n [n]
|
||||||
* 'f(..,..).' = Function with arguments (args)
|
* '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::*)
|
* 'm(cls).' = Pointer to member (cls::*)
|
||||||
*
|
*
|
||||||
* The complete type representation for varargs is:
|
* The complete type representation for varargs is:
|
||||||
|
|
@ -183,7 +183,8 @@ SwigType *SwigType_del_element(SwigType *t) {
|
||||||
* SwigType_pop()
|
* SwigType_pop()
|
||||||
*
|
*
|
||||||
* Pop one type element off the type.
|
* Pop one type element off the type.
|
||||||
* Example: t in: q(const).p.Integer
|
* For example:
|
||||||
|
* t in: q(const).p.Integer
|
||||||
* t out: p.Integer
|
* t out: p.Integer
|
||||||
* result: q(const).
|
* result: q(const).
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
@ -771,7 +772,6 @@ SwigType *SwigType_array_type(const SwigType *ty) {
|
||||||
* Functions
|
* Functions
|
||||||
*
|
*
|
||||||
* SwigType_add_function()
|
* SwigType_add_function()
|
||||||
* SwigType_del_function()
|
|
||||||
* SwigType_isfunction()
|
* SwigType_isfunction()
|
||||||
* SwigType_pop_function()
|
* SwigType_pop_function()
|
||||||
*
|
*
|
||||||
|
|
@ -795,14 +795,36 @@ SwigType *SwigType_add_function(SwigType *t, ParmList *parms) {
|
||||||
return t;
|
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 *SwigType_pop_function(SwigType *t) {
|
||||||
SwigType *f = 0;
|
SwigType *f = 0;
|
||||||
SwigType *g = 0;
|
SwigType *g = 0;
|
||||||
char *c = Char(t);
|
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);
|
f = SwigType_pop(t);
|
||||||
c = Char(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)) {
|
if (strncmp(c, "f(", 2)) {
|
||||||
printf("Fatal error. SwigType_pop_function applied to non-function.\n");
|
printf("Fatal error. SwigType_pop_function applied to non-function.\n");
|
||||||
abort();
|
abort();
|
||||||
|
|
@ -814,14 +836,55 @@ SwigType *SwigType_pop_function(SwigType *t) {
|
||||||
return g;
|
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) {
|
int SwigType_isfunction(const SwigType *t) {
|
||||||
char *c;
|
char *c;
|
||||||
if (!t) {
|
if (!t) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
c = Char(t);
|
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) {
|
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, '.');
|
c = strchr(c, '.');
|
||||||
if (c)
|
if (c)
|
||||||
c++;
|
c++;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue