polymorphism patch merge
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@4435 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
c146f71da1
commit
c47494cb7a
15 changed files with 2007 additions and 15 deletions
|
|
@ -203,6 +203,7 @@ Language::Language() {
|
|||
classtypes = NewHash();
|
||||
overloading = 0;
|
||||
multiinput = 0;
|
||||
directors = 0;
|
||||
}
|
||||
|
||||
Language::~Language() {
|
||||
|
|
@ -1292,6 +1293,265 @@ int Language::typedefHandler(Node *) {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorMethod()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorMethod(Node *n, Node *parent, String* super) {
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorConstructor()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorConstructor(Node *n) {
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorDefaultConstructor()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorDefaultConstructor(Node *n) {
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::tagDirectorBases()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::tagDirectorBases(Node *n) {
|
||||
List* bl;
|
||||
if (Getattr(n, "directorBase")) return SWIG_OK;
|
||||
if (Getattr(n, "hasVirtual") == 0) return SWIG_OK;
|
||||
Setattr(n, "directorBase", "1");
|
||||
bl = Getattr(n, "bases");
|
||||
if (bl) {
|
||||
Node* bi;
|
||||
for (bi = Firstitem(bl); bi; bi = Nextitem(bl)) {
|
||||
tagDirectorBases(bi);
|
||||
}
|
||||
}
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::unrollVirtualMethods()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::unrollVirtualMethods(Node *n,
|
||||
Node *parent,
|
||||
Hash *vm,
|
||||
int default_director,
|
||||
int &virtual_destructor,
|
||||
int &has_virtual) {
|
||||
int only_virtual = (Getattr(parent, "director:nonvirtual") == 0);
|
||||
int top = (n == parent);
|
||||
has_virtual = 0;
|
||||
Node *ni;
|
||||
String *type;
|
||||
String *nodeType;
|
||||
String *cdecl;
|
||||
String *storage;
|
||||
String *classname;
|
||||
String *decl;
|
||||
// default_director < 0 turns off director generation for this class and all its superclasses
|
||||
if (default_director >= 0) {
|
||||
if (Getattr(n, "feature:director")) default_director = 1;
|
||||
if (Getattr(n, "feature:nodirector")) default_director = -1;
|
||||
}
|
||||
classname = Getattr(n, "name");
|
||||
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
|
||||
nodeType = Getattr(ni, "nodeType");
|
||||
storage = Getattr(ni, "storage");
|
||||
cdecl = Getattr(ni, "cdecl");
|
||||
decl = Getattr(ni, "decl");
|
||||
if (!Cmp(nodeType, "cdecl") && SwigType_isfunction(decl)) {
|
||||
int is_virtual = storage && !Cmp(storage, "virtual");
|
||||
if (is_virtual) has_virtual = 1;
|
||||
String* access = Getattr(ni, "access");
|
||||
if (!access || !Cmp(access, "public")) {
|
||||
if (!only_virtual || is_virtual) {
|
||||
String *method_id;
|
||||
String *name = Getattr(ni, "name");
|
||||
method_id = NewStringf("%s|%s", name, decl);
|
||||
int director = default_director;
|
||||
if (director >= 0) {
|
||||
if (Getattr(ni, "feature:director")) director = 1;
|
||||
if (Getattr(ni, "feature:nodirector")) director = 0;
|
||||
}
|
||||
if ((director == 1) && !Getattr(vm, method_id)) {
|
||||
String *fqname = NewString("");
|
||||
Printf(fqname, "%s::%s", classname, name);
|
||||
Hash *item = NewHash();
|
||||
Setattr(item, "fqName", fqname);
|
||||
Setattr(item, "methodNode", ni);
|
||||
Setattr(vm, method_id, item);
|
||||
Delete(fqname);
|
||||
Delete(item);
|
||||
}
|
||||
Delete(method_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!Cmp(nodeType, "destructor")) {
|
||||
if (storage && !Cmp(storage, "virtual")) {
|
||||
virtual_destructor = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
List* bl = Getattr(n, "bases");
|
||||
if (bl) {
|
||||
Node* bi;
|
||||
for (bi = Firstitem(bl); bi; bi = Nextitem(bl)) {
|
||||
int virtual_base = 0;
|
||||
unrollVirtualMethods(bi, parent, vm, default_director, virtual_destructor, virtual_base);
|
||||
if (virtual_base) {
|
||||
has_virtual = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (has_virtual) {
|
||||
Setattr(n, "hasVirtual", "1");
|
||||
}
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorDisown()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorDisown(Node *n) {
|
||||
Node *disown = NewHash();
|
||||
String *mrename;
|
||||
String *symname = Getattr(n,"sym:name");
|
||||
mrename = Swig_name_disown(symname); //Getattr(n, "name"));
|
||||
String *type = NewString(ClassType);
|
||||
String *name = NewString("self");
|
||||
SwigType_add_pointer(type);
|
||||
Parm *p = NewParm(type, name);
|
||||
Delete(name);
|
||||
Delete(type);
|
||||
type = NewString("void");
|
||||
String *action = NewString("");
|
||||
Printv(action, "{\n",
|
||||
"__DIRECTOR__ *director = dynamic_cast<__DIRECTOR__*>(arg1);\n",
|
||||
"if (director) director->__disown();\n",
|
||||
"}\n",
|
||||
NULL);
|
||||
Setattr(disown, "wrap:action", action);
|
||||
Setattr(disown,"name", mrename);
|
||||
Setattr(disown,"sym:name", mrename);
|
||||
Setattr(disown,"type",type);
|
||||
Setattr(disown,"parms", p);
|
||||
Delete(action);
|
||||
Delete(mrename);
|
||||
Delete(type);
|
||||
Delete(p);
|
||||
|
||||
functionWrapper(disown);
|
||||
Delete(disown);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorConstructors()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorConstructors(Node *n) {
|
||||
Node *ni;
|
||||
String *nodeType;
|
||||
int constructor = 0;
|
||||
for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
|
||||
nodeType = Getattr(ni, "nodeType");
|
||||
if (!Cmp(nodeType, "constructor")) {
|
||||
classDirectorConstructor(ni);
|
||||
constructor = 1;
|
||||
}
|
||||
}
|
||||
if (!constructor) {
|
||||
classDirectorDefaultConstructor(n);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorMethods()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorMethods(Node *n) {
|
||||
Node *vtable = Getattr(n, "vtable");
|
||||
Node *item;
|
||||
String *key;
|
||||
for (key = Firstkey(vtable); key != 0; key = Nextkey(vtable)) {
|
||||
item = Getattr(vtable, key);
|
||||
String *method = Getattr(item, "methodNode");
|
||||
String *fqname = Getattr(item, "fqName");
|
||||
if (classDirectorMethod(method, n, fqname) == SWIG_OK) {
|
||||
Setattr(item, "director", "1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorInit()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorInit(Node *n) {
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirectorEnd()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirectorEnd(Node *n) {
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDirector()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
int Language::classDirector(Node *n) {
|
||||
Node *module = Getattr(n,"module");
|
||||
String *classtype = Getattr(n, "classtype");
|
||||
Hash *directormap = 0;
|
||||
if (module) {
|
||||
directormap = Getattr(module, "wrap:directormap");
|
||||
if (directormap == 0) {
|
||||
directormap = NewHash();
|
||||
Setattr(module, "wrap:directormap", directormap);
|
||||
}
|
||||
}
|
||||
Hash* vtable = NewHash();
|
||||
int virtual_destructor = 0;
|
||||
int has_virtual = 0;
|
||||
unrollVirtualMethods(n, n, vtable, 0, virtual_destructor, has_virtual);
|
||||
if (Len(vtable) > 0) {
|
||||
if (!virtual_destructor) {
|
||||
String *classtype = Getattr(n, "classtype");
|
||||
Swig_warning(WARN_LANG_DIRECTOR_VDESTRUCT, input_file, line_number,
|
||||
"Director base class %s has no virtual destructor.\n",
|
||||
classtype);
|
||||
}
|
||||
Setattr(n, "vtable", vtable);
|
||||
tagDirectorBases(n);
|
||||
classDirectorInit(n);
|
||||
classDirectorConstructors(n);
|
||||
classDirectorMethods(n);
|
||||
classDirectorEnd(n);
|
||||
if (directormap != 0) {
|
||||
Setattr(directormap, classtype, n);
|
||||
}
|
||||
}
|
||||
Delete(vtable);
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Language::classDeclaration()
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
|
@ -1339,6 +1599,12 @@ int Language::classDeclaration(Node *n) {
|
|||
}
|
||||
Setattr(n,"classtype", SwigType_namestr(ClassType));
|
||||
|
||||
/*
|
||||
if (CPlusPlus) {
|
||||
classDirector(n);
|
||||
}
|
||||
*/
|
||||
|
||||
InClass = 1;
|
||||
CurrentClass = n;
|
||||
|
||||
|
|
@ -1349,10 +1615,14 @@ int Language::classDeclaration(Node *n) {
|
|||
}
|
||||
|
||||
/* Call classHandler() here */
|
||||
if (!ImportMode)
|
||||
if (!ImportMode) {
|
||||
if (CPlusPlus && directorsEnabled()) {
|
||||
classDirector(n);
|
||||
}
|
||||
classHandler(n);
|
||||
else
|
||||
} else {
|
||||
Language::classHandler(n);
|
||||
}
|
||||
|
||||
InClass = 0;
|
||||
CurrentClass = 0;
|
||||
|
|
@ -1399,6 +1669,12 @@ int Language::classHandler(Node *n) {
|
|||
destructorHandler(CurrentClass);
|
||||
}
|
||||
}
|
||||
|
||||
/* emit director disown method */
|
||||
if (Getattr(n, "vtable")) {
|
||||
classDirectorDisown(n);
|
||||
}
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1816,6 +2092,30 @@ void Language::allow_multiple_input(int val) {
|
|||
multiinput = val;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::allow_directors()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void Language::allow_directors(int val) {
|
||||
directors = val;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::directorsEnabled()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int Language::directorsEnabled() const {
|
||||
return directors;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::is_smart_pointer()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int Language::is_smart_pointer() const {
|
||||
return SmartPointer;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Language::is_wrapping_class()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ static char *usage = (char*)"\
|
|||
-swiglib - Report location of SWIG library and exit\n\
|
||||
-v - Run in verbose mode\n\
|
||||
-fcompact - Compile in compact mode\n\
|
||||
-fdirectors - Enable C++ directors\n\
|
||||
-fvirtual - Compile in virtual elimination mode\n\
|
||||
-small - Compile in virtual elimination & compact mode\n\
|
||||
-version - Print SWIG version number\n\
|
||||
|
|
@ -189,6 +190,7 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
int dump_classes = 0;
|
||||
int werror = 0;
|
||||
int depend = 0;
|
||||
int directors = 0;
|
||||
|
||||
DOH *libfiles = 0;
|
||||
DOH *cpps = 0 ;
|
||||
|
|
@ -285,6 +287,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
} else if (strcmp(temp, "-small") == 0) {
|
||||
Wrapper_compact_print_mode_set(1);
|
||||
Wrapper_virtual_elimination_mode_set(1);
|
||||
} else if (strcmp(temp, "-fdirectors") == 0) {
|
||||
directors = 1;
|
||||
lang->allow_directors();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -324,6 +329,10 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
Wrapper_compact_print_mode_set(1);
|
||||
Wrapper_virtual_elimination_mode_set(1);
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i], "-fdirectors") == 0) {
|
||||
directors = 1;
|
||||
lang->allow_directors();
|
||||
Swig_mark_arg(i);
|
||||
} else if (strcmp(argv[i],"-c") == 0) {
|
||||
NoInclude=1;
|
||||
Preprocessor_define((DOH *) "SWIG_NOINCLUDE 1", 0);
|
||||
|
|
@ -534,6 +543,9 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
if (lang_config) {
|
||||
Printf(fs,"\n%%include \"%s\"\n", lang_config);
|
||||
}
|
||||
if (directors) {
|
||||
Printf(fs,"\n%%include \"director.swg\"\n");
|
||||
}
|
||||
Printf(fs,"%%include \"%s\"\n", Swig_last_file());
|
||||
for (i = 0; i < Len(libfiles); i++) {
|
||||
Printf(fs,"\n%%include \"%s\"\n", Getitem(libfiles,i));
|
||||
|
|
@ -631,8 +643,15 @@ int SWIG_main(int argc, char *argv[], Language *l) {
|
|||
} else {
|
||||
Setattr(top,"outfile", NewStringf("%s_wrap.c", Swig_file_basename(input_file)));
|
||||
}
|
||||
Setattr(top,"outfile_h", NewStringf("%s_wrap.h", Swig_file_basename(input_file)));
|
||||
} else {
|
||||
char *header = strdup(outfile_name);
|
||||
char *ext = header + strlen(header);
|
||||
while (ext > header && *ext != '.') ext--;
|
||||
if (*ext == '.') *ext = 0;
|
||||
Setattr(top,"outfile", outfile_name);
|
||||
Setattr(top,"outfile_h", NewStringf("%s.h", header));
|
||||
free(header);
|
||||
}
|
||||
if (contracts) {
|
||||
Swig_contracts(top);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -178,23 +178,48 @@ public:
|
|||
virtual int functionWrapper(Node *n);
|
||||
virtual int nativeWrapper(Node *n);
|
||||
|
||||
/* C++ director class generation */
|
||||
virtual int classDirector(Node *n);
|
||||
virtual int classDirectorInit(Node *n);
|
||||
virtual int classDirectorEnd(Node *n);
|
||||
virtual int tagDirectorBases(Node *n);
|
||||
virtual int unrollVirtualMethods(Node *n,
|
||||
Node *parent,
|
||||
Hash *vm,
|
||||
int default_director,
|
||||
int &virtual_destructor,
|
||||
int &has_virtual);
|
||||
virtual int classDirectorConstructor(Node *n);
|
||||
virtual int classDirectorDefaultConstructor(Node *n);
|
||||
virtual int classDirectorMethod(Node *n, Node *parent, String *super);
|
||||
virtual int classDirectorConstructors(Node *n);
|
||||
virtual int classDirectorMethods(Node *n);
|
||||
virtual int classDirectorDisown(Node *n);
|
||||
|
||||
/* Miscellaneous */
|
||||
|
||||
virtual int validIdentifier(String *s); /* valid identifier? */
|
||||
virtual int addSymbol(String *s, Node *n); /* Add symbol */
|
||||
virtual Node *symbolLookup(String *s); /* Symbol lookup */
|
||||
virtual Node *classLookup(SwigType *s); /* Class lookup */
|
||||
|
||||
/* Allow director related code generation */
|
||||
void allow_directors(int val = 1);
|
||||
|
||||
/* Return true if directors are enabled */
|
||||
int directorsEnabled() const;
|
||||
|
||||
|
||||
protected:
|
||||
/* Patch C++ pass-by-value */
|
||||
static void patch_parms(Parm *p);
|
||||
|
||||
/* Allow overloaded functions */
|
||||
void allow_overloading(int val = 1);
|
||||
|
||||
/* Allow multiple-input typemaps */
|
||||
void allow_multiple_input(int val = 1);
|
||||
|
||||
/* Allow overloaded functions */
|
||||
void allow_overloading(int val = 1);
|
||||
|
||||
/* Wrapping class query */
|
||||
int is_wrapping_class();
|
||||
|
||||
|
|
@ -210,11 +235,16 @@ public:
|
|||
/* Fully qualified type name to use */
|
||||
String *getClassType() const;
|
||||
|
||||
/* Return true if the current method is part of a smart-pointer */
|
||||
int is_smart_pointer() const;
|
||||
|
||||
private:
|
||||
Hash *symbols;
|
||||
Hash *classtypes;
|
||||
int overloading;
|
||||
int multiinput;
|
||||
int directors;
|
||||
|
||||
};
|
||||
|
||||
extern int SWIG_main(int, char **, Language *);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue