mirror of https://github.com/swig/swig
Fix missing constructor generation due to abstract class test failure
when a method is declared in the class along with a using declaration and the using declaration is declared before the method that implemented the pure virtual method, such as: struct ConcreteDerived : AbstractBase { ConcreteDerived() {} // was not wrapped using AbstractBase::f; virtual void f(int n) override {} }; SourceForge bug: https://sourceforge.net/p/swig/bugs/932/ check_implemented in allocate.cxx was correctly finding a non-abstract method, however, Swig_symbol_clookup_local_check, was using the using declaration node instead of using the node returned by check_implemented. The checkfunc is now given more control by returning the node to use rather than Swig_symbol_clookup_local_check always using the head of the csym linked list.
This commit is contained in:
parent
34e25241e7
commit
69d5373131
|
@ -7,6 +7,19 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
Version 4.2.0 (in progress)
|
Version 4.2.0 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2023-08-02: wsfulton
|
||||||
|
https://sourceforge.net/p/swig/bugs/932/
|
||||||
|
Fix missing constructor generation due to abstract class test
|
||||||
|
failure when a method is declared in the class along with a
|
||||||
|
using declaration and the using declaration is declared before
|
||||||
|
the method that implemented the pure virtual method, such as:
|
||||||
|
|
||||||
|
struct ConcreteDerived : AbstractBase {
|
||||||
|
ConcreteDerived() {} // was not wrapped
|
||||||
|
using AbstractBase::f;
|
||||||
|
virtual void f(int n) override {}
|
||||||
|
};
|
||||||
|
|
||||||
2023-08-02: olly
|
2023-08-02: olly
|
||||||
[PHP] Implement overloading between different integer types and
|
[PHP] Implement overloading between different integer types and
|
||||||
between double and float.
|
between double and float.
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
%module abstract_inherit_using
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
class AbstractBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void f(int n) = 0;
|
||||||
|
void f(const char *another_representation_of_n) {}
|
||||||
|
virtual ~AbstractBase() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConcreteDerived1 : public AbstractBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConcreteDerived1() {}
|
||||||
|
|
||||||
|
// Abstract test always worked
|
||||||
|
virtual void f(int n) {}
|
||||||
|
using AbstractBase::f;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConcreteDerived2 : public AbstractBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConcreteDerived2() {}
|
||||||
|
|
||||||
|
// SWIG thought this class was abstract when using declaration was before method f and didn't generate constructor
|
||||||
|
using AbstractBase::f;
|
||||||
|
virtual void f(int n) {}
|
||||||
|
};
|
||||||
|
%}
|
|
@ -0,0 +1,24 @@
|
||||||
|
|
||||||
|
import abstract_inherit_using.*;
|
||||||
|
|
||||||
|
public class abstract_inherit_using_runme {
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("abstract_inherit_using");
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String argv[])
|
||||||
|
{
|
||||||
|
ConcreteDerived1 cd1 = new ConcreteDerived1();
|
||||||
|
cd1.f(1234);
|
||||||
|
cd1.f("one");
|
||||||
|
ConcreteDerived2 cd2 = new ConcreteDerived2();
|
||||||
|
cd2.f(1234);
|
||||||
|
cd2.f("one");
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,12 @@
|
||||||
*
|
*
|
||||||
* allocate.cxx
|
* allocate.cxx
|
||||||
*
|
*
|
||||||
* This module tries to figure out which classes and structures support
|
* This module also has two main purposes modifying the parse tree.
|
||||||
|
*
|
||||||
|
* First, it is responsible for adding in using declarations from base class
|
||||||
|
* members into the parse tree.
|
||||||
|
*
|
||||||
|
* Second, after each class declaration, it analyses if the class/struct supports
|
||||||
* default constructors and destructors in C++. There are several rules that
|
* default constructors and destructors in C++. There are several rules that
|
||||||
* define this behavior including pure abstract methods, private sections,
|
* define this behavior including pure abstract methods, private sections,
|
||||||
* and non-default constructors in base classes. See the ARM or
|
* and non-default constructors in base classes. See the ARM or
|
||||||
|
@ -17,9 +22,6 @@
|
||||||
* Once the analysis is complete, the non-explicit/implied default constructors
|
* Once the analysis is complete, the non-explicit/implied default constructors
|
||||||
* and destructors are added to the parse tree. Implied copy constructors are
|
* and destructors are added to the parse tree. Implied copy constructors are
|
||||||
* added too if requested via the copyctor feature.
|
* added too if requested via the copyctor feature.
|
||||||
*
|
|
||||||
* This module also is responsible for adding in using declarations from base
|
|
||||||
* class members into the parse tree.
|
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "swigmod.h"
|
#include "swigmod.h"
|
||||||
|
@ -37,7 +39,7 @@ void Wrapper_virtual_elimination_mode_set(int flag) {
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static String *search_decl = 0; /* Declarator being searched */
|
static String *search_decl = 0; /* Declarator being searched */
|
||||||
static int check_implemented(Node *n) {
|
static Node *check_implemented(Node *n) {
|
||||||
String *decl;
|
String *decl;
|
||||||
if (!n)
|
if (!n)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -51,7 +53,7 @@ extern "C" {
|
||||||
if (!GetFlag(n, "abstract")) {
|
if (!GetFlag(n, "abstract")) {
|
||||||
Delete(decl1);
|
Delete(decl1);
|
||||||
Delete(decl2);
|
Delete(decl2);
|
||||||
return 1;
|
return n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Delete(decl1);
|
Delete(decl1);
|
||||||
|
|
|
@ -105,8 +105,8 @@ static int exportprimitive = 0; // -exportprimitive argument
|
||||||
static String *memberfunction_name = 0;
|
static String *memberfunction_name = 0;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static int has_classname(Node *class_node) {
|
static Node *has_classname(Node *class_node) {
|
||||||
return Getattr(class_node, "guile:goopsclassname") ? 1 : 0;
|
return Getattr(class_node, "guile:goopsclassname") ? class_node : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,8 +732,7 @@ public:
|
||||||
if (goops) {
|
if (goops) {
|
||||||
if (i < numreq) {
|
if (i < numreq) {
|
||||||
if (strcmp("void", Char(pt)) != 0) {
|
if (strcmp("void", Char(pt)) != 0) {
|
||||||
Node *class_node = Swig_symbol_clookup_check(pb, Getattr(n, "sym:symtab"),
|
Node *class_node = Swig_symbol_clookup_check(pb, Getattr(n, "sym:symtab"), has_classname);
|
||||||
has_classname);
|
|
||||||
String *goopsclassname = !class_node ? NULL : Getattr(class_node, "guile:goopsclassname");
|
String *goopsclassname = !class_node ? NULL : Getattr(class_node, "guile:goopsclassname");
|
||||||
/* do input conversion */
|
/* do input conversion */
|
||||||
if (goopsclassname) {
|
if (goopsclassname) {
|
||||||
|
|
|
@ -234,11 +234,11 @@ extern "C" {
|
||||||
extern void Swig_symbol_conflict_warn(Node *n, Node *c, const String *symname, int inclass);
|
extern void Swig_symbol_conflict_warn(Node *n, Node *c, const String *symname, int inclass);
|
||||||
extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *n);
|
extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *n);
|
||||||
extern Node *Swig_symbol_clookup(const_String_or_char_ptr symname, Symtab *tab);
|
extern Node *Swig_symbol_clookup(const_String_or_char_ptr symname, Symtab *tab);
|
||||||
extern Node *Swig_symbol_clookup_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));
|
extern Node *Swig_symbol_clookup_check(const_String_or_char_ptr symname, Symtab *tab, Node *(*checkfunc) (Node *));
|
||||||
extern Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n);
|
extern Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n);
|
||||||
extern Symtab *Swig_symbol_cscope(const_String_or_char_ptr symname, Symtab *tab);
|
extern Symtab *Swig_symbol_cscope(const_String_or_char_ptr symname, Symtab *tab);
|
||||||
extern Node *Swig_symbol_clookup_local(const_String_or_char_ptr symname, Symtab *tab);
|
extern Node *Swig_symbol_clookup_local(const_String_or_char_ptr symname, Symtab *tab);
|
||||||
extern Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));
|
extern Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr symname, Symtab *tab, Node *(*checkfunc) (Node *));
|
||||||
extern String *Swig_symbol_qualified(Node *n);
|
extern String *Swig_symbol_qualified(Node *n);
|
||||||
extern Node *Swig_symbol_isoverloaded(Node *n);
|
extern Node *Swig_symbol_isoverloaded(Node *n);
|
||||||
extern void Swig_symbol_remove(Node *n);
|
extern void Swig_symbol_remove(Node *n);
|
||||||
|
|
|
@ -495,7 +495,7 @@ void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *s) {
|
||||||
*
|
*
|
||||||
* Inherit symbols from another scope. Primarily for C++ inheritance and
|
* Inherit symbols from another scope. Primarily for C++ inheritance and
|
||||||
* for using directives, such as 'using namespace X;'
|
* for using directives, such as 'using namespace X;'
|
||||||
* but not for using declarations, such as 'using A;'.
|
* but not for using declarations, such as 'using X::A;'.
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void Swig_symbol_inherit(Symtab *s) {
|
void Swig_symbol_inherit(Symtab *s) {
|
||||||
|
@ -1019,12 +1019,12 @@ void Swig_symbol_conflict_warn(Node *n, Node *c, const String *symname, int incl
|
||||||
*
|
*
|
||||||
* This function operates in the C namespace, not the target namespace.
|
* This function operates in the C namespace, not the target namespace.
|
||||||
*
|
*
|
||||||
* The check function is an optional callback that can be used to verify a particular
|
* The checkfunc function is an optional callback that can be used to verify a particular
|
||||||
* symbol match. This is only used in some of the more exotic parts of SWIG. For instance,
|
* symbol match. This is only used in some of the more exotic parts of SWIG. For instance,
|
||||||
* verifying that a class hierarchy implements all pure virtual methods.
|
* verifying that a class hierarchy implements all pure virtual methods.
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (Node *n)) {
|
static Node *_symbol_lookup(const String *name, Symtab *symtab, Node *(*checkfunc) (Node *n)) {
|
||||||
Node *n;
|
Node *n;
|
||||||
List *inherit;
|
List *inherit;
|
||||||
Hash *sym = Getattr(symtab, "csymtab");
|
Hash *sym = Getattr(symtab, "csymtab");
|
||||||
|
@ -1039,17 +1039,13 @@ static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (No
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (n) {
|
if (n) {
|
||||||
/* if a check-function is defined. Call it to determine a match */
|
/* if checkfunc is defined. Call it to determine a match */
|
||||||
if (check) {
|
if (checkfunc) {
|
||||||
int c = check(n);
|
Node *cn = checkfunc(n);
|
||||||
if (c == 1) {
|
if (cn) {
|
||||||
Setmark(symtab, 0);
|
Setmark(symtab, 0);
|
||||||
return n;
|
/* Note that checkfunc can return n != cn, where cn could be a node further down the csym linked list starting at n */
|
||||||
}
|
return cn;
|
||||||
if (c < 0) {
|
|
||||||
/* Terminate the search right away */
|
|
||||||
Setmark(symtab, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Setmark(symtab, 0);
|
Setmark(symtab, 0);
|
||||||
|
@ -1062,7 +1058,7 @@ static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (No
|
||||||
Setmark(symtab, 0);
|
Setmark(symtab, 0);
|
||||||
dname = Swig_symbol_template_deftype(name, symtab);
|
dname = Swig_symbol_template_deftype(name, symtab);
|
||||||
if (!Equal(dname, name)) {
|
if (!Equal(dname, name)) {
|
||||||
n = _symbol_lookup(dname, symtab, check);
|
n = _symbol_lookup(dname, symtab, checkfunc);
|
||||||
}
|
}
|
||||||
Delete(dname);
|
Delete(dname);
|
||||||
if (n)
|
if (n)
|
||||||
|
@ -1075,7 +1071,7 @@ static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (No
|
||||||
int i, len;
|
int i, len;
|
||||||
len = Len(inherit);
|
len = Len(inherit);
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
n = _symbol_lookup(name, Getitem(inherit, i), check);
|
n = _symbol_lookup(name, Getitem(inherit, i), checkfunc);
|
||||||
if (n) {
|
if (n) {
|
||||||
Setmark(symtab, 0);
|
Setmark(symtab, 0);
|
||||||
return n;
|
return n;
|
||||||
|
@ -1087,13 +1083,13 @@ static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (No
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Node *symbol_lookup(const_String_or_char_ptr name, Symtab *symtab, int (*check) (Node *n)) {
|
static Node *symbol_lookup(const_String_or_char_ptr name, Symtab *symtab, Node *(*checkfunc) (Node *n)) {
|
||||||
Node *n = 0;
|
Node *n = 0;
|
||||||
if (DohCheck(name)) {
|
if (DohCheck(name)) {
|
||||||
n = _symbol_lookup(name, symtab, check);
|
n = _symbol_lookup(name, symtab, checkfunc);
|
||||||
} else {
|
} else {
|
||||||
String *sname = NewString(name);
|
String *sname = NewString(name);
|
||||||
n = _symbol_lookup(sname, symtab, check);
|
n = _symbol_lookup(sname, symtab, checkfunc);
|
||||||
Delete(sname);
|
Delete(sname);
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
|
@ -1105,7 +1101,7 @@ static Node *symbol_lookup(const_String_or_char_ptr name, Symtab *symtab, int (*
|
||||||
* symbol_lookup_qualified()
|
* symbol_lookup_qualified()
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symtab, const String *prefix, int local, int (*checkfunc) (Node *n)) {
|
static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symtab, const String *prefix, int local, Node *(*checkfunc) (Node *n)) {
|
||||||
/* This is a little funky, we search by fully qualified names */
|
/* This is a little funky, we search by fully qualified names */
|
||||||
|
|
||||||
if (!symtab)
|
if (!symtab)
|
||||||
|
@ -1269,7 +1265,7 @@ Node *Swig_symbol_clookup(const_String_or_char_ptr name, Symtab *n) {
|
||||||
* inheritance hierarchy.
|
* inheritance hierarchy.
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *n)) {
|
Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, Node *(*checkfunc) (Node *n)) {
|
||||||
Hash *hsym = 0;
|
Hash *hsym = 0;
|
||||||
Node *s = 0;
|
Node *s = 0;
|
||||||
|
|
||||||
|
@ -1321,8 +1317,7 @@ Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (*
|
||||||
}
|
}
|
||||||
/* Check if s is a 'using' node */
|
/* Check if s is a 'using' node */
|
||||||
while (s && Checkattr(s, "nodeType", "using")) {
|
while (s && Checkattr(s, "nodeType", "using")) {
|
||||||
Node *ss;
|
Node *ss = Swig_symbol_clookup(Getattr(s, "uname"), Getattr(s, "sym:symtab"));
|
||||||
ss = Swig_symbol_clookup(Getattr(s, "uname"), Getattr(s, "sym:symtab"));
|
|
||||||
if (!ss && !checkfunc) {
|
if (!ss && !checkfunc) {
|
||||||
SWIG_WARN_NODE_BEGIN(s);
|
SWIG_WARN_NODE_BEGIN(s);
|
||||||
Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
|
Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
|
||||||
|
@ -1390,7 +1385,7 @@ Node *Swig_symbol_clookup_local(const_String_or_char_ptr name, Symtab *n) {
|
||||||
* Swig_symbol_clookup_local_check()
|
* Swig_symbol_clookup_local_check()
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *)) {
|
Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, Node *(*checkfunc) (Node *)) {
|
||||||
Hash *hsym;
|
Hash *hsym;
|
||||||
Node *s = 0;
|
Node *s = 0;
|
||||||
|
|
||||||
|
@ -1439,7 +1434,8 @@ Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n,
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Swig_symbol_clookup_no_inherit()
|
* Swig_symbol_clookup_no_inherit()
|
||||||
*
|
*
|
||||||
* Symbol lookup like Swig_symbol_clookup but does not follow using declarations.
|
* Symbol lookup like Swig_symbol_clookup but does not follow using directives.
|
||||||
|
* Using declarations are followed.
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n) {
|
Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n) {
|
||||||
|
@ -1662,12 +1658,12 @@ static SwigType *symbol_template_qualify(const SwigType *e, Symtab *st) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int symbol_no_constructor(Node *n) {
|
static Node *symbol_no_constructor(Node *n) {
|
||||||
return !Checkattr(n, "nodeType", "constructor");
|
return Checkattr(n, "nodeType", "constructor") ? 0 : n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int symbol_is_template(Node *n) {
|
static Node *symbol_is_template(Node *n) {
|
||||||
return Checkattr(n, "nodeType", "template");
|
return Checkattr(n, "nodeType", "template") ? n : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue