Experimental patch for abstract methods
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4385 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
b2fbb2fad7
commit
bcba55e6f0
3 changed files with 184 additions and 19 deletions
|
|
@ -26,6 +26,31 @@ void Wrapper_virtual_elimination_mode_set(int flag) {
|
||||||
virtual_elimination_mode = flag;
|
virtual_elimination_mode = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper function to assist with abstract class checking.
|
||||||
|
This is a major hack. Sorry. */
|
||||||
|
|
||||||
|
static String *search_decl = 0; /* Declarator being searched */
|
||||||
|
static int check_implemented(Node *n) {
|
||||||
|
String *local_decl;
|
||||||
|
if (!n) return 0;
|
||||||
|
while (n) {
|
||||||
|
if (Strcmp(nodeType(n), "cdecl") == 0) {
|
||||||
|
local_decl = Getattr(n,"decl");
|
||||||
|
if (local_decl) local_decl = SwigType_typedef_resolve_all(local_decl);
|
||||||
|
if (local_decl && (Strcmp(local_decl, search_decl) == 0)) {
|
||||||
|
if (!Getattr(n,"abstract")) {
|
||||||
|
Delete(local_decl);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Delete(local_decl);
|
||||||
|
}
|
||||||
|
n = Getattr(n,"csym:nextSibling");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Allocate : public Dispatcher {
|
class Allocate : public Dispatcher {
|
||||||
Node *inclass;
|
Node *inclass;
|
||||||
enum AccessMode { PUBLIC, PRIVATE, PROTECTED };
|
enum AccessMode { PUBLIC, PRIVATE, PROTECTED };
|
||||||
|
|
@ -143,11 +168,16 @@ class Allocate : public Dispatcher {
|
||||||
if (base_decl) base_decl = SwigType_typedef_resolve_all(base_decl);
|
if (base_decl) base_decl = SwigType_typedef_resolve_all(base_decl);
|
||||||
if (Strstr(name,"~")) continue; /* Don't care about destructors */
|
if (Strstr(name,"~")) continue; /* Don't care about destructors */
|
||||||
int implemented = 0;
|
int implemented = 0;
|
||||||
Node *dn = Swig_symbol_clookup(name,0);
|
/* Node *dn = Swig_symbol_clookup_local(name,0);
|
||||||
if (!dn) {
|
if (!dn) {
|
||||||
Printf(stdout,"node: %x '%s'. base: %x '%s'. member '%s'\n", n, Getattr(n,"name"), base, Getattr(base,"name"), name);
|
Printf(stdout,"node: %x '%s'. base: %x '%s'. member '%s'\n", n, Getattr(n,"name"), base, Getattr(base,"name"), name);
|
||||||
}
|
}
|
||||||
assert(dn != 0); // Assertion of doom
|
assert(dn != 0); // Assertion of doom
|
||||||
|
*/
|
||||||
|
search_decl = base_decl;
|
||||||
|
Node *dn = Swig_symbol_clookup_local_check(name,0,check_implemented);
|
||||||
|
|
||||||
|
/*
|
||||||
while (dn && !implemented) {
|
while (dn && !implemented) {
|
||||||
String *local_decl = Getattr(dn,"decl");
|
String *local_decl = Getattr(dn,"decl");
|
||||||
if (local_decl) local_decl = SwigType_typedef_resolve_all(local_decl);
|
if (local_decl) local_decl = SwigType_typedef_resolve_all(local_decl);
|
||||||
|
|
@ -158,10 +188,16 @@ class Allocate : public Dispatcher {
|
||||||
Delete(local_decl);
|
Delete(local_decl);
|
||||||
dn = Getattr(dn,"csym:nextSibling");
|
dn = Getattr(dn,"csym:nextSibling");
|
||||||
}
|
}
|
||||||
if (!implemented && (Getattr(nn,"abstract"))) {
|
*/
|
||||||
|
|
||||||
|
Delete(base_decl);
|
||||||
|
|
||||||
|
/* if (!implemented && (Getattr(nn,"abstract"))) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
Delete(base_decl);
|
*/
|
||||||
|
|
||||||
|
if (!dn) return 1;
|
||||||
/*
|
/*
|
||||||
if (dn && (Getattr(dn,"abstract"))) {
|
if (dn && (Getattr(dn,"abstract"))) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
|
|
@ -281,8 +281,10 @@ extern Symtab *Swig_symbol_popscope();
|
||||||
extern Node *Swig_symbol_add(String_or_char *symname, Node *node);
|
extern Node *Swig_symbol_add(String_or_char *symname, Node *node);
|
||||||
extern void Swig_symbol_cadd(String_or_char *symname, Node *node);
|
extern void Swig_symbol_cadd(String_or_char *symname, Node *node);
|
||||||
extern Node *Swig_symbol_clookup(String_or_char *symname, Symtab *tab);
|
extern Node *Swig_symbol_clookup(String_or_char *symname, Symtab *tab);
|
||||||
|
extern Node *Swig_symbol_clookup_check(String_or_char *symname, Symtab *tab, int (*check)(Node *));
|
||||||
extern Symtab *Swig_symbol_cscope(String_or_char *symname, Symtab *tab);
|
extern Symtab *Swig_symbol_cscope(String_or_char *symname, Symtab *tab);
|
||||||
extern Node *Swig_symbol_clookup_local(String_or_char *symname, Symtab *tab);
|
extern Node *Swig_symbol_clookup_local(String_or_char *symname, Symtab *tab);
|
||||||
|
extern Node *Swig_symbol_clookup_local_check(String_or_char *symname, Symtab *tab, int (*check)(Node *));
|
||||||
extern String *Swig_symbol_qualified(Node *node);
|
extern String *Swig_symbol_qualified(Node *node);
|
||||||
extern Node *Swig_symbol_isoverloaded(Node *node);
|
extern Node *Swig_symbol_isoverloaded(Node *node);
|
||||||
extern void Swig_symbol_remove(Node *node);
|
extern void Swig_symbol_remove(Node *node);
|
||||||
|
|
|
||||||
|
|
@ -648,10 +648,14 @@ Swig_symbol_add(String_or_char *symname, Node *n) {
|
||||||
* towards the global scope.
|
* towards the global scope.
|
||||||
*
|
*
|
||||||
* 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
|
||||||
|
* 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.
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static Node *
|
static Node *
|
||||||
symbol_lookup(String_or_char *name, Symtab *symtab) {
|
symbol_lookup(String_or_char *name, Symtab *symtab, int (*check)(Node *n)) {
|
||||||
Node *n;
|
Node *n;
|
||||||
List *inherit;
|
List *inherit;
|
||||||
Hash *sym = Getattr(symtab,"csymtab");
|
Hash *sym = Getattr(symtab,"csymtab");
|
||||||
|
|
@ -661,15 +665,30 @@ symbol_lookup(String_or_char *name, Symtab *symtab) {
|
||||||
|
|
||||||
n = Getattr(sym,name);
|
n = Getattr(sym,name);
|
||||||
if (n) {
|
if (n) {
|
||||||
Setmark(symtab,0);
|
/* if a check-function is defined. Call it to determine a match */
|
||||||
return n;
|
if (check) {
|
||||||
|
int c = check(n);
|
||||||
|
if (c == 1) {
|
||||||
|
Setmark(symtab,0);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
if (c < 0) {
|
||||||
|
/* Terminate the search right away */
|
||||||
|
Setmark(symtab,0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Setmark(symtab,0);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inherit = Getattr(symtab,"inherit");
|
inherit = Getattr(symtab,"inherit");
|
||||||
if (inherit) {
|
if (inherit) {
|
||||||
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));
|
n = symbol_lookup(name, Getitem(inherit,i),check);
|
||||||
if (n) {
|
if (n) {
|
||||||
Setmark(symtab,0);
|
Setmark(symtab,0);
|
||||||
return n;
|
return n;
|
||||||
|
|
@ -681,7 +700,7 @@ symbol_lookup(String_or_char *name, Symtab *symtab) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Node *
|
static Node *
|
||||||
symbol_lookup_qualified(String_or_char *name, Symtab *symtab, String *prefix, int local) {
|
symbol_lookup_qualified(String_or_char *name, Symtab *symtab, String *prefix, int local, int (*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) return 0;
|
if (!symtab) return 0;
|
||||||
|
|
@ -691,7 +710,7 @@ symbol_lookup_qualified(String_or_char *name, Symtab *symtab, String *prefix, in
|
||||||
String *prefix;
|
String *prefix;
|
||||||
bname = Swig_scopename_last(name);
|
bname = Swig_scopename_last(name);
|
||||||
prefix = Swig_scopename_prefix(name);
|
prefix = Swig_scopename_prefix(name);
|
||||||
n = symbol_lookup_qualified(bname,symtab,prefix,local);
|
n = symbol_lookup_qualified(bname,symtab,prefix,local,checkfunc);
|
||||||
Delete(bname);
|
Delete(bname);
|
||||||
Delete(prefix);
|
Delete(prefix);
|
||||||
return n;
|
return n;
|
||||||
|
|
@ -713,13 +732,13 @@ symbol_lookup_qualified(String_or_char *name, Symtab *symtab, String *prefix, in
|
||||||
/* Found a scope match */
|
/* Found a scope match */
|
||||||
if (st) {
|
if (st) {
|
||||||
if (!name) return st;
|
if (!name) return st;
|
||||||
n = symbol_lookup(name, st);
|
n = symbol_lookup(name, st,checkfunc);
|
||||||
}
|
}
|
||||||
Delete(qname);
|
Delete(qname);
|
||||||
if (!n) {
|
if (!n) {
|
||||||
if (!local) {
|
if (!local) {
|
||||||
Node *pn = parentNode(symtab);
|
Node *pn = parentNode(symtab);
|
||||||
if (pn) n = symbol_lookup_qualified(name,pn, prefix, local);
|
if (pn) n = symbol_lookup_qualified(name,pn, prefix, local,checkfunc);
|
||||||
} else {
|
} else {
|
||||||
n = 0;
|
n = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -757,12 +776,12 @@ Swig_symbol_clookup(String_or_char *name, Symtab *n) {
|
||||||
if (Strncmp(name,"::",2) == 0) {
|
if (Strncmp(name,"::",2) == 0) {
|
||||||
String *nname = NewString(Char(name)+2);
|
String *nname = NewString(Char(name)+2);
|
||||||
if (Swig_scopename_check(nname)) {
|
if (Swig_scopename_check(nname)) {
|
||||||
s = symbol_lookup_qualified(nname,global_scope,0,0);
|
s = symbol_lookup_qualified(nname,global_scope,0,0,0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String *prefix = Swig_scopename_prefix(name);
|
String *prefix = Swig_scopename_prefix(name);
|
||||||
if (prefix) {
|
if (prefix) {
|
||||||
s = symbol_lookup_qualified(name,hsym,0,0);
|
s = symbol_lookup_qualified(name,hsym,0,0,0);
|
||||||
Delete(prefix);
|
Delete(prefix);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -772,7 +791,7 @@ Swig_symbol_clookup(String_or_char *name, Symtab *n) {
|
||||||
}
|
}
|
||||||
if (!s) {
|
if (!s) {
|
||||||
while (hsym) {
|
while (hsym) {
|
||||||
s = symbol_lookup(name,hsym);
|
s = symbol_lookup(name,hsym,0);
|
||||||
if (s) break;
|
if (s) break;
|
||||||
hsym = parentNode(hsym);
|
hsym = parentNode(hsym);
|
||||||
if (!hsym) break;
|
if (!hsym) break;
|
||||||
|
|
@ -793,6 +812,73 @@ Swig_symbol_clookup(String_or_char *name, Symtab *n) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Swig_symbol_clookup_check()
|
||||||
|
*
|
||||||
|
* This function is identical to Swig_symbol_clookup() except that it
|
||||||
|
* accepts a callback function that is invoked to determine a symbol match.
|
||||||
|
* The purpose of this function is to support complicated algorithms that need
|
||||||
|
* to examine multiple definitions of the same symbol that might appear in an
|
||||||
|
* inheritance hierarchy.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
Node *
|
||||||
|
Swig_symbol_clookup_check(String_or_char *name, Symtab *n, int (*checkfunc)(Node *n)) {
|
||||||
|
Hash *hsym;
|
||||||
|
Node *s = 0;
|
||||||
|
|
||||||
|
if (!n) {
|
||||||
|
hsym = current_symtab;
|
||||||
|
} else {
|
||||||
|
if (Strcmp(nodeType(n),"symboltable")) {
|
||||||
|
n = Getattr(n,"sym:symtab");
|
||||||
|
}
|
||||||
|
assert(n);
|
||||||
|
if (n) {
|
||||||
|
hsym = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Swig_scopename_check(name)) {
|
||||||
|
if (Strncmp(name,"::",2) == 0) {
|
||||||
|
String *nname = NewString(Char(name)+2);
|
||||||
|
if (Swig_scopename_check(nname)) {
|
||||||
|
s = symbol_lookup_qualified(nname,global_scope,0,0,checkfunc);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String *prefix = Swig_scopename_prefix(name);
|
||||||
|
if (prefix) {
|
||||||
|
s = symbol_lookup_qualified(name,hsym,0,0,checkfunc);
|
||||||
|
Delete(prefix);
|
||||||
|
if (!s) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!s) {
|
||||||
|
while (hsym) {
|
||||||
|
s = symbol_lookup(name,hsym,checkfunc);
|
||||||
|
if (s) break;
|
||||||
|
hsym = parentNode(hsym);
|
||||||
|
if (!hsym) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!s) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Check if s is a 'using' node */
|
||||||
|
while (s && Strcmp(nodeType(s),"using") == 0) {
|
||||||
|
Node *ss;
|
||||||
|
ss = Swig_symbol_clookup(Getattr(s,"uname"), Getattr(s,"sym:symtab"));
|
||||||
|
if (!ss && !checkfunc) {
|
||||||
|
Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", Getattr(s,"uname"));
|
||||||
|
}
|
||||||
|
s = ss;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
Node *
|
Node *
|
||||||
Swig_symbol_clookup_local(String_or_char *name, Symtab *n) {
|
Swig_symbol_clookup_local(String_or_char *name, Symtab *n) {
|
||||||
Hash *h, *hsym;
|
Hash *h, *hsym;
|
||||||
|
|
@ -812,13 +898,13 @@ Swig_symbol_clookup_local(String_or_char *name, Symtab *n) {
|
||||||
|
|
||||||
if (Swig_scopename_check(name)) {
|
if (Swig_scopename_check(name)) {
|
||||||
if (Strncmp(name,"::",2) == 0) {
|
if (Strncmp(name,"::",2) == 0) {
|
||||||
s = symbol_lookup_qualified(Char(name)+2,global_scope,0,0);
|
s = symbol_lookup_qualified(Char(name)+2,global_scope,0,0,0);
|
||||||
} else {
|
} else {
|
||||||
s = symbol_lookup_qualified(name,hsym,0,0);
|
s = symbol_lookup_qualified(name,hsym,0,0,0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!s) {
|
if (!s) {
|
||||||
s = symbol_lookup(name,hsym);
|
s = symbol_lookup(name,hsym,0);
|
||||||
}
|
}
|
||||||
if (!s) return 0;
|
if (!s) return 0;
|
||||||
/* Check if s is a 'using' node */
|
/* Check if s is a 'using' node */
|
||||||
|
|
@ -832,6 +918,47 @@ Swig_symbol_clookup_local(String_or_char *name, Symtab *n) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Node *
|
||||||
|
Swig_symbol_clookup_local_check(String_or_char *name, Symtab *n, int (*checkfunc)(Node *)) {
|
||||||
|
Hash *h, *hsym;
|
||||||
|
Node *s = 0;
|
||||||
|
|
||||||
|
if (!n) {
|
||||||
|
hsym = current_symtab;
|
||||||
|
h = ccurrent;
|
||||||
|
} else {
|
||||||
|
if (Strcmp(nodeType(n),"symboltable")) {
|
||||||
|
n = Getattr(n,"sym:symtab");
|
||||||
|
}
|
||||||
|
assert(n);
|
||||||
|
hsym = n;
|
||||||
|
h = Getattr(n,"csymtab");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Swig_scopename_check(name)) {
|
||||||
|
if (Strncmp(name,"::",2) == 0) {
|
||||||
|
s = symbol_lookup_qualified(Char(name)+2,global_scope,0,0,checkfunc);
|
||||||
|
} else {
|
||||||
|
s = symbol_lookup_qualified(name,hsym,0,0,checkfunc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!s) {
|
||||||
|
s = symbol_lookup(name,hsym,checkfunc);
|
||||||
|
}
|
||||||
|
if (!s) return 0;
|
||||||
|
/* Check if s is a 'using' node */
|
||||||
|
while (s && Strcmp(nodeType(s),"using") == 0) {
|
||||||
|
Node *ss = Swig_symbol_clookup_local_check(Getattr(s,"uname"), Getattr(s,"sym:symtab"),checkfunc);
|
||||||
|
if (!ss && !checkfunc) {
|
||||||
|
Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", Getattr(s,"uname"));
|
||||||
|
}
|
||||||
|
s = ss;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Swig_symbol_cscope()
|
* Swig_symbol_cscope()
|
||||||
*
|
*
|
||||||
|
|
@ -840,8 +967,8 @@ Swig_symbol_clookup_local(String_or_char *name, Symtab *n) {
|
||||||
|
|
||||||
Symtab *
|
Symtab *
|
||||||
Swig_symbol_cscope(String_or_char *name, Symtab *symtab) {
|
Swig_symbol_cscope(String_or_char *name, Symtab *symtab) {
|
||||||
if (Strncmp(name,"::",2) == 0) return symbol_lookup_qualified(0, global_scope, name, 0);
|
if (Strncmp(name,"::",2) == 0) return symbol_lookup_qualified(0, global_scope, name, 0,0);
|
||||||
return symbol_lookup_qualified(0,symtab,name,0);
|
return symbol_lookup_qualified(0,symtab,name,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue