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:
Marcelo Matus 2004-11-15 22:53:13 +00:00
commit a32173a68c
5 changed files with 119 additions and 83 deletions

View file

@ -332,7 +332,15 @@ static String *make_unnamed() {
/* Return the node name when it requires to emit a name warning */ /* Return the node name when it requires to emit a name warning */
static String *name_warning(Node *n,String *name,SwigType *decl) { static String *name_warning(Node *n,String *name,SwigType *decl) {
/* Return in the obvious cases */ /* 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 */ /* Check to see if the name is in the hash */
return Swig_name_object_get(namewarn_hash,Namespaceprefix,name,decl); return Swig_name_object_get(namewarn_hash,Namespaceprefix,name,decl);
@ -2822,7 +2830,7 @@ cpp_class_decl :
Classprefix = NewString($3); Classprefix = NewString($3);
/* Deal with inheritance */ /* Deal with inheritance */
if ($4) { if ($4) {
bases = make_inherit_list($3,$4); bases = make_inherit_list($3,Getattr($4,"public"));
} }
if (SwigType_istemplate($3)) { if (SwigType_istemplate($3)) {
String *fbase, *tbase, *prefix; String *fbase, *tbase, *prefix;
@ -2881,7 +2889,11 @@ cpp_class_decl :
Setline($$,cparse_start_line); Setline($$,cparse_start_line);
Setattr($$,"name",$3); Setattr($$,"name",$3);
Setattr($$,"kind",$2); 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"); Setattr($$,"allows_typedef","1");
/* Check for pure-abstract class */ /* Check for pure-abstract class */
Setattr($$,"abstract", pure_abstract($7)); Setattr($$,"abstract", pure_abstract($7));
@ -5016,34 +5028,43 @@ raw_inherit : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list
; ;
base_list : base_specifier { base_list : base_specifier {
$$ = NewList(); Hash *list = NewHash();
if ($1) Append($$,$1); 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 { | base_list COMMA base_specifier {
$$ = $1; Hash *list = $1;
if ($3) Append($$,$3); Node *base = $3;
Node *name = Getattr(base,"name");
Append(Getattr(list,Getattr(base,"access")),name);
$$ = list;
} }
; ;
base_specifier : opt_virtual idcolon { base_specifier : opt_virtual idcolon {
$$ = NewHash();
Setattr($$,"name",$2);
if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) { 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); Setattr($$,"access","private");
$$ = (char *) 0; Swig_warning(WARN_PARSE_NO_ACCESS,cparse_file,cparse_line,
"No access specifier given for base class %s (ignored).\n",$2);
} else { } else {
$$ = $2; Setattr($$,"access","public");
Setfile($$,cparse_file);
Setline($$,cparse_line);
} }
} }
| opt_virtual access_specifier opt_virtual idcolon { | opt_virtual access_specifier opt_virtual idcolon {
$$ = 0; $$ = NewHash();
if (strcmp($2,"public") == 0) { Setattr($$,"name",$4);
$$ = $4; Setattr($$,"access",$2);
Setfile($$, cparse_file); if (Strcmp($2,"public") != 0) {
Setline($$, cparse_line); Swig_warning(WARN_PARSE_PRIVATE_INHERIT, cparse_file,
} else { cparse_line,"%s inheritance ignored.\n", $2);
Swig_warning(WARN_PARSE_PRIVATE_INHERIT, cparse_file, cparse_line, "%s inheritance ignored.\n", $2);
} }
} }
; ;

View file

@ -96,8 +96,6 @@ void cparse_normalize_void(Node *n) {
int need_protected(Node* n, int dirprot_mode) int need_protected(Node* n, int dirprot_mode)
{ {
if (!(Swig_need_protected() || dirprot_mode)) return 0;
/* First, 'n' looks like a function */ /* First, 'n' looks like a function */
if ((Strcmp(nodeType(n),"cdecl") == 0) && if ((Strcmp(nodeType(n),"cdecl") == 0) &&
SwigType_isfunction(Getattr(n,"decl"))) { SwigType_isfunction(Getattr(n,"decl"))) {

View file

@ -135,7 +135,7 @@ class Allocate : public Dispatcher {
Delete(local_type); Delete(local_type);
for (int j = 0; j < Len(bases); j++) { for (int j = 0; j < Len(bases); j++) {
b = Getitem(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 1;
} }
return 0; return 0;
@ -147,7 +147,7 @@ class Allocate : public Dispatcher {
Node *c, *bases; /* bases is the closest ancestors of class n */ Node *c, *bases; /* bases is the closest ancestors of class n */
int defined = 0; int defined = 0;
bases = Getattr(n, "bases"); bases = Getattr(n, "allbases");
if (!bases) return 0; if (!bases) return 0;
@ -170,7 +170,7 @@ class Allocate : public Dispatcher {
Node *bases; /* bases is the closest ancestors of classnode */ Node *bases; /* bases is the closest ancestors of classnode */
int defined = 0; int defined = 0;
bases = Getattr(classnode, "bases"); bases = Getattr(classnode, "allbases");
if (!bases) return 0; if (!bases) return 0;
//if (checkAttribute(member, "storage", "virtual")) //if (checkAttribute(member, "storage", "virtual"))
@ -211,52 +211,28 @@ class Allocate : public Dispatcher {
String *base_decl = Getattr(nn,"decl"); String *base_decl = Getattr(nn,"decl");
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;
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)) { if (SwigType_isfunction(base_decl)) {
search_decl = SwigType_pop_function(base_decl); search_decl = SwigType_pop_function(base_decl);
} }
Node *dn = Swig_symbol_clookup_local_check(name,0,check_implemented); Node *dn = Swig_symbol_clookup_local_check(name,0,check_implemented);
Delete(search_decl); Delete(search_decl);
Delete(base_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) { if (!dn) {
Setattr(n,"abstract:firstnode",nn); List *abstract = Getattr(n,"abstract");
return 1; 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; if (!bases) return 0;
for (int i = 0; i < Len(bases); i++) { for (int i = 0; i < Len(bases); i++) {
if (is_abstract_inherit(n,Getitem(bases,i))) { if (is_abstract_inherit(n,Getitem(bases,i))) {
@ -441,18 +417,24 @@ public:
any pure virtual methods of its own, but it didn't implement all of the pure methods in any pure virtual methods of its own, but it didn't implement all of the pure methods in
a base class */ a base class */
if (is_abstract_inherit(n)) { if (!Getattr(n,"abstract") && 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,"allocate:public_constructor") || (!Getattr(n,"feature:nodefault") && !Getattr(n,"allocate:has_constructor"))))) {
if (!Getattr(n,"feature:notabstract")) { if (!Getattr(n,"feature:notabstract")) {
Node *na = Getattr(n,"abstract:firstnode"); Node *na = Getattr(n,"abstract:firstnode");
Swig_warning(WARN_TYPE_ABSTRACT, Getfile(n), Getline(n), if (na) {
"Class '%s' might be abstract, " Swig_warning(WARN_TYPE_ABSTRACT, Getfile(n), Getline(n),
"no constructors generated,\n", "Class '%s' might be abstract, "
SwigType_namestr(Getattr(n,"name"))); "no constructors generated,\n",
Swig_warning(WARN_TYPE_ABSTRACT, Getfile(na), Getline(na), SwigType_namestr(Getattr(n,"name")));
" method '%s' might not be implemented.", Swig_warning(WARN_TYPE_ABSTRACT, Getfile(na), Getline(na),
SwigType_namestr(Getattr(na,"name"))); " method '%s' might not be implemented.",
Setattr(n,"abstract",NewList()); 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")) { if (!Getattr(n,"allocate:default_constructor")) {
/* Check base classes */ /* Check base classes */
List *bases = Getattr(n,"bases"); List *bases = Getattr(n,"allbases");
int allows_default = 1; int allows_default = 1;
for (int i = 0; i < Len(bases); i++) { for (int i = 0; i < Len(bases); i++) {
@ -482,7 +464,7 @@ public:
} }
if (!Getattr(n,"allocate:has_destructor")) { if (!Getattr(n,"allocate:has_destructor")) {
/* No destructor was defined. We need to check a few things here too */ /* 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; int allows_destruct = 1;
for (int i = 0; i < Len(bases); i++) { for (int i = 0; i < Len(bases); i++) {
@ -499,7 +481,7 @@ public:
if (!Getattr(n,"allocate:has_assign")) { if (!Getattr(n,"allocate:has_assign")) {
/* No destructor was defined. We need to check a few things here too */ /* 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; int allows_assign = 1;
for (int i = 0; i < Len(bases); i++) { for (int i = 0; i < Len(bases); i++) {
@ -516,7 +498,7 @@ public:
if (!Getattr(n,"allocate:has_new")) { if (!Getattr(n,"allocate:has_new")) {
/* No destructor was defined. We need to check a few things here too */ /* 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; int allows_new = 1;
for (int i = 0; i < Len(bases); i++) { for (int i = 0; i < Len(bases); i++) {

View file

@ -200,7 +200,8 @@ public:
Node *parent, Node *parent,
Hash *vm, Hash *vm,
int default_director, int default_director,
int &virtual_destructor); int &virtual_destructor,
int protectedbase = 0);
virtual int classDirectorConstructor(Node *n); virtual int classDirectorConstructor(Node *n);
virtual int classDirectorDefaultConstructor(Node *n); virtual int classDirectorDefaultConstructor(Node *n);
virtual int classDirectorMethod(Node *n, Node *parent, String *super); virtual int classDirectorMethod(Node *n, Node *parent, String *super);
@ -279,6 +280,12 @@ public:
/* Director 'protected' constructor "template" code*/ /* Director 'protected' constructor "template" code*/
String *director_prot_ctor_code; String *director_prot_ctor_code;
/* Director allows multiple inheritance */
int director_multiple_inheritance;
/* Director language module */
int director_language;
private: private:
Hash *symbols; Hash *symbols;
Hash *classtypes; Hash *classtypes;

View file

@ -129,14 +129,16 @@ class TypePass : private Dispatcher {
} }
/* generate C++ inheritance type-relationships */ /* 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 (first == cls) return; /* The Marcelo check */
if (!cls) cls = first; if (!cls) cls = first;
List *ilist = Getattr(cls,"bases"); List *ilist = Getattr(cls,bases);
if (!ilist) { if (!ilist) {
List *nlist = Getattr(cls,"baselist"); List *nlist = Getattr(cls,baselist);
if (nlist) { if (nlist) {
int len = Len(nlist); int len = Len(nlist);
int i; int i;
@ -197,7 +199,7 @@ class TypePass : private Dispatcher {
if (tname) Delete(tname); if (tname) Delete(tname);
if (!bcls) { if (!bcls) {
if (!clsforward) { 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)); Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(cls),Getline(cls),"Nothing known about base class '%s'. Ignored.\n", SwigType_namestr(bname));
if (Strchr(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)); 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) { if (ilist) {
Setattr(cls,"bases",ilist); Setattr(cls,bases,ilist);
} }
} }
if (!ilist) return; if (!ilist) return;
@ -240,11 +242,37 @@ class TypePass : private Dispatcher {
/* Recursively hit base classes */ /* Recursively hit base classes */
String *newcast = NewStringf("(%s *)%s", SwigType_namestr(Getattr(bclass,"name")), cast); 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); 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 */ /* Clean overloaded list. Removes templates, friends, ignored, and errors */
void clean_overloaded(Node *n) { void clean_overloaded(Node *n) {