process protected/private bases
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6736 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
f678d1eed0
commit
a32173a68c
5 changed files with 119 additions and 83 deletions
|
|
@ -332,8 +332,16 @@ static String *make_unnamed() {
|
|||
/* Return the node name when it requires to emit a name warning */
|
||||
static String *name_warning(Node *n,String *name,SwigType *decl) {
|
||||
/* Return in the obvious cases */
|
||||
if (!namewarn_hash || !name || !need_name_warning(n)) return 0;
|
||||
|
||||
if (!namewarn_hash || !name || !need_name_warning(n)) {
|
||||
return 0;
|
||||
} else {
|
||||
String *access = Getattr(n,"access");
|
||||
int is_public = !access || (Strcmp(access,"public") == 0);
|
||||
if (!is_public && !need_protected(n,dirprot_mode)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check to see if the name is in the hash */
|
||||
return Swig_name_object_get(namewarn_hash,Namespaceprefix,name,decl);
|
||||
}
|
||||
|
|
@ -2822,7 +2830,7 @@ cpp_class_decl :
|
|||
Classprefix = NewString($3);
|
||||
/* Deal with inheritance */
|
||||
if ($4) {
|
||||
bases = make_inherit_list($3,$4);
|
||||
bases = make_inherit_list($3,Getattr($4,"public"));
|
||||
}
|
||||
if (SwigType_istemplate($3)) {
|
||||
String *fbase, *tbase, *prefix;
|
||||
|
|
@ -2881,7 +2889,11 @@ cpp_class_decl :
|
|||
Setline($$,cparse_start_line);
|
||||
Setattr($$,"name",$3);
|
||||
Setattr($$,"kind",$2);
|
||||
Setattr($$,"baselist",$4);
|
||||
if ($4) {
|
||||
Setattr($$,"baselist", Getattr($4,"public"));
|
||||
Setattr($$,"protectedbaselist", Getattr($4,"protected"));
|
||||
Setattr($$,"privatebaselist", Getattr($4,"private"));
|
||||
}
|
||||
Setattr($$,"allows_typedef","1");
|
||||
/* Check for pure-abstract class */
|
||||
Setattr($$,"abstract", pure_abstract($7));
|
||||
|
|
@ -5016,34 +5028,43 @@ raw_inherit : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list
|
|||
;
|
||||
|
||||
base_list : base_specifier {
|
||||
$$ = NewList();
|
||||
if ($1) Append($$,$1);
|
||||
Hash *list = NewHash();
|
||||
Node *base = $1;
|
||||
Node *name = Getattr(base,"name");
|
||||
Setattr(list,"public",NewList());
|
||||
Setattr(list,"protected",NewList());
|
||||
Setattr(list,"private",NewList());
|
||||
Append(Getattr(list,Getattr(base,"access")),name);
|
||||
$$ = list;
|
||||
}
|
||||
|
||||
| base_list COMMA base_specifier {
|
||||
$$ = $1;
|
||||
if ($3) Append($$,$3);
|
||||
Hash *list = $1;
|
||||
Node *base = $3;
|
||||
Node *name = Getattr(base,"name");
|
||||
Append(Getattr(list,Getattr(base,"access")),name);
|
||||
$$ = list;
|
||||
}
|
||||
;
|
||||
|
||||
base_specifier : opt_virtual idcolon {
|
||||
$$ = NewHash();
|
||||
Setattr($$,"name",$2);
|
||||
if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) {
|
||||
Swig_warning(WARN_PARSE_NO_ACCESS,cparse_file, cparse_line,"No access specifier given for base class %s (ignored).\n",$2);
|
||||
$$ = (char *) 0;
|
||||
Setattr($$,"access","private");
|
||||
Swig_warning(WARN_PARSE_NO_ACCESS,cparse_file,cparse_line,
|
||||
"No access specifier given for base class %s (ignored).\n",$2);
|
||||
} else {
|
||||
$$ = $2;
|
||||
Setfile($$,cparse_file);
|
||||
Setline($$,cparse_line);
|
||||
Setattr($$,"access","public");
|
||||
}
|
||||
}
|
||||
| opt_virtual access_specifier opt_virtual idcolon {
|
||||
$$ = 0;
|
||||
if (strcmp($2,"public") == 0) {
|
||||
$$ = $4;
|
||||
Setfile($$, cparse_file);
|
||||
Setline($$, cparse_line);
|
||||
} else {
|
||||
Swig_warning(WARN_PARSE_PRIVATE_INHERIT, cparse_file, cparse_line, "%s inheritance ignored.\n", $2);
|
||||
$$ = NewHash();
|
||||
Setattr($$,"name",$4);
|
||||
Setattr($$,"access",$2);
|
||||
if (Strcmp($2,"public") != 0) {
|
||||
Swig_warning(WARN_PARSE_PRIVATE_INHERIT, cparse_file,
|
||||
cparse_line,"%s inheritance ignored.\n", $2);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
|
|
|||
|
|
@ -96,8 +96,6 @@ void cparse_normalize_void(Node *n) {
|
|||
|
||||
int need_protected(Node* n, int dirprot_mode)
|
||||
{
|
||||
if (!(Swig_need_protected() || dirprot_mode)) return 0;
|
||||
|
||||
/* First, 'n' looks like a function */
|
||||
if ((Strcmp(nodeType(n),"cdecl") == 0) &&
|
||||
SwigType_isfunction(Getattr(n,"decl"))) {
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ class Allocate : public Dispatcher {
|
|||
Delete(local_type);
|
||||
for (int j = 0; j < Len(bases); j++) {
|
||||
b = Getitem(bases,j);
|
||||
if (function_is_defined_in_bases(c, Getattr(b, "bases")))
|
||||
if (function_is_defined_in_bases(c, Getattr(b, "allbases")))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -147,7 +147,7 @@ class Allocate : public Dispatcher {
|
|||
Node *c, *bases; /* bases is the closest ancestors of class n */
|
||||
int defined = 0;
|
||||
|
||||
bases = Getattr(n, "bases");
|
||||
bases = Getattr(n, "allbases");
|
||||
|
||||
if (!bases) return 0;
|
||||
|
||||
|
|
@ -170,7 +170,7 @@ class Allocate : public Dispatcher {
|
|||
Node *bases; /* bases is the closest ancestors of classnode */
|
||||
int defined = 0;
|
||||
|
||||
bases = Getattr(classnode, "bases");
|
||||
bases = Getattr(classnode, "allbases");
|
||||
if (!bases) return 0;
|
||||
|
||||
//if (checkAttribute(member, "storage", "virtual"))
|
||||
|
|
@ -211,52 +211,28 @@ class Allocate : public Dispatcher {
|
|||
String *base_decl = Getattr(nn,"decl");
|
||||
if (base_decl) base_decl = SwigType_typedef_resolve_all(base_decl);
|
||||
if (Strstr(name,"~")) continue; /* Don't care about destructors */
|
||||
/*
|
||||
int implemented = 0;
|
||||
Node *dn = Swig_symbol_clookup_local(name,0);
|
||||
if (!dn) {
|
||||
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
|
||||
*/
|
||||
|
||||
if (SwigType_isfunction(base_decl)) {
|
||||
search_decl = SwigType_pop_function(base_decl);
|
||||
}
|
||||
Node *dn = Swig_symbol_clookup_local_check(name,0,check_implemented);
|
||||
Delete(search_decl);
|
||||
Delete(base_decl);
|
||||
/*
|
||||
while (dn && !implemented) {
|
||||
String *local_decl = Getattr(dn,"decl");
|
||||
if (local_decl) local_decl = SwigType_typedef_resolve_all(local_decl);
|
||||
if (local_decl && !Strcmp(local_decl, base_decl)) {
|
||||
if (Getattr(dn,"abstract")) return 1;
|
||||
implemented++;
|
||||
}
|
||||
Delete(local_decl);
|
||||
dn = Getattr(dn,"csym:nextSibling");
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* if (!implemented && (Getattr(nn,"abstract"))) {
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
if (!dn) {
|
||||
Setattr(n,"abstract:firstnode",nn);
|
||||
return 1;
|
||||
List *abstract = Getattr(n,"abstract");
|
||||
if (!abstract) {
|
||||
abstract = NewList();
|
||||
Setattr(n,"abstract",abstract);
|
||||
} else {
|
||||
if (!Getattr(n,"abstract:firstnode"))
|
||||
Setattr(n,"abstract:firstnode",nn);
|
||||
}
|
||||
Append(abstract,nn);
|
||||
}
|
||||
/*
|
||||
if (dn && (Getattr(dn,"abstract"))) {
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
List *bases = Getattr(base,"bases");
|
||||
List *bases = Getattr(base,"allbases");
|
||||
if (!bases) return 0;
|
||||
for (int i = 0; i < Len(bases); i++) {
|
||||
if (is_abstract_inherit(n,Getitem(bases,i))) {
|
||||
|
|
@ -440,19 +416,25 @@ public:
|
|||
/* Check if the class is abstract via inheritance. This might occur if a class didn't have
|
||||
any pure virtual methods of its own, but it didn't implement all of the pure methods in
|
||||
a base class */
|
||||
|
||||
if (is_abstract_inherit(n)) {
|
||||
if ((!Getattr(n,"abstract")) && ((Getattr(n,"allocate:public_constructor") || (!Getattr(n,"feature:nodefault") && !Getattr(n,"allocate:has_constructor"))))) {
|
||||
|
||||
if (!Getattr(n,"abstract") && is_abstract_inherit(n)) {
|
||||
if (((Getattr(n,"allocate:public_constructor") || (!Getattr(n,"feature:nodefault") && !Getattr(n,"allocate:has_constructor"))))) {
|
||||
if (!Getattr(n,"feature:notabstract")) {
|
||||
Node *na = Getattr(n,"abstract:firstnode");
|
||||
Swig_warning(WARN_TYPE_ABSTRACT, Getfile(n), Getline(n),
|
||||
"Class '%s' might be abstract, "
|
||||
"no constructors generated,\n",
|
||||
SwigType_namestr(Getattr(n,"name")));
|
||||
Swig_warning(WARN_TYPE_ABSTRACT, Getfile(na), Getline(na),
|
||||
" method '%s' might not be implemented.",
|
||||
SwigType_namestr(Getattr(na,"name")));
|
||||
Setattr(n,"abstract",NewList());
|
||||
if (na) {
|
||||
Swig_warning(WARN_TYPE_ABSTRACT, Getfile(n), Getline(n),
|
||||
"Class '%s' might be abstract, "
|
||||
"no constructors generated,\n",
|
||||
SwigType_namestr(Getattr(n,"name")));
|
||||
Swig_warning(WARN_TYPE_ABSTRACT, Getfile(na), Getline(na),
|
||||
" method '%s' might not be implemented.",
|
||||
SwigType_namestr(Getattr(na,"name")));
|
||||
if (!Getattr(n,"abstract")) {
|
||||
List *abstract = NewList();
|
||||
Append(abstract,na);
|
||||
Setattr(n,"abstract",abstract);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -465,7 +447,7 @@ public:
|
|||
}
|
||||
if (!Getattr(n,"allocate:default_constructor")) {
|
||||
/* Check base classes */
|
||||
List *bases = Getattr(n,"bases");
|
||||
List *bases = Getattr(n,"allbases");
|
||||
int allows_default = 1;
|
||||
|
||||
for (int i = 0; i < Len(bases); i++) {
|
||||
|
|
@ -482,7 +464,7 @@ public:
|
|||
}
|
||||
if (!Getattr(n,"allocate:has_destructor")) {
|
||||
/* No destructor was defined. We need to check a few things here too */
|
||||
List *bases = Getattr(n,"bases");
|
||||
List *bases = Getattr(n,"allbases");
|
||||
int allows_destruct = 1;
|
||||
|
||||
for (int i = 0; i < Len(bases); i++) {
|
||||
|
|
@ -499,7 +481,7 @@ public:
|
|||
|
||||
if (!Getattr(n,"allocate:has_assign")) {
|
||||
/* No destructor was defined. We need to check a few things here too */
|
||||
List *bases = Getattr(n,"bases");
|
||||
List *bases = Getattr(n,"allbases");
|
||||
int allows_assign = 1;
|
||||
|
||||
for (int i = 0; i < Len(bases); i++) {
|
||||
|
|
@ -516,7 +498,7 @@ public:
|
|||
|
||||
if (!Getattr(n,"allocate:has_new")) {
|
||||
/* No destructor was defined. We need to check a few things here too */
|
||||
List *bases = Getattr(n,"bases");
|
||||
List *bases = Getattr(n,"allbases");
|
||||
int allows_new = 1;
|
||||
|
||||
for (int i = 0; i < Len(bases); i++) {
|
||||
|
|
|
|||
|
|
@ -200,7 +200,8 @@ public:
|
|||
Node *parent,
|
||||
Hash *vm,
|
||||
int default_director,
|
||||
int &virtual_destructor);
|
||||
int &virtual_destructor,
|
||||
int protectedbase = 0);
|
||||
virtual int classDirectorConstructor(Node *n);
|
||||
virtual int classDirectorDefaultConstructor(Node *n);
|
||||
virtual int classDirectorMethod(Node *n, Node *parent, String *super);
|
||||
|
|
@ -279,6 +280,12 @@ public:
|
|||
/* Director 'protected' constructor "template" code*/
|
||||
String *director_prot_ctor_code;
|
||||
|
||||
/* Director allows multiple inheritance */
|
||||
int director_multiple_inheritance;
|
||||
|
||||
/* Director language module */
|
||||
int director_language;
|
||||
|
||||
private:
|
||||
Hash *symbols;
|
||||
Hash *classtypes;
|
||||
|
|
|
|||
|
|
@ -127,16 +127,18 @@ class TypePass : private Dispatcher {
|
|||
}
|
||||
Swig_symbol_setscope(currentsym);
|
||||
}
|
||||
|
||||
|
||||
/* generate C++ inheritance type-relationships */
|
||||
void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) {
|
||||
void cplus_inherit_types_impl(Node *first, Node *cls, String*clsname,
|
||||
const char *bases, const char *baselist,
|
||||
int ispublic, String *cast = 0) {
|
||||
|
||||
if (first == cls) return; /* The Marcelo check */
|
||||
if (!cls) cls = first;
|
||||
|
||||
List *ilist = Getattr(cls,"bases");
|
||||
List *ilist = Getattr(cls,bases);
|
||||
if (!ilist) {
|
||||
List *nlist = Getattr(cls,"baselist");
|
||||
List *nlist = Getattr(cls,baselist);
|
||||
if (nlist) {
|
||||
int len = Len(nlist);
|
||||
int i;
|
||||
|
|
@ -197,7 +199,7 @@ class TypePass : private Dispatcher {
|
|||
if (tname) Delete(tname);
|
||||
if (!bcls) {
|
||||
if (!clsforward) {
|
||||
if (!Getmeta(bname,"already_warned")) {
|
||||
if (ispublic && !Getmeta(bname,"already_warned")) {
|
||||
Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls),Getline(cls),"Nothing known about base class '%s'. Ignored.\n", SwigType_namestr(bname));
|
||||
if (Strchr(bname,'<')) {
|
||||
Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls), Getline(cls), "Maybe you forgot to instantiate '%s' using %%template.\n", SwigType_namestr(bname));
|
||||
|
|
@ -210,7 +212,7 @@ class TypePass : private Dispatcher {
|
|||
}
|
||||
}
|
||||
if (ilist) {
|
||||
Setattr(cls,"bases",ilist);
|
||||
Setattr(cls,bases,ilist);
|
||||
}
|
||||
}
|
||||
if (!ilist) return;
|
||||
|
|
@ -240,11 +242,37 @@ class TypePass : private Dispatcher {
|
|||
|
||||
/* Recursively hit base classes */
|
||||
String *newcast = NewStringf("(%s *)%s", SwigType_namestr(Getattr(bclass,"name")), cast);
|
||||
cplus_inherit_types(first,bclass,clsname, newcast);
|
||||
cplus_inherit_types_impl(first,bclass,clsname,bases,baselist,ispublic,newcast);
|
||||
Delete(newcast);
|
||||
}
|
||||
}
|
||||
|
||||
void append_list(List *lb, List *la) {
|
||||
if (la && lb) {
|
||||
for (Iterator bi = First(la); bi.item; bi = Next(bi)) {
|
||||
Append(lb,bi.item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) {
|
||||
cplus_inherit_types_impl(first, cls, clsname, "bases", "baselist", 1, cast);
|
||||
cplus_inherit_types_impl(first, cls, clsname, "protectedbases","protectedbaselist", 0, cast);
|
||||
cplus_inherit_types_impl(first, cls, clsname, "privatebases" ,"privatebaselist", 0, cast);
|
||||
|
||||
if (!cls) cls = first;
|
||||
|
||||
List *allbases = NewList();
|
||||
append_list(allbases,Getattr(cls,"bases"));
|
||||
append_list(allbases,Getattr(cls,"protectedbases"));
|
||||
append_list(allbases,Getattr(cls,"privatebases"));
|
||||
if (Len(allbases)) {
|
||||
Setattr(cls,"allbases",allbases);
|
||||
} else {
|
||||
Delete(allbases);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean overloaded list. Removes templates, friends, ignored, and errors */
|
||||
|
||||
void clean_overloaded(Node *n) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue