Merge branch 'director-unwrap-result'

* director-unwrap-result:
  Unwrap director classes only when returning a pointer or reference to an object
This commit is contained in:
William S Fulton 2022-10-07 18:41:14 +01:00
commit 4a397869a2
9 changed files with 369 additions and 6 deletions

View file

@ -234,6 +234,95 @@ static void cparse_template_expand(Node *templnode, Node *n, String *tname, Stri
}
}
/* -----------------------------------------------------------------------------
* cparse_fix_function_decl()
*
* Move the prefix of the "type" attribute (excluding any trailing qualifier)
* to the end of the "decl" attribute.
* Examples:
* decl="f().", type="p.q(const).char" => decl="f().p.", type="q(const).char"
* decl="f().p.", type="p.SomeClass" => decl="f().p.p.", type="SomeClass"
* decl="f().", type="r.q(const).p.int" => decl="f().r.q(const).p.", type="int"
* ----------------------------------------------------------------------------- */
static void cparse_fix_function_decl(String *name, SwigType *decl, SwigType *type) {
String *prefix;
int prefixLen;
SwigType* last;
/* The type's prefix is what potentially has to be moved to the end of 'decl' */
prefix = SwigType_prefix(type);
/* First some parts (qualifier and array) have to be removed from prefix
in order to remain in the 'type' attribute. */
last = SwigType_last(prefix);
while (last) {
if (SwigType_isqualifier(last) || SwigType_isarray(last)) {
/* Keep this part in the 'type' */
Delslice(prefix, Len(prefix) - Len(last), DOH_END);
Delete(last);
last = SwigType_last(prefix);
} else {
/* Done with processing prefix */
Delete(last);
last = 0;
}
}
/* Transfer prefix from the 'type' to the 'decl' attribute */
prefixLen = Len(prefix);
if (prefixLen > 0) {
Append(decl, prefix);
Delslice(type, 0, prefixLen);
if (template_debug) {
Printf(stdout, " change function '%s' to type='%s', decl='%s'\n",
name, type, decl);
}
}
Delete(prefix);
}
/* -----------------------------------------------------------------------------
* cparse_postprocess_expanded_template()
*
* This function postprocesses the given node after template expansion.
* Currently the only task to perform is fixing function decl and type attributes.
* ----------------------------------------------------------------------------- */
static void cparse_postprocess_expanded_template(Node *n) {
String *nodeType;
if (!n)
return;
nodeType = nodeType(n);
if (Getattr(n, "error"))
return;
if (Equal(nodeType, "cdecl")) {
/* A simple C declaration */
SwigType *d = Getattr(n, "decl");
if (d && SwigType_isfunction(d)) {
/* A function node */
SwigType *t = Getattr(n, "type");
if (t) {
String *name = Getattr(n, "name");
cparse_fix_function_decl(name, d, t);
}
}
} else {
/* Look for any children */
Node *cn = firstChild(n);
while (cn) {
cparse_postprocess_expanded_template(cn);
cn = nextSibling(cn);
}
}
}
/* -----------------------------------------------------------------------------
* partial_arg()
* ----------------------------------------------------------------------------- */
static
String *partial_arg(String *s, String *p) {
char *c;
@ -422,6 +511,8 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab
}
}
cparse_postprocess_expanded_template(n);
/* Patch bases */
{
List *bases = Getattr(n, "baselist");

View file

@ -3159,9 +3159,7 @@ public:
#if 1
int unwrap = 0;
String *decl = Getattr(n, "decl");
int is_pointer = SwigType_ispointer_return(decl);
int is_reference = SwigType_isreference_return(decl);
if (is_pointer || is_reference) {
if (SwigType_refptr_count_return(decl) == 1) {
String *type = Getattr(n, "type");
//Node *classNode = Swig_methodclass(n);
//Node *module = Getattr(classNode, "module");

View file

@ -1880,9 +1880,7 @@ public:
*/
bool unwrap = false;
String *decl = Getattr(n, "decl");
int is_pointer = SwigType_ispointer_return(decl);
int is_reference = SwigType_isreference_return(decl);
if (is_pointer || is_reference) {
if (SwigType_refptr_count_return(decl) == 1) {
String *type = Getattr(n, "type");
Node *parent = Swig_methodclass(n);
Node *modname = Getattr(parent, "module");

View file

@ -139,6 +139,8 @@ extern "C" {
extern List *SwigType_split(const SwigType *t);
extern String *SwigType_pop(SwigType *t);
extern void SwigType_push(SwigType *t, String *s);
extern SwigType *SwigType_last(SwigType *t);
extern int SwigType_refptr_count_return(const SwigType *t);
extern List *SwigType_parmlist(const SwigType *p);
extern String *SwigType_parm(const SwigType *p);
extern String *SwigType_str(const SwigType *s, const_String_or_char_ptr id);

View file

@ -208,6 +208,90 @@ SwigType *SwigType_pop(SwigType *t) {
return result;
}
/* -----------------------------------------------------------------------------
* SwigType_last()
*
* Return the last element of the given (partial) type.
* For example:
* t: q(const).p.
* result: p.
* ----------------------------------------------------------------------------- */
SwigType *SwigType_last(SwigType *t) {
SwigType *result;
char *c;
char *last;
int sz = 0;
if (!t)
return 0;
/* Find the last element */
c = Char(t);
last = 0;
while (*c) {
last = c;
sz = element_size(c);
c = c + sz;
if (*c == '.') {
c++;
sz++;
}
}
/* Extract the last element */
if (last) {
result = NewStringWithSize(last, sz);
} else {
result = 0;
}
return result;
}
/* -----------------------------------------------------------------------------
* SwigType_refptr_count_return()
*
* Returns the number of pointer and reference indirections found in the given
* type. For functions this concerns the return type.
* For example:
* r.p. => 2
* q(const).p. => 1
* r.f(int).p.p. => 2
* f().p.q(const).p. => 2
* ----------------------------------------------------------------------------- */
int SwigType_refptr_count_return(const SwigType *t) {
char *c;
char *last;
int sz;
int result = 0;
if (!t)
return 0;
c = Char(t);
last = c;
while (*c) {
last = c;
sz = element_size(c);
c = c + sz;
if (*(c-1) == '.') {
if (((last[0] == 'p') || (last[0] == 'r')) && (last[1] == '.')) {
result++;
} else if (strncmp(last, "f(", 2) == 0) {
/* restart counter if this is a function type */
result = 0;
}
}
if (*c == '.') {
c++;
}
}
return result;
}
/* -----------------------------------------------------------------------------
* SwigType_parm()
*